PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.4
4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 All 140 releases
learnpress / assets / dist / js / admin / edit-question.js

edit-question.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.4, at assets/dist/js/admin/edit-question.js

10,933 lines 391.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/js/lpToastify.js"
5 /*!*************************************!*\
6 !*** ./assets/src/js/lpToastify.js ***!
7 \*************************************/
8 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
10 "use strict";
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ show: () => (/* binding */ show)
14 /* harmony export */ });
15 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
16 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
17 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
18 /**
19 * Utils functions
20 *
21 * @param url
22 * @param data
23 * @param functions
24 * @since 4.3.0
25 * @version 1.0.0
26 */
27
28
29 const argsToastify = {
30 text: '',
31 gravity: lpData.toast.gravity,
32 // `top` or `bottom`
33 position: lpData.toast.position,
34 // `left`, `center` or `right`
35 className: `${lpData.toast.classPrefix}`,
36 close: lpData.toast.close == 1,
37 stopOnFocus: lpData.toast.stopOnFocus == 1,
38 duration: lpData.toast.duration
39 };
40 const show = (message, status = 'success', argsCustom) => {
41 let args = argsToastify;
42 if (argsCustom) {
43 args = {
44 ...args,
45 ...argsCustom
46 };
47 }
48 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
49 ...args,
50 text: message,
51 className: `${lpData.toast.classPrefix} ${status}`
52 });
53 toastify.showToast();
54 };
55
56 /***/ },
57
58 /***/ "./assets/src/js/utils.js"
59 /*!********************************!*\
60 !*** ./assets/src/js/utils.js ***!
61 \********************************/
62 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
63
64 "use strict";
65 __webpack_require__.r(__webpack_exports__);
66 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
67 /* harmony export */ debounce: () => (/* binding */ debounce),
68 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
69 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
70 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
71 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
72 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
73 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
74 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
75 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
76 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
77 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
78 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
79 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
80 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
81 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
82 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
83 /* harmony export */ });
84 /**
85 * Utils functions
86 *
87 * @param url
88 * @param data
89 * @param functions
90 * @since 4.2.5.1
91 * @version 1.0.6
92 */
93 const lpClassName = {
94 hidden: 'lp-hidden',
95 loading: 'loading',
96 elCollapse: 'lp-collapse',
97 elSectionToggle: '.lp-section-toggle',
98 elTriggerToggle: '.lp-trigger-toggle'
99 };
100 const lpFetchAPI = (url, data = {}, functions = {}) => {
101 if ('function' === typeof functions.before) {
102 functions.before();
103 }
104 fetch(url, {
105 method: 'GET',
106 ...data
107 }).then(response => response.json()).then(response => {
108 if ('function' === typeof functions.success) {
109 functions.success(response);
110 }
111 }).catch(err => {
112 if ('function' === typeof functions.error) {
113 functions.error(err);
114 }
115 }).finally(() => {
116 if ('function' === typeof functions.completed) {
117 functions.completed();
118 }
119 });
120 };
121
122 /**
123 * Get current URL without params.
124 *
125 * @since 4.2.5.1
126 */
127 const lpGetCurrentURLNoParam = () => {
128 let currentUrl = window.location.href;
129 const hasParams = currentUrl.includes('?');
130 if (hasParams) {
131 currentUrl = currentUrl.split('?')[0];
132 }
133 return currentUrl;
134 };
135 const lpAddQueryArgs = (endpoint, args) => {
136 const url = new URL(endpoint);
137 Object.keys(args).forEach(arg => {
138 url.searchParams.set(arg, args[arg]);
139 });
140 return url;
141 };
142
143 /**
144 * Listen element viewed.
145 *
146 * @param el
147 * @param callback
148 * @since 4.2.5.8
149 */
150 const listenElementViewed = (el, callback) => {
151 const observerSeeItem = new IntersectionObserver(function (entries) {
152 for (const entry of entries) {
153 if (entry.isIntersecting) {
154 callback(entry);
155 }
156 }
157 });
158 observerSeeItem.observe(el);
159 };
160
161 /**
162 * Listen element created.
163 *
164 * @param callback
165 * @since 4.2.5.8
166 */
167 const listenElementCreated = callback => {
168 const observerCreateItem = new MutationObserver(function (mutations) {
169 mutations.forEach(function (mutation) {
170 if (mutation.addedNodes) {
171 mutation.addedNodes.forEach(function (node) {
172 if (node.nodeType === 1) {
173 callback(node);
174 }
175 });
176 }
177 });
178 });
179 observerCreateItem.observe(document, {
180 childList: true,
181 subtree: true
182 });
183 // End.
184 };
185
186 /**
187 * Listen element created.
188 *
189 * @param selector
190 * @param callback
191 * @since 4.2.7.1
192 */
193 const lpOnElementReady = (selector, callback) => {
194 const element = document.querySelector(selector);
195 if (element) {
196 callback(element);
197 return;
198 }
199 const observer = new MutationObserver((mutations, obs) => {
200 const element = document.querySelector(selector);
201 if (element) {
202 obs.disconnect();
203 callback(element);
204 }
205 });
206 observer.observe(document.documentElement, {
207 childList: true,
208 subtree: true
209 });
210 };
211
212 // Parse JSON from string with content include LP_AJAX_START.
213 const lpAjaxParseJsonOld = data => {
214 if (typeof data !== 'string') {
215 return data;
216 }
217 const m = String.raw({
218 raw: data
219 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
220 try {
221 if (m) {
222 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
223 } else {
224 data = JSON.parse(data);
225 }
226 } catch (e) {
227 data = {};
228 }
229 return data;
230 };
231
232 // status 0: hide, 1: show
233 const lpShowHideEl = (el, status = 0) => {
234 if (!el) {
235 return;
236 }
237 if (!status) {
238 el.classList.add(lpClassName.hidden);
239 } else {
240 el.classList.remove(lpClassName.hidden);
241 }
242 };
243
244 // status 0: hide, 1: show
245 const lpSetLoadingEl = (el, status) => {
246 if (!el) {
247 return;
248 }
249 if (!status) {
250 el.classList.remove(lpClassName.loading);
251 } else {
252 el.classList.add(lpClassName.loading);
253 }
254 };
255
256 // Toggle collapse section
257 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
258 if (!elTriggerClassName) {
259 elTriggerClassName = lpClassName.elTriggerToggle;
260 }
261
262 // Exclude elements, which should not trigger the collapse toggle
263 if (elsExclude && elsExclude.length > 0) {
264 for (const elExclude of elsExclude) {
265 if (target.closest(elExclude)) {
266 return;
267 }
268 }
269 }
270 const elTrigger = target.closest(elTriggerClassName);
271 if (!elTrigger) {
272 return;
273 }
274
275 //console.log( 'elTrigger', elTrigger );
276
277 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
278 if (!elSectionToggle) {
279 return;
280 }
281 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
282 if ('function' === typeof callback) {
283 callback(elSectionToggle);
284 }
285 };
286
287 // Get data of form
288 const getDataOfForm = form => {
289 const dataSend = {};
290 const formData = new FormData(form);
291 for (const pair of formData.entries()) {
292 const key = pair[0];
293 const value = formData.getAll(key);
294 if (!dataSend.hasOwnProperty(key)) {
295 // Convert value array to string.
296 dataSend[key] = value.join(',');
297 }
298 }
299 return dataSend;
300 };
301
302 // Get field keys of form
303 const getFieldKeysOfForm = form => {
304 const keys = [];
305 const elements = form.elements;
306 for (let i = 0; i < elements.length; i++) {
307 const name = elements[i].name;
308 if (name && !keys.includes(name)) {
309 keys.push(name);
310 }
311 }
312 return keys;
313 };
314
315 // Merge data handle with data form.
316 const mergeDataWithDatForm = (elForm, dataHandle) => {
317 const dataForm = getDataOfForm(elForm);
318 const keys = getFieldKeysOfForm(elForm);
319 keys.forEach(key => {
320 if (!dataForm.hasOwnProperty(key)) {
321 delete dataHandle[key];
322 } else if (dataForm[key][0] === '') {
323 delete dataForm[key];
324 delete dataHandle[key];
325 }
326 });
327 dataHandle = {
328 ...dataHandle,
329 ...dataForm
330 };
331 return dataHandle;
332 };
333
334 /**
335 * Event trigger
336 * For each list of event handlers, listen event on document.
337 *
338 * eventName: 'click', 'change', ...
339 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
340 *
341 * @param eventName
342 * @param eventHandlers
343 */
344 const eventHandlers = (eventName, eventHandlers) => {
345 document.addEventListener(eventName, e => {
346 const target = e.target;
347 let args = {
348 e,
349 target
350 };
351 eventHandlers.forEach(eventHandler => {
352 args = {
353 ...args,
354 ...eventHandler
355 };
356
357 //console.log( args );
358
359 // Check condition before call back
360 if (eventHandler.conditionBeforeCallBack) {
361 if (eventHandler.conditionBeforeCallBack(args) !== true) {
362 return;
363 }
364 }
365
366 // Special check for keydown event with checkIsEventEnter = true
367 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
368 if (e.key !== 'Enter') {
369 return;
370 }
371 }
372 if (target.closest(eventHandler.selector)) {
373 if (eventHandler.class) {
374 // Call method of class, function callBack will understand exactly {this} is class object.
375 eventHandler.class[eventHandler.callBack](args);
376 } else {
377 // For send args is objected, {this} is eventHandler object, not class object.
378 eventHandler.callBack(args);
379 }
380 }
381 });
382 });
383 };
384
385 /**
386 * Debounce - delays function execution until after `wait` ms of inactivity.
387 *
388 * Each call resets the timer. Only the last call in a burst executes.
389 *
390 * USE CASES:
391 * - Search inputs, form validation, window resize
392 * - Multiple elements need independent timers
393 * - When you need to call with different arguments
394 *
395 * EXAMPLES:
396 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
397 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
398 *
399 * const debouncedResize = debounce( recalculateLayout, 250 );
400 * window.addEventListener('resize', debouncedResize);
401 *
402 * ⚠️ Create ONCE outside event handlers, not inside.
403 *
404 * @param {Function} func - Function to debounce (can be anonymous)
405 * @param {number} wait - Milliseconds to wait (default: 500)
406 * @return {Function} Debounced wrapper function
407 * @since 4.3.7
408 * @version 1.0.0
409 */
410 const debounce = (func, wait = 500) => {
411 let timer;
412 return args => {
413 clearTimeout(timer);
414 timer = setTimeout(() => func(args), wait);
415 };
416 };
417
418 /***/ },
419
420 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
421 /*!*****************************************************************************************!*\
422 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
423 \*****************************************************************************************/
424 (module, __webpack_exports__, __webpack_require__) {
425
426 "use strict";
427 __webpack_require__.r(__webpack_exports__);
428 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
429 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
430 /* harmony export */ });
431 /* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js");
432 /* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
433 /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
434 /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
435 // Imports
436
437
438 var ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
439 // Module
440 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
441 * Toastify js 1.12.0
442 * https://github.com/apvarun/toastify-js
443 * @license MIT licensed
444 *
445 * Copyright (C) 2018 Varun A P
446 */
447
448 .toastify {
449 padding: 12px 20px;
450 color: #ffffff;
451 display: inline-block;
452 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
453 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
454 background: linear-gradient(135deg, #73a5ff, #5477f5);
455 position: fixed;
456 opacity: 0;
457 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
458 border-radius: 2px;
459 cursor: pointer;
460 text-decoration: none;
461 max-width: calc(50% - 20px);
462 z-index: 2147483647;
463 }
464
465 .toastify.on {
466 opacity: 1;
467 }
468
469 .toast-close {
470 background: transparent;
471 border: 0;
472 color: white;
473 cursor: pointer;
474 font-family: inherit;
475 font-size: 1em;
476 opacity: 0.4;
477 padding: 0 5px;
478 }
479
480 .toastify-right {
481 right: 15px;
482 }
483
484 .toastify-left {
485 left: 15px;
486 }
487
488 .toastify-top {
489 top: -150px;
490 }
491
492 .toastify-bottom {
493 bottom: -150px;
494 }
495
496 .toastify-rounded {
497 border-radius: 25px;
498 }
499
500 .toastify-avatar {
501 width: 1.5em;
502 height: 1.5em;
503 margin: -7px 5px;
504 border-radius: 2px;
505 }
506
507 .toastify-center {
508 margin-left: auto;
509 margin-right: auto;
510 left: 0;
511 right: 0;
512 max-width: fit-content;
513 max-width: -moz-fit-content;
514 }
515
516 @media only screen and (max-width: 360px) {
517 .toastify-right, .toastify-left {
518 margin-left: auto;
519 margin-right: auto;
520 left: 0;
521 right: 0;
522 max-width: fit-content;
523 }
524 }
525 `, "",{"version":3,"sources":["webpack://./node_modules/toastify-js/src/toastify.css"],"names":[],"mappings":"AAAA;;;;;;EAME;;AAEF;IACI,kBAAkB;IAClB,cAAc;IACd,qBAAqB;IACrB,uFAAuF;IACvF,6DAA6D;IAC7D,qDAAqD;IACrD,eAAe;IACf,UAAU;IACV,wDAAwD;IACxD,kBAAkB;IAClB,eAAe;IACf,qBAAqB;IACrB,2BAA2B;IAC3B,mBAAmB;AACvB;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,uBAAuB;IACvB,SAAS;IACT,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,cAAc;IACd,YAAY;IACZ,cAAc;AAClB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,OAAO;IACP,QAAQ;IACR,sBAAsB;IACtB,2BAA2B;AAC/B;;AAEA;IACI;QACI,iBAAiB;QACjB,kBAAkB;QAClB,OAAO;QACP,QAAQ;QACR,sBAAsB;IAC1B;AACJ","sourcesContent":["/*!\n * Toastify js 1.12.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n\n.toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n}\n\n.toastify.on {\n opacity: 1;\n}\n\n.toast-close {\n background: transparent;\n border: 0;\n color: white;\n cursor: pointer;\n font-family: inherit;\n font-size: 1em;\n opacity: 0.4;\n padding: 0 5px;\n}\n\n.toastify-right {\n right: 15px;\n}\n\n.toastify-left {\n left: 15px;\n}\n\n.toastify-top {\n top: -150px;\n}\n\n.toastify-bottom {\n bottom: -150px;\n}\n\n.toastify-rounded {\n border-radius: 25px;\n}\n\n.toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: -7px 5px;\n border-radius: 2px;\n}\n\n.toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n}\n\n@media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n}\n"],"sourceRoot":""}]);
526 // Exports
527 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
528
529
530 /***/ },
531
532 /***/ "./node_modules/css-loader/dist/runtime/api.js"
533 /*!*****************************************************!*\
534 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
535 \*****************************************************/
536 (module) {
537
538 "use strict";
539
540
541 /*
542 MIT License http://www.opensource.org/licenses/mit-license.php
543 Author Tobias Koppers @sokra
544 */
545 module.exports = function (cssWithMappingToString) {
546 var list = [];
547
548 // return the list of modules as css string
549 list.toString = function toString() {
550 return this.map(function (item) {
551 var content = "";
552 var needLayer = typeof item[5] !== "undefined";
553 if (item[4]) {
554 content += "@supports (".concat(item[4], ") {");
555 }
556 if (item[2]) {
557 content += "@media ".concat(item[2], " {");
558 }
559 if (needLayer) {
560 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
561 }
562 content += cssWithMappingToString(item);
563 if (needLayer) {
564 content += "}";
565 }
566 if (item[2]) {
567 content += "}";
568 }
569 if (item[4]) {
570 content += "}";
571 }
572 return content;
573 }).join("");
574 };
575
576 // import a list of modules into the list
577 list.i = function i(modules, media, dedupe, supports, layer) {
578 if (typeof modules === "string") {
579 modules = [[null, modules, undefined]];
580 }
581 var alreadyImportedModules = {};
582 if (dedupe) {
583 for (var k = 0; k < this.length; k++) {
584 var id = this[k][0];
585 if (id != null) {
586 alreadyImportedModules[id] = true;
587 }
588 }
589 }
590 for (var _k = 0; _k < modules.length; _k++) {
591 var item = [].concat(modules[_k]);
592 if (dedupe && alreadyImportedModules[item[0]]) {
593 continue;
594 }
595 if (typeof layer !== "undefined") {
596 if (typeof item[5] === "undefined") {
597 item[5] = layer;
598 } else {
599 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
600 item[5] = layer;
601 }
602 }
603 if (media) {
604 if (!item[2]) {
605 item[2] = media;
606 } else {
607 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
608 item[2] = media;
609 }
610 }
611 if (supports) {
612 if (!item[4]) {
613 item[4] = "".concat(supports);
614 } else {
615 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
616 item[4] = supports;
617 }
618 }
619 list.push(item);
620 }
621 };
622 return list;
623 };
624
625 /***/ },
626
627 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
628 /*!************************************************************!*\
629 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
630 \************************************************************/
631 (module) {
632
633 "use strict";
634
635
636 module.exports = function (item) {
637 var content = item[1];
638 var cssMapping = item[3];
639 if (!cssMapping) {
640 return content;
641 }
642 if (typeof btoa === "function") {
643 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
644 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
645 var sourceMapping = "/*# ".concat(data, " */");
646 return [content].concat([sourceMapping]).join("\n");
647 }
648 return [content].join("\n");
649 };
650
651 /***/ },
652
653 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
654 /*!*********************************************************!*\
655 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
656 \*********************************************************/
657 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
658
659 "use strict";
660 __webpack_require__.r(__webpack_exports__);
661 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
662 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
663 /* harmony export */ Sortable: () => (/* binding */ Sortable),
664 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
665 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
666 /* harmony export */ });
667 /**!
668 * Sortable 1.15.7
669 * @author RubaXa <[email protected]>
670 * @author owenm <[email protected]>
671 * @license MIT
672 */
673 function _arrayLikeToArray(r, a) {
674 (null == a || a > r.length) && (a = r.length);
675 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
676 return n;
677 }
678 function _arrayWithoutHoles(r) {
679 if (Array.isArray(r)) return _arrayLikeToArray(r);
680 }
681 function _defineProperty(e, r, t) {
682 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
683 value: t,
684 enumerable: !0,
685 configurable: !0,
686 writable: !0
687 }) : e[r] = t, e;
688 }
689 function _extends() {
690 return _extends = Object.assign ? Object.assign.bind() : function (n) {
691 for (var e = 1; e < arguments.length; e++) {
692 var t = arguments[e];
693 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
694 }
695 return n;
696 }, _extends.apply(null, arguments);
697 }
698 function _iterableToArray(r) {
699 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
700 }
701 function _nonIterableSpread() {
702 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
703 }
704 function ownKeys(e, r) {
705 var t = Object.keys(e);
706 if (Object.getOwnPropertySymbols) {
707 var o = Object.getOwnPropertySymbols(e);
708 r && (o = o.filter(function (r) {
709 return Object.getOwnPropertyDescriptor(e, r).enumerable;
710 })), t.push.apply(t, o);
711 }
712 return t;
713 }
714 function _objectSpread2(e) {
715 for (var r = 1; r < arguments.length; r++) {
716 var t = null != arguments[r] ? arguments[r] : {};
717 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
718 _defineProperty(e, r, t[r]);
719 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
720 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
721 });
722 }
723 return e;
724 }
725 function _objectWithoutProperties(e, t) {
726 if (null == e) return {};
727 var o,
728 r,
729 i = _objectWithoutPropertiesLoose(e, t);
730 if (Object.getOwnPropertySymbols) {
731 var n = Object.getOwnPropertySymbols(e);
732 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
733 }
734 return i;
735 }
736 function _objectWithoutPropertiesLoose(r, e) {
737 if (null == r) return {};
738 var t = {};
739 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
740 if (-1 !== e.indexOf(n)) continue;
741 t[n] = r[n];
742 }
743 return t;
744 }
745 function _toConsumableArray(r) {
746 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
747 }
748 function _toPrimitive(t, r) {
749 if ("object" != typeof t || !t) return t;
750 var e = t[Symbol.toPrimitive];
751 if (void 0 !== e) {
752 var i = e.call(t, r || "default");
753 if ("object" != typeof i) return i;
754 throw new TypeError("@@toPrimitive must return a primitive value.");
755 }
756 return ("string" === r ? String : Number)(t);
757 }
758 function _toPropertyKey(t) {
759 var i = _toPrimitive(t, "string");
760 return "symbol" == typeof i ? i : i + "";
761 }
762 function _typeof(o) {
763 "@babel/helpers - typeof";
764
765 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
766 return typeof o;
767 } : function (o) {
768 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
769 }, _typeof(o);
770 }
771 function _unsupportedIterableToArray(r, a) {
772 if (r) {
773 if ("string" == typeof r) return _arrayLikeToArray(r, a);
774 var t = {}.toString.call(r).slice(8, -1);
775 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
776 }
777 }
778
779 var version = "1.15.7";
780
781 function userAgent(pattern) {
782 if (typeof window !== 'undefined' && window.navigator) {
783 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
784 }
785 }
786 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
787 var Edge = userAgent(/Edge/i);
788 var FireFox = userAgent(/firefox/i);
789 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
790 var IOS = userAgent(/iP(ad|od|hone)/i);
791 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
792
793 var captureMode = {
794 capture: false,
795 passive: false
796 };
797 function on(el, event, fn) {
798 el.addEventListener(event, fn, !IE11OrLess && captureMode);
799 }
800 function off(el, event, fn) {
801 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
802 }
803 function matches( /**HTMLElement*/el, /**String*/selector) {
804 if (!selector) return;
805 selector[0] === '>' && (selector = selector.substring(1));
806 if (el) {
807 try {
808 if (el.matches) {
809 return el.matches(selector);
810 } else if (el.msMatchesSelector) {
811 return el.msMatchesSelector(selector);
812 } else if (el.webkitMatchesSelector) {
813 return el.webkitMatchesSelector(selector);
814 }
815 } catch (_) {
816 return false;
817 }
818 }
819 return false;
820 }
821 function getParentOrHost(el) {
822 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
823 }
824 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
825 if (el) {
826 ctx = ctx || document;
827 do {
828 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
829 return el;
830 }
831 if (el === ctx) break;
832 /* jshint boss:true */
833 } while (el = getParentOrHost(el));
834 }
835 return null;
836 }
837 var R_SPACE = /\s+/g;
838 function toggleClass(el, name, state) {
839 if (el && name) {
840 if (el.classList) {
841 el.classList[state ? 'add' : 'remove'](name);
842 } else {
843 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
844 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
845 }
846 }
847 }
848 function css(el, prop, val) {
849 var style = el && el.style;
850 if (style) {
851 if (val === void 0) {
852 if (document.defaultView && document.defaultView.getComputedStyle) {
853 val = document.defaultView.getComputedStyle(el, '');
854 } else if (el.currentStyle) {
855 val = el.currentStyle;
856 }
857 return prop === void 0 ? val : val[prop];
858 } else {
859 if (!(prop in style) && prop.indexOf('webkit') === -1) {
860 prop = '-webkit-' + prop;
861 }
862 style[prop] = val + (typeof val === 'string' ? '' : 'px');
863 }
864 }
865 }
866 function matrix(el, selfOnly) {
867 var appliedTransforms = '';
868 if (typeof el === 'string') {
869 appliedTransforms = el;
870 } else {
871 do {
872 var transform = css(el, 'transform');
873 if (transform && transform !== 'none') {
874 appliedTransforms = transform + ' ' + appliedTransforms;
875 }
876 /* jshint boss:true */
877 } while (!selfOnly && (el = el.parentNode));
878 }
879 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
880 /*jshint -W056 */
881 return matrixFn && new matrixFn(appliedTransforms);
882 }
883 function find(ctx, tagName, iterator) {
884 if (ctx) {
885 var list = ctx.getElementsByTagName(tagName),
886 i = 0,
887 n = list.length;
888 if (iterator) {
889 for (; i < n; i++) {
890 iterator(list[i], i);
891 }
892 }
893 return list;
894 }
895 return [];
896 }
897 function getWindowScrollingElement() {
898 var scrollingElement = document.scrollingElement;
899 if (scrollingElement) {
900 return scrollingElement;
901 } else {
902 return document.documentElement;
903 }
904 }
905
906 /**
907 * Returns the "bounding client rect" of given element
908 * @param {HTMLElement} el The element whose boundingClientRect is wanted
909 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
910 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
911 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
912 * @param {[HTMLElement]} container The parent the element will be placed in
913 * @return {Object} The boundingClientRect of el, with specified adjustments
914 */
915 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
916 if (!el.getBoundingClientRect && el !== window) return;
917 var elRect, top, left, bottom, right, height, width;
918 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
919 elRect = el.getBoundingClientRect();
920 top = elRect.top;
921 left = elRect.left;
922 bottom = elRect.bottom;
923 right = elRect.right;
924 height = elRect.height;
925 width = elRect.width;
926 } else {
927 top = 0;
928 left = 0;
929 bottom = window.innerHeight;
930 right = window.innerWidth;
931 height = window.innerHeight;
932 width = window.innerWidth;
933 }
934 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
935 // Adjust for translate()
936 container = container || el.parentNode;
937
938 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
939 // Not needed on <= IE11
940 if (!IE11OrLess) {
941 do {
942 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
943 var containerRect = container.getBoundingClientRect();
944
945 // Set relative to edges of padding box of container
946 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
947 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
948 bottom = top + elRect.height;
949 right = left + elRect.width;
950 break;
951 }
952 /* jshint boss:true */
953 } while (container = container.parentNode);
954 }
955 }
956 if (undoScale && el !== window) {
957 // Adjust for scale()
958 var elMatrix = matrix(container || el),
959 scaleX = elMatrix && elMatrix.a,
960 scaleY = elMatrix && elMatrix.d;
961 if (elMatrix) {
962 top /= scaleY;
963 left /= scaleX;
964 width /= scaleX;
965 height /= scaleY;
966 bottom = top + height;
967 right = left + width;
968 }
969 }
970 return {
971 top: top,
972 left: left,
973 bottom: bottom,
974 right: right,
975 width: width,
976 height: height
977 };
978 }
979
980 /**
981 * Checks if a side of an element is scrolled past a side of its parents
982 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
983 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
984 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
985 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
986 */
987 function isScrolledPast(el, elSide, parentSide) {
988 var parent = getParentAutoScrollElement(el, true),
989 elSideVal = getRect(el)[elSide];
990
991 /* jshint boss:true */
992 while (parent) {
993 var parentSideVal = getRect(parent)[parentSide],
994 visible = void 0;
995 if (parentSide === 'top' || parentSide === 'left') {
996 visible = elSideVal >= parentSideVal;
997 } else {
998 visible = elSideVal <= parentSideVal;
999 }
1000 if (!visible) return parent;
1001 if (parent === getWindowScrollingElement()) break;
1002 parent = getParentAutoScrollElement(parent, false);
1003 }
1004 return false;
1005 }
1006
1007 /**
1008 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
1009 * and non-draggable elements
1010 * @param {HTMLElement} el The parent element
1011 * @param {Number} childNum The index of the child
1012 * @param {Object} options Parent Sortable's options
1013 * @return {HTMLElement} The child at index childNum, or null if not found
1014 */
1015 function getChild(el, childNum, options, includeDragEl) {
1016 var currentChild = 0,
1017 i = 0,
1018 children = el.children;
1019 while (i < children.length) {
1020 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
1021 if (currentChild === childNum) {
1022 return children[i];
1023 }
1024 currentChild++;
1025 }
1026 i++;
1027 }
1028 return null;
1029 }
1030
1031 /**
1032 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
1033 * @param {HTMLElement} el Parent element
1034 * @param {selector} selector Any other elements that should be ignored
1035 * @return {HTMLElement} The last child, ignoring ghostEl
1036 */
1037 function lastChild(el, selector) {
1038 var last = el.lastElementChild;
1039 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
1040 last = last.previousElementSibling;
1041 }
1042 return last || null;
1043 }
1044
1045 /**
1046 * Returns the index of an element within its parent for a selected set of
1047 * elements
1048 * @param {HTMLElement} el
1049 * @param {selector} selector
1050 * @return {number}
1051 */
1052 function index(el, selector) {
1053 var index = 0;
1054 if (!el || !el.parentNode) {
1055 return -1;
1056 }
1057
1058 /* jshint boss:true */
1059 while (el = el.previousElementSibling) {
1060 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
1061 index++;
1062 }
1063 }
1064 return index;
1065 }
1066
1067 /**
1068 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
1069 * The value is returned in real pixels.
1070 * @param {HTMLElement} el
1071 * @return {Array} Offsets in the format of [left, top]
1072 */
1073 function getRelativeScrollOffset(el) {
1074 var offsetLeft = 0,
1075 offsetTop = 0,
1076 winScroller = getWindowScrollingElement();
1077 if (el) {
1078 do {
1079 var elMatrix = matrix(el),
1080 scaleX = elMatrix.a,
1081 scaleY = elMatrix.d;
1082 offsetLeft += el.scrollLeft * scaleX;
1083 offsetTop += el.scrollTop * scaleY;
1084 } while (el !== winScroller && (el = el.parentNode));
1085 }
1086 return [offsetLeft, offsetTop];
1087 }
1088
1089 /**
1090 * Returns the index of the object within the given array
1091 * @param {Array} arr Array that may or may not hold the object
1092 * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
1093 * @return {Number} The index of the object in the array, or -1
1094 */
1095 function indexOfObject(arr, obj) {
1096 for (var i in arr) {
1097 if (!arr.hasOwnProperty(i)) continue;
1098 for (var key in obj) {
1099 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
1100 }
1101 }
1102 return -1;
1103 }
1104 function getParentAutoScrollElement(el, includeSelf) {
1105 // skip to window
1106 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
1107 var elem = el;
1108 var gotSelf = false;
1109 do {
1110 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
1111 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
1112 var elemCSS = css(elem);
1113 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
1114 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
1115 if (gotSelf || includeSelf) return elem;
1116 gotSelf = true;
1117 }
1118 }
1119 /* jshint boss:true */
1120 } while (elem = elem.parentNode);
1121 return getWindowScrollingElement();
1122 }
1123 function extend(dst, src) {
1124 if (dst && src) {
1125 for (var key in src) {
1126 if (src.hasOwnProperty(key)) {
1127 dst[key] = src[key];
1128 }
1129 }
1130 }
1131 return dst;
1132 }
1133 function isRectEqual(rect1, rect2) {
1134 return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
1135 }
1136 var _throttleTimeout;
1137 function throttle(callback, ms) {
1138 return function () {
1139 if (!_throttleTimeout) {
1140 var args = arguments,
1141 _this = this;
1142 if (args.length === 1) {
1143 callback.call(_this, args[0]);
1144 } else {
1145 callback.apply(_this, args);
1146 }
1147 _throttleTimeout = setTimeout(function () {
1148 _throttleTimeout = void 0;
1149 }, ms);
1150 }
1151 };
1152 }
1153 function cancelThrottle() {
1154 clearTimeout(_throttleTimeout);
1155 _throttleTimeout = void 0;
1156 }
1157 function scrollBy(el, x, y) {
1158 el.scrollLeft += x;
1159 el.scrollTop += y;
1160 }
1161 function clone(el) {
1162 var Polymer = window.Polymer;
1163 var $ = window.jQuery || window.Zepto;
1164 if (Polymer && Polymer.dom) {
1165 return Polymer.dom(el).cloneNode(true);
1166 } else if ($) {
1167 return $(el).clone(true)[0];
1168 } else {
1169 return el.cloneNode(true);
1170 }
1171 }
1172 function setRect(el, rect) {
1173 css(el, 'position', 'absolute');
1174 css(el, 'top', rect.top);
1175 css(el, 'left', rect.left);
1176 css(el, 'width', rect.width);
1177 css(el, 'height', rect.height);
1178 }
1179 function unsetRect(el) {
1180 css(el, 'position', '');
1181 css(el, 'top', '');
1182 css(el, 'left', '');
1183 css(el, 'width', '');
1184 css(el, 'height', '');
1185 }
1186 function getChildContainingRectFromElement(container, options, ghostEl) {
1187 var rect = {};
1188 Array.from(container.children).forEach(function (child) {
1189 var _rect$left, _rect$top, _rect$right, _rect$bottom;
1190 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
1191 var childRect = getRect(child);
1192 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
1193 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
1194 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
1195 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
1196 });
1197 rect.width = rect.right - rect.left;
1198 rect.height = rect.bottom - rect.top;
1199 rect.x = rect.left;
1200 rect.y = rect.top;
1201 return rect;
1202 }
1203 var expando = 'Sortable' + new Date().getTime();
1204
1205 function AnimationStateManager() {
1206 var animationStates = [],
1207 animationCallbackId;
1208 return {
1209 captureAnimationState: function captureAnimationState() {
1210 animationStates = [];
1211 if (!this.options.animation) return;
1212 var children = [].slice.call(this.el.children);
1213 children.forEach(function (child) {
1214 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
1215 animationStates.push({
1216 target: child,
1217 rect: getRect(child)
1218 });
1219 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
1220
1221 // If animating: compensate for current animation
1222 if (child.thisAnimationDuration) {
1223 var childMatrix = matrix(child, true);
1224 if (childMatrix) {
1225 fromRect.top -= childMatrix.f;
1226 fromRect.left -= childMatrix.e;
1227 }
1228 }
1229 child.fromRect = fromRect;
1230 });
1231 },
1232 addAnimationState: function addAnimationState(state) {
1233 animationStates.push(state);
1234 },
1235 removeAnimationState: function removeAnimationState(target) {
1236 animationStates.splice(indexOfObject(animationStates, {
1237 target: target
1238 }), 1);
1239 },
1240 animateAll: function animateAll(callback) {
1241 var _this = this;
1242 if (!this.options.animation) {
1243 clearTimeout(animationCallbackId);
1244 if (typeof callback === 'function') callback();
1245 return;
1246 }
1247 var animating = false,
1248 animationTime = 0;
1249 animationStates.forEach(function (state) {
1250 var time = 0,
1251 target = state.target,
1252 fromRect = target.fromRect,
1253 toRect = getRect(target),
1254 prevFromRect = target.prevFromRect,
1255 prevToRect = target.prevToRect,
1256 animatingRect = state.rect,
1257 targetMatrix = matrix(target, true);
1258 if (targetMatrix) {
1259 // Compensate for current animation
1260 toRect.top -= targetMatrix.f;
1261 toRect.left -= targetMatrix.e;
1262 }
1263 target.toRect = toRect;
1264 if (target.thisAnimationDuration) {
1265 // Could also check if animatingRect is between fromRect and toRect
1266 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
1267 // Make sure animatingRect is on line between toRect & fromRect
1268 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
1269 // If returning to same place as started from animation and on same axis
1270 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
1271 }
1272 }
1273
1274 // if fromRect != toRect: animate
1275 if (!isRectEqual(toRect, fromRect)) {
1276 target.prevFromRect = fromRect;
1277 target.prevToRect = toRect;
1278 if (!time) {
1279 time = _this.options.animation;
1280 }
1281 _this.animate(target, animatingRect, toRect, time);
1282 }
1283 if (time) {
1284 animating = true;
1285 animationTime = Math.max(animationTime, time);
1286 clearTimeout(target.animationResetTimer);
1287 target.animationResetTimer = setTimeout(function () {
1288 target.animationTime = 0;
1289 target.prevFromRect = null;
1290 target.fromRect = null;
1291 target.prevToRect = null;
1292 target.thisAnimationDuration = null;
1293 }, time);
1294 target.thisAnimationDuration = time;
1295 }
1296 });
1297 clearTimeout(animationCallbackId);
1298 if (!animating) {
1299 if (typeof callback === 'function') callback();
1300 } else {
1301 animationCallbackId = setTimeout(function () {
1302 if (typeof callback === 'function') callback();
1303 }, animationTime);
1304 }
1305 animationStates = [];
1306 },
1307 animate: function animate(target, currentRect, toRect, duration) {
1308 if (duration) {
1309 css(target, 'transition', '');
1310 css(target, 'transform', '');
1311 var elMatrix = matrix(this.el),
1312 scaleX = elMatrix && elMatrix.a,
1313 scaleY = elMatrix && elMatrix.d,
1314 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
1315 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
1316 target.animatingX = !!translateX;
1317 target.animatingY = !!translateY;
1318 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
1319 this.forRepaintDummy = repaint(target); // repaint
1320
1321 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
1322 css(target, 'transform', 'translate3d(0,0,0)');
1323 typeof target.animated === 'number' && clearTimeout(target.animated);
1324 target.animated = setTimeout(function () {
1325 css(target, 'transition', '');
1326 css(target, 'transform', '');
1327 target.animated = false;
1328 target.animatingX = false;
1329 target.animatingY = false;
1330 }, duration);
1331 }
1332 }
1333 };
1334 }
1335 function repaint(target) {
1336 return target.offsetWidth;
1337 }
1338 function calculateRealTime(animatingRect, fromRect, toRect, options) {
1339 return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
1340 }
1341
1342 var plugins = [];
1343 var defaults = {
1344 initializeByDefault: true
1345 };
1346 var PluginManager = {
1347 mount: function mount(plugin) {
1348 // Set default static properties
1349 for (var option in defaults) {
1350 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
1351 plugin[option] = defaults[option];
1352 }
1353 }
1354 plugins.forEach(function (p) {
1355 if (p.pluginName === plugin.pluginName) {
1356 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
1357 }
1358 });
1359 plugins.push(plugin);
1360 },
1361 pluginEvent: function pluginEvent(eventName, sortable, evt) {
1362 var _this = this;
1363 this.eventCanceled = false;
1364 evt.cancel = function () {
1365 _this.eventCanceled = true;
1366 };
1367 var eventNameGlobal = eventName + 'Global';
1368 plugins.forEach(function (plugin) {
1369 if (!sortable[plugin.pluginName]) return;
1370 // Fire global events if it exists in this sortable
1371 if (sortable[plugin.pluginName][eventNameGlobal]) {
1372 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
1373 sortable: sortable
1374 }, evt));
1375 }
1376
1377 // Only fire plugin event if plugin is enabled in this sortable,
1378 // and plugin has event defined
1379 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
1380 sortable[plugin.pluginName][eventName](_objectSpread2({
1381 sortable: sortable
1382 }, evt));
1383 }
1384 });
1385 },
1386 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
1387 plugins.forEach(function (plugin) {
1388 var pluginName = plugin.pluginName;
1389 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
1390 var initialized = new plugin(sortable, el, sortable.options);
1391 initialized.sortable = sortable;
1392 initialized.options = sortable.options;
1393 sortable[pluginName] = initialized;
1394
1395 // Add default options from plugin
1396 _extends(defaults, initialized.defaults);
1397 });
1398 for (var option in sortable.options) {
1399 if (!sortable.options.hasOwnProperty(option)) continue;
1400 var modified = this.modifyOption(sortable, option, sortable.options[option]);
1401 if (typeof modified !== 'undefined') {
1402 sortable.options[option] = modified;
1403 }
1404 }
1405 },
1406 getEventProperties: function getEventProperties(name, sortable) {
1407 var eventProperties = {};
1408 plugins.forEach(function (plugin) {
1409 if (typeof plugin.eventProperties !== 'function') return;
1410 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
1411 });
1412 return eventProperties;
1413 },
1414 modifyOption: function modifyOption(sortable, name, value) {
1415 var modifiedValue;
1416 plugins.forEach(function (plugin) {
1417 // Plugin must exist on the Sortable
1418 if (!sortable[plugin.pluginName]) return;
1419
1420 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
1421 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
1422 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
1423 }
1424 });
1425 return modifiedValue;
1426 }
1427 };
1428
1429 function dispatchEvent(_ref) {
1430 var sortable = _ref.sortable,
1431 rootEl = _ref.rootEl,
1432 name = _ref.name,
1433 targetEl = _ref.targetEl,
1434 cloneEl = _ref.cloneEl,
1435 toEl = _ref.toEl,
1436 fromEl = _ref.fromEl,
1437 oldIndex = _ref.oldIndex,
1438 newIndex = _ref.newIndex,
1439 oldDraggableIndex = _ref.oldDraggableIndex,
1440 newDraggableIndex = _ref.newDraggableIndex,
1441 originalEvent = _ref.originalEvent,
1442 putSortable = _ref.putSortable,
1443 extraEventProperties = _ref.extraEventProperties;
1444 sortable = sortable || rootEl && rootEl[expando];
1445 if (!sortable) return;
1446 var evt,
1447 options = sortable.options,
1448 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
1449 // Support for new CustomEvent feature
1450 if (window.CustomEvent && !IE11OrLess && !Edge) {
1451 evt = new CustomEvent(name, {
1452 bubbles: true,
1453 cancelable: true
1454 });
1455 } else {
1456 evt = document.createEvent('Event');
1457 evt.initEvent(name, true, true);
1458 }
1459 evt.to = toEl || rootEl;
1460 evt.from = fromEl || rootEl;
1461 evt.item = targetEl || rootEl;
1462 evt.clone = cloneEl;
1463 evt.oldIndex = oldIndex;
1464 evt.newIndex = newIndex;
1465 evt.oldDraggableIndex = oldDraggableIndex;
1466 evt.newDraggableIndex = newDraggableIndex;
1467 evt.originalEvent = originalEvent;
1468 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
1469 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
1470 for (var option in allEventProperties) {
1471 evt[option] = allEventProperties[option];
1472 }
1473 if (rootEl) {
1474 rootEl.dispatchEvent(evt);
1475 }
1476 if (options[onName]) {
1477 options[onName].call(sortable, evt);
1478 }
1479 }
1480
1481 var _excluded = ["evt"];
1482 var pluginEvent = function pluginEvent(eventName, sortable) {
1483 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
1484 originalEvent = _ref.evt,
1485 data = _objectWithoutProperties(_ref, _excluded);
1486 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
1487 dragEl: dragEl,
1488 parentEl: parentEl,
1489 ghostEl: ghostEl,
1490 rootEl: rootEl,
1491 nextEl: nextEl,
1492 lastDownEl: lastDownEl,
1493 cloneEl: cloneEl,
1494 cloneHidden: cloneHidden,
1495 dragStarted: moved,
1496 putSortable: putSortable,
1497 activeSortable: Sortable.active,
1498 originalEvent: originalEvent,
1499 oldIndex: oldIndex,
1500 oldDraggableIndex: oldDraggableIndex,
1501 newIndex: newIndex,
1502 newDraggableIndex: newDraggableIndex,
1503 hideGhostForTarget: _hideGhostForTarget,
1504 unhideGhostForTarget: _unhideGhostForTarget,
1505 cloneNowHidden: function cloneNowHidden() {
1506 cloneHidden = true;
1507 },
1508 cloneNowShown: function cloneNowShown() {
1509 cloneHidden = false;
1510 },
1511 dispatchSortableEvent: function dispatchSortableEvent(name) {
1512 _dispatchEvent({
1513 sortable: sortable,
1514 name: name,
1515 originalEvent: originalEvent
1516 });
1517 }
1518 }, data));
1519 };
1520 function _dispatchEvent(info) {
1521 dispatchEvent(_objectSpread2({
1522 putSortable: putSortable,
1523 cloneEl: cloneEl,
1524 targetEl: dragEl,
1525 rootEl: rootEl,
1526 oldIndex: oldIndex,
1527 oldDraggableIndex: oldDraggableIndex,
1528 newIndex: newIndex,
1529 newDraggableIndex: newDraggableIndex
1530 }, info));
1531 }
1532 var dragEl,
1533 parentEl,
1534 ghostEl,
1535 rootEl,
1536 nextEl,
1537 lastDownEl,
1538 cloneEl,
1539 cloneHidden,
1540 oldIndex,
1541 newIndex,
1542 oldDraggableIndex,
1543 newDraggableIndex,
1544 activeGroup,
1545 putSortable,
1546 awaitingDragStarted = false,
1547 ignoreNextClick = false,
1548 sortables = [],
1549 tapEvt,
1550 touchEvt,
1551 lastDx,
1552 lastDy,
1553 tapDistanceLeft,
1554 tapDistanceTop,
1555 moved,
1556 lastTarget,
1557 lastDirection,
1558 pastFirstInvertThresh = false,
1559 isCircumstantialInvert = false,
1560 targetMoveDistance,
1561 // For positioning ghost absolutely
1562 ghostRelativeParent,
1563 ghostRelativeParentInitialScroll = [],
1564 // (left, top)
1565
1566 _silent = false,
1567 savedInputChecked = [];
1568
1569 /** @const */
1570 var documentExists = typeof document !== 'undefined',
1571 PositionGhostAbsolutely = IOS,
1572 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
1573 // This will not pass for IE9, because IE9 DnD only works on anchors
1574 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
1575 supportCssPointerEvents = function () {
1576 if (!documentExists) return;
1577 // false when <= IE11
1578 if (IE11OrLess) {
1579 return false;
1580 }
1581 var el = document.createElement('x');
1582 el.style.cssText = 'pointer-events:auto';
1583 return el.style.pointerEvents === 'auto';
1584 }(),
1585 _detectDirection = function _detectDirection(el, options) {
1586 var elCSS = css(el),
1587 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
1588 child1 = getChild(el, 0, options),
1589 child2 = getChild(el, 1, options),
1590 firstChildCSS = child1 && css(child1),
1591 secondChildCSS = child2 && css(child2),
1592 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
1593 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
1594 if (elCSS.display === 'flex') {
1595 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
1596 }
1597 if (elCSS.display === 'grid') {
1598 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
1599 }
1600 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
1601 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
1602 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
1603 }
1604 return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
1605 },
1606 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
1607 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
1608 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
1609 dragElOppLength = vertical ? dragRect.width : dragRect.height,
1610 targetS1Opp = vertical ? targetRect.left : targetRect.top,
1611 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
1612 targetOppLength = vertical ? targetRect.width : targetRect.height;
1613 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
1614 },
1615 /**
1616 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
1617 * @param {Number} x X position
1618 * @param {Number} y Y position
1619 * @return {HTMLElement} Element of the first found nearest Sortable
1620 */
1621 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
1622 var ret;
1623 sortables.some(function (sortable) {
1624 var threshold = sortable[expando].options.emptyInsertThreshold;
1625 if (!threshold || lastChild(sortable)) return;
1626 var rect = getRect(sortable),
1627 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
1628 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
1629 if (insideHorizontally && insideVertically) {
1630 return ret = sortable;
1631 }
1632 });
1633 return ret;
1634 },
1635 _prepareGroup = function _prepareGroup(options) {
1636 function toFn(value, pull) {
1637 return function (to, from, dragEl, evt) {
1638 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
1639 if (value == null && (pull || sameGroup)) {
1640 // Default pull value
1641 // Default pull and put value if same group
1642 return true;
1643 } else if (value == null || value === false) {
1644 return false;
1645 } else if (pull && value === 'clone') {
1646 return value;
1647 } else if (typeof value === 'function') {
1648 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
1649 } else {
1650 var otherGroup = (pull ? to : from).options.group.name;
1651 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
1652 }
1653 };
1654 }
1655 var group = {};
1656 var originalGroup = options.group;
1657 if (!originalGroup || _typeof(originalGroup) != 'object') {
1658 originalGroup = {
1659 name: originalGroup
1660 };
1661 }
1662 group.name = originalGroup.name;
1663 group.checkPull = toFn(originalGroup.pull, true);
1664 group.checkPut = toFn(originalGroup.put);
1665 group.revertClone = originalGroup.revertClone;
1666 options.group = group;
1667 },
1668 _hideGhostForTarget = function _hideGhostForTarget() {
1669 if (!supportCssPointerEvents && ghostEl) {
1670 css(ghostEl, 'display', 'none');
1671 }
1672 },
1673 _unhideGhostForTarget = function _unhideGhostForTarget() {
1674 if (!supportCssPointerEvents && ghostEl) {
1675 css(ghostEl, 'display', '');
1676 }
1677 };
1678
1679 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
1680 if (documentExists && !ChromeForAndroid) {
1681 document.addEventListener('click', function (evt) {
1682 if (ignoreNextClick) {
1683 evt.preventDefault();
1684 evt.stopPropagation && evt.stopPropagation();
1685 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
1686 ignoreNextClick = false;
1687 return false;
1688 }
1689 }, true);
1690 }
1691 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
1692 if (dragEl) {
1693 evt = evt.touches ? evt.touches[0] : evt;
1694 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
1695 if (nearest) {
1696 // Create imitation event
1697 var event = {};
1698 for (var i in evt) {
1699 if (evt.hasOwnProperty(i)) {
1700 event[i] = evt[i];
1701 }
1702 }
1703 event.target = event.rootEl = nearest;
1704 event.preventDefault = void 0;
1705 event.stopPropagation = void 0;
1706 nearest[expando]._onDragOver(event);
1707 }
1708 }
1709 };
1710 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
1711 if (dragEl) {
1712 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
1713 }
1714 };
1715
1716 /**
1717 * @class Sortable
1718 * @param {HTMLElement} el
1719 * @param {Object} [options]
1720 */
1721 function Sortable(el, options) {
1722 if (!(el && el.nodeType && el.nodeType === 1)) {
1723 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
1724 }
1725 this.el = el; // root element
1726 this.options = options = _extends({}, options);
1727
1728 // Export instance
1729 el[expando] = this;
1730 var defaults = {
1731 group: null,
1732 sort: true,
1733 disabled: false,
1734 store: null,
1735 handle: null,
1736 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
1737 swapThreshold: 1,
1738 // percentage; 0 <= x <= 1
1739 invertSwap: false,
1740 // invert always
1741 invertedSwapThreshold: null,
1742 // will be set to same as swapThreshold if default
1743 removeCloneOnHide: true,
1744 direction: function direction() {
1745 return _detectDirection(el, this.options);
1746 },
1747 ghostClass: 'sortable-ghost',
1748 chosenClass: 'sortable-chosen',
1749 dragClass: 'sortable-drag',
1750 ignore: 'a, img',
1751 filter: null,
1752 preventOnFilter: true,
1753 animation: 0,
1754 easing: null,
1755 setData: function setData(dataTransfer, dragEl) {
1756 dataTransfer.setData('Text', dragEl.textContent);
1757 },
1758 dropBubble: false,
1759 dragoverBubble: false,
1760 dataIdAttr: 'data-id',
1761 delay: 0,
1762 delayOnTouchOnly: false,
1763 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
1764 forceFallback: false,
1765 fallbackClass: 'sortable-fallback',
1766 fallbackOnBody: false,
1767 fallbackTolerance: 0,
1768 fallbackOffset: {
1769 x: 0,
1770 y: 0
1771 },
1772 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
1773 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
1774 emptyInsertThreshold: 5
1775 };
1776 PluginManager.initializePlugins(this, el, defaults);
1777
1778 // Set default options
1779 for (var name in defaults) {
1780 !(name in options) && (options[name] = defaults[name]);
1781 }
1782 _prepareGroup(options);
1783
1784 // Bind all private methods
1785 for (var fn in this) {
1786 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
1787 this[fn] = this[fn].bind(this);
1788 }
1789 }
1790
1791 // Setup drag mode
1792 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
1793 if (this.nativeDraggable) {
1794 // Touch start threshold cannot be greater than the native dragstart threshold
1795 this.options.touchStartThreshold = 1;
1796 }
1797
1798 // Bind events
1799 if (options.supportPointer) {
1800 on(el, 'pointerdown', this._onTapStart);
1801 } else {
1802 on(el, 'mousedown', this._onTapStart);
1803 on(el, 'touchstart', this._onTapStart);
1804 }
1805 if (this.nativeDraggable) {
1806 on(el, 'dragover', this);
1807 on(el, 'dragenter', this);
1808 }
1809 sortables.push(this.el);
1810
1811 // Restore sorting
1812 options.store && options.store.get && this.sort(options.store.get(this) || []);
1813
1814 // Add animation state manager
1815 _extends(this, AnimationStateManager());
1816 }
1817 Sortable.prototype = /** @lends Sortable.prototype */{
1818 constructor: Sortable,
1819 _isOutsideThisEl: function _isOutsideThisEl(target) {
1820 if (!this.el.contains(target) && target !== this.el) {
1821 lastTarget = null;
1822 }
1823 },
1824 _getDirection: function _getDirection(evt, target) {
1825 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
1826 },
1827 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
1828 if (!evt.cancelable) return;
1829 var _this = this,
1830 el = this.el,
1831 options = this.options,
1832 preventOnFilter = options.preventOnFilter,
1833 type = evt.type,
1834 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
1835 target = (touch || evt).target,
1836 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
1837 filter = options.filter;
1838 _saveInputCheckedState(el);
1839
1840 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
1841 if (dragEl) {
1842 return;
1843 }
1844 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
1845 return; // only left button and enabled
1846 }
1847
1848 // cancel dnd if original target is content editable
1849 if (originalTarget.isContentEditable) {
1850 return;
1851 }
1852
1853 // Safari ignores further event handling after mousedown
1854 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
1855 return;
1856 }
1857 target = closest(target, options.draggable, el, false);
1858 if (target && target.animated) {
1859 return;
1860 }
1861 if (lastDownEl === target) {
1862 // Ignoring duplicate `down`
1863 return;
1864 }
1865
1866 // Get the index of the dragged element within its parent
1867 oldIndex = index(target);
1868 oldDraggableIndex = index(target, options.draggable);
1869
1870 // Check filter
1871 if (typeof filter === 'function') {
1872 if (filter.call(this, evt, target, this)) {
1873 _dispatchEvent({
1874 sortable: _this,
1875 rootEl: originalTarget,
1876 name: 'filter',
1877 targetEl: target,
1878 toEl: el,
1879 fromEl: el
1880 });
1881 pluginEvent('filter', _this, {
1882 evt: evt
1883 });
1884 preventOnFilter && evt.preventDefault();
1885 return; // cancel dnd
1886 }
1887 } else if (filter) {
1888 filter = filter.split(',').some(function (criteria) {
1889 criteria = closest(originalTarget, criteria.trim(), el, false);
1890 if (criteria) {
1891 _dispatchEvent({
1892 sortable: _this,
1893 rootEl: criteria,
1894 name: 'filter',
1895 targetEl: target,
1896 fromEl: el,
1897 toEl: el
1898 });
1899 pluginEvent('filter', _this, {
1900 evt: evt
1901 });
1902 return true;
1903 }
1904 });
1905 if (filter) {
1906 preventOnFilter && evt.preventDefault();
1907 return; // cancel dnd
1908 }
1909 }
1910 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
1911 return;
1912 }
1913
1914 // Prepare `dragstart`
1915 this._prepareDragStart(evt, touch, target);
1916 },
1917 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
1918 var _this = this,
1919 el = _this.el,
1920 options = _this.options,
1921 ownerDocument = el.ownerDocument,
1922 dragStartFn;
1923 if (target && !dragEl && target.parentNode === el) {
1924 var dragRect = getRect(target);
1925 rootEl = el;
1926 dragEl = target;
1927 parentEl = dragEl.parentNode;
1928 nextEl = dragEl.nextSibling;
1929 lastDownEl = target;
1930 activeGroup = options.group;
1931 Sortable.dragged = dragEl;
1932 tapEvt = {
1933 target: dragEl,
1934 clientX: (touch || evt).clientX,
1935 clientY: (touch || evt).clientY
1936 };
1937 tapDistanceLeft = tapEvt.clientX - dragRect.left;
1938 tapDistanceTop = tapEvt.clientY - dragRect.top;
1939 this._lastX = (touch || evt).clientX;
1940 this._lastY = (touch || evt).clientY;
1941 dragEl.style['will-change'] = 'all';
1942 dragStartFn = function dragStartFn() {
1943 pluginEvent('delayEnded', _this, {
1944 evt: evt
1945 });
1946 if (Sortable.eventCanceled) {
1947 _this._onDrop();
1948 return;
1949 }
1950 // Delayed drag has been triggered
1951 // we can re-enable the events: touchmove/mousemove
1952 _this._disableDelayedDragEvents();
1953 if (!FireFox && _this.nativeDraggable) {
1954 dragEl.draggable = true;
1955 }
1956
1957 // Bind the events: dragstart/dragend
1958 _this._triggerDragStart(evt, touch);
1959
1960 // Drag start event
1961 _dispatchEvent({
1962 sortable: _this,
1963 name: 'choose',
1964 originalEvent: evt
1965 });
1966
1967 // Chosen item
1968 toggleClass(dragEl, options.chosenClass, true);
1969 };
1970
1971 // Disable "draggable"
1972 options.ignore.split(',').forEach(function (criteria) {
1973 find(dragEl, criteria.trim(), _disableDraggable);
1974 });
1975 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
1976 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
1977 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
1978 if (options.supportPointer) {
1979 on(ownerDocument, 'pointerup', _this._onDrop);
1980 // Native D&D triggers pointercancel
1981 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
1982 } else {
1983 on(ownerDocument, 'mouseup', _this._onDrop);
1984 on(ownerDocument, 'touchend', _this._onDrop);
1985 on(ownerDocument, 'touchcancel', _this._onDrop);
1986 }
1987
1988 // Make dragEl draggable (must be before delay for FireFox)
1989 if (FireFox && this.nativeDraggable) {
1990 this.options.touchStartThreshold = 4;
1991 dragEl.draggable = true;
1992 }
1993 pluginEvent('delayStart', this, {
1994 evt: evt
1995 });
1996
1997 // Delay is impossible for native DnD in Edge or IE
1998 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
1999 if (Sortable.eventCanceled) {
2000 this._onDrop();
2001 return;
2002 }
2003 // If the user moves the pointer or let go the click or touch
2004 // before the delay has been reached:
2005 // disable the delayed drag
2006 if (options.supportPointer) {
2007 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
2008 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
2009 } else {
2010 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
2011 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
2012 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
2013 }
2014 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
2015 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
2016 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
2017 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
2018 } else {
2019 dragStartFn();
2020 }
2021 }
2022 },
2023 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
2024 var touch = e.touches ? e.touches[0] : e;
2025 if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
2026 this._disableDelayedDrag();
2027 }
2028 },
2029 _disableDelayedDrag: function _disableDelayedDrag() {
2030 dragEl && _disableDraggable(dragEl);
2031 clearTimeout(this._dragStartTimer);
2032 this._disableDelayedDragEvents();
2033 },
2034 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
2035 var ownerDocument = this.el.ownerDocument;
2036 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
2037 off(ownerDocument, 'touchend', this._disableDelayedDrag);
2038 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
2039 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
2040 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
2041 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
2042 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
2043 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
2044 },
2045 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
2046 touch = touch || evt.pointerType == 'touch' && evt;
2047 if (!this.nativeDraggable || touch) {
2048 if (this.options.supportPointer) {
2049 on(document, 'pointermove', this._onTouchMove);
2050 } else if (touch) {
2051 on(document, 'touchmove', this._onTouchMove);
2052 } else {
2053 on(document, 'mousemove', this._onTouchMove);
2054 }
2055 } else {
2056 on(dragEl, 'dragend', this);
2057 on(rootEl, 'dragstart', this._onDragStart);
2058 }
2059 try {
2060 if (document.selection) {
2061 _nextTick(function () {
2062 document.selection.empty();
2063 });
2064 } else {
2065 window.getSelection().removeAllRanges();
2066 }
2067 } catch (err) {}
2068 },
2069 _dragStarted: function _dragStarted(fallback, evt) {
2070 awaitingDragStarted = false;
2071 if (rootEl && dragEl) {
2072 pluginEvent('dragStarted', this, {
2073 evt: evt
2074 });
2075 if (this.nativeDraggable) {
2076 on(document, 'dragover', _checkOutsideTargetEl);
2077 }
2078 var options = this.options;
2079
2080 // Apply effect
2081 !fallback && toggleClass(dragEl, options.dragClass, false);
2082 toggleClass(dragEl, options.ghostClass, true);
2083 Sortable.active = this;
2084 fallback && this._appendGhost();
2085
2086 // Drag start event
2087 _dispatchEvent({
2088 sortable: this,
2089 name: 'start',
2090 originalEvent: evt
2091 });
2092 } else {
2093 this._nulling();
2094 }
2095 },
2096 _emulateDragOver: function _emulateDragOver() {
2097 if (touchEvt) {
2098 this._lastX = touchEvt.clientX;
2099 this._lastY = touchEvt.clientY;
2100 _hideGhostForTarget();
2101 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
2102 var parent = target;
2103 while (target && target.shadowRoot) {
2104 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
2105 if (target === parent) break;
2106 parent = target;
2107 }
2108 dragEl.parentNode[expando]._isOutsideThisEl(target);
2109 if (parent) {
2110 do {
2111 if (parent[expando]) {
2112 var inserted = void 0;
2113 inserted = parent[expando]._onDragOver({
2114 clientX: touchEvt.clientX,
2115 clientY: touchEvt.clientY,
2116 target: target,
2117 rootEl: parent
2118 });
2119 if (inserted && !this.options.dragoverBubble) {
2120 break;
2121 }
2122 }
2123 target = parent; // store last element
2124 }
2125 /* jshint boss:true */ while (parent = getParentOrHost(parent));
2126 }
2127 _unhideGhostForTarget();
2128 }
2129 },
2130 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
2131 if (tapEvt) {
2132 var options = this.options,
2133 fallbackTolerance = options.fallbackTolerance,
2134 fallbackOffset = options.fallbackOffset,
2135 touch = evt.touches ? evt.touches[0] : evt,
2136 ghostMatrix = ghostEl && matrix(ghostEl, true),
2137 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
2138 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
2139 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
2140 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
2141 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
2142
2143 // only set the status to dragging, when we are actually dragging
2144 if (!Sortable.active && !awaitingDragStarted) {
2145 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
2146 return;
2147 }
2148 this._onDragStart(evt, true);
2149 }
2150 if (ghostEl) {
2151 if (ghostMatrix) {
2152 ghostMatrix.e += dx - (lastDx || 0);
2153 ghostMatrix.f += dy - (lastDy || 0);
2154 } else {
2155 ghostMatrix = {
2156 a: 1,
2157 b: 0,
2158 c: 0,
2159 d: 1,
2160 e: dx,
2161 f: dy
2162 };
2163 }
2164 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
2165 css(ghostEl, 'webkitTransform', cssMatrix);
2166 css(ghostEl, 'mozTransform', cssMatrix);
2167 css(ghostEl, 'msTransform', cssMatrix);
2168 css(ghostEl, 'transform', cssMatrix);
2169 lastDx = dx;
2170 lastDy = dy;
2171 touchEvt = touch;
2172 }
2173 evt.cancelable && evt.preventDefault();
2174 }
2175 },
2176 _appendGhost: function _appendGhost() {
2177 // Bug if using scale(): https://stackoverflow.com/questions/2637058
2178 // Not being adjusted for
2179 if (!ghostEl) {
2180 var container = this.options.fallbackOnBody ? document.body : rootEl,
2181 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
2182 options = this.options;
2183
2184 // Position absolutely
2185 if (PositionGhostAbsolutely) {
2186 // Get relatively positioned parent
2187 ghostRelativeParent = container;
2188 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
2189 ghostRelativeParent = ghostRelativeParent.parentNode;
2190 }
2191 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
2192 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
2193 rect.top += ghostRelativeParent.scrollTop;
2194 rect.left += ghostRelativeParent.scrollLeft;
2195 } else {
2196 ghostRelativeParent = getWindowScrollingElement();
2197 }
2198 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
2199 }
2200 ghostEl = dragEl.cloneNode(true);
2201 toggleClass(ghostEl, options.ghostClass, false);
2202 toggleClass(ghostEl, options.fallbackClass, true);
2203 toggleClass(ghostEl, options.dragClass, true);
2204 css(ghostEl, 'transition', '');
2205 css(ghostEl, 'transform', '');
2206 css(ghostEl, 'box-sizing', 'border-box');
2207 css(ghostEl, 'margin', 0);
2208 css(ghostEl, 'top', rect.top);
2209 css(ghostEl, 'left', rect.left);
2210 css(ghostEl, 'width', rect.width);
2211 css(ghostEl, 'height', rect.height);
2212 css(ghostEl, 'opacity', '0.8');
2213 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
2214 css(ghostEl, 'zIndex', '100000');
2215 css(ghostEl, 'pointerEvents', 'none');
2216 Sortable.ghost = ghostEl;
2217 container.appendChild(ghostEl);
2218
2219 // Set transform-origin
2220 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
2221 }
2222 },
2223 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
2224 var _this = this;
2225 var dataTransfer = evt.dataTransfer;
2226 var options = _this.options;
2227 pluginEvent('dragStart', this, {
2228 evt: evt
2229 });
2230 if (Sortable.eventCanceled) {
2231 this._onDrop();
2232 return;
2233 }
2234 pluginEvent('setupClone', this);
2235 if (!Sortable.eventCanceled) {
2236 cloneEl = clone(dragEl);
2237 cloneEl.removeAttribute("id");
2238 cloneEl.draggable = false;
2239 cloneEl.style['will-change'] = '';
2240 this._hideClone();
2241 toggleClass(cloneEl, this.options.chosenClass, false);
2242 Sortable.clone = cloneEl;
2243 }
2244
2245 // #1143: IFrame support workaround
2246 _this.cloneId = _nextTick(function () {
2247 pluginEvent('clone', _this);
2248 if (Sortable.eventCanceled) return;
2249 if (!_this.options.removeCloneOnHide) {
2250 rootEl.insertBefore(cloneEl, dragEl);
2251 }
2252 _this._hideClone();
2253 _dispatchEvent({
2254 sortable: _this,
2255 name: 'clone'
2256 });
2257 });
2258 !fallback && toggleClass(dragEl, options.dragClass, true);
2259
2260 // Set proper drop events
2261 if (fallback) {
2262 ignoreNextClick = true;
2263 _this._loopId = setInterval(_this._emulateDragOver, 50);
2264 } else {
2265 // Undo what was set in _prepareDragStart before drag started
2266 off(document, 'mouseup', _this._onDrop);
2267 off(document, 'touchend', _this._onDrop);
2268 off(document, 'touchcancel', _this._onDrop);
2269 if (dataTransfer) {
2270 dataTransfer.effectAllowed = 'move';
2271 options.setData && options.setData.call(_this, dataTransfer, dragEl);
2272 }
2273 on(document, 'drop', _this);
2274
2275 // #1276 fix:
2276 css(dragEl, 'transform', 'translateZ(0)');
2277 }
2278 awaitingDragStarted = true;
2279 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
2280 on(document, 'selectstart', _this);
2281 moved = true;
2282 window.getSelection().removeAllRanges();
2283 if (Safari) {
2284 css(document.body, 'user-select', 'none');
2285 }
2286 },
2287 // Returns true - if no further action is needed (either inserted or another condition)
2288 _onDragOver: function _onDragOver( /**Event*/evt) {
2289 var el = this.el,
2290 target = evt.target,
2291 dragRect,
2292 targetRect,
2293 revert,
2294 options = this.options,
2295 group = options.group,
2296 activeSortable = Sortable.active,
2297 isOwner = activeGroup === group,
2298 canSort = options.sort,
2299 fromSortable = putSortable || activeSortable,
2300 vertical,
2301 _this = this,
2302 completedFired = false;
2303 if (_silent) return;
2304 function dragOverEvent(name, extra) {
2305 pluginEvent(name, _this, _objectSpread2({
2306 evt: evt,
2307 isOwner: isOwner,
2308 axis: vertical ? 'vertical' : 'horizontal',
2309 revert: revert,
2310 dragRect: dragRect,
2311 targetRect: targetRect,
2312 canSort: canSort,
2313 fromSortable: fromSortable,
2314 target: target,
2315 completed: completed,
2316 onMove: function onMove(target, after) {
2317 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
2318 },
2319 changed: changed
2320 }, extra));
2321 }
2322
2323 // Capture animation state
2324 function capture() {
2325 dragOverEvent('dragOverAnimationCapture');
2326 _this.captureAnimationState();
2327 if (_this !== fromSortable) {
2328 fromSortable.captureAnimationState();
2329 }
2330 }
2331
2332 // Return invocation when dragEl is inserted (or completed)
2333 function completed(insertion) {
2334 dragOverEvent('dragOverCompleted', {
2335 insertion: insertion
2336 });
2337 if (insertion) {
2338 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
2339 if (isOwner) {
2340 activeSortable._hideClone();
2341 } else {
2342 activeSortable._showClone(_this);
2343 }
2344 if (_this !== fromSortable) {
2345 // Set ghost class to new sortable's ghost class
2346 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
2347 toggleClass(dragEl, options.ghostClass, true);
2348 }
2349 if (putSortable !== _this && _this !== Sortable.active) {
2350 putSortable = _this;
2351 } else if (_this === Sortable.active && putSortable) {
2352 putSortable = null;
2353 }
2354
2355 // Animation
2356 if (fromSortable === _this) {
2357 _this._ignoreWhileAnimating = target;
2358 }
2359 _this.animateAll(function () {
2360 dragOverEvent('dragOverAnimationComplete');
2361 _this._ignoreWhileAnimating = null;
2362 });
2363 if (_this !== fromSortable) {
2364 fromSortable.animateAll();
2365 fromSortable._ignoreWhileAnimating = null;
2366 }
2367 }
2368
2369 // Null lastTarget if it is not inside a previously swapped element
2370 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
2371 lastTarget = null;
2372 }
2373
2374 // no bubbling and not fallback
2375 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
2376 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
2377
2378 // Do not detect for empty insert if already inserted
2379 !insertion && nearestEmptyInsertDetectEvent(evt);
2380 }
2381 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
2382 return completedFired = true;
2383 }
2384
2385 // Call when dragEl has been inserted
2386 function changed() {
2387 newIndex = index(dragEl);
2388 newDraggableIndex = index(dragEl, options.draggable);
2389 _dispatchEvent({
2390 sortable: _this,
2391 name: 'change',
2392 toEl: el,
2393 newIndex: newIndex,
2394 newDraggableIndex: newDraggableIndex,
2395 originalEvent: evt
2396 });
2397 }
2398 if (evt.preventDefault !== void 0) {
2399 evt.cancelable && evt.preventDefault();
2400 }
2401 target = closest(target, options.draggable, el, true);
2402 dragOverEvent('dragOver');
2403 if (Sortable.eventCanceled) return completedFired;
2404 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
2405 return completed(false);
2406 }
2407 ignoreNextClick = false;
2408 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
2409 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
2410 vertical = this._getDirection(evt, target) === 'vertical';
2411 dragRect = getRect(dragEl);
2412 dragOverEvent('dragOverValid');
2413 if (Sortable.eventCanceled) return completedFired;
2414 if (revert) {
2415 parentEl = rootEl; // actualization
2416 capture();
2417 this._hideClone();
2418 dragOverEvent('revert');
2419 if (!Sortable.eventCanceled) {
2420 if (nextEl) {
2421 rootEl.insertBefore(dragEl, nextEl);
2422 } else {
2423 rootEl.appendChild(dragEl);
2424 }
2425 }
2426 return completed(true);
2427 }
2428 var elLastChild = lastChild(el, options.draggable);
2429 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
2430 // Insert to end of list
2431
2432 // If already at end of list: Do not insert
2433 if (elLastChild === dragEl) {
2434 return completed(false);
2435 }
2436
2437 // if there is a last element, it is the target
2438 if (elLastChild && el === evt.target) {
2439 target = elLastChild;
2440 }
2441 if (target) {
2442 targetRect = getRect(target);
2443 }
2444 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
2445 capture();
2446 if (elLastChild && elLastChild.nextSibling) {
2447 // the last draggable element is not the last node
2448 el.insertBefore(dragEl, elLastChild.nextSibling);
2449 } else {
2450 el.appendChild(dragEl);
2451 }
2452 parentEl = el; // actualization
2453
2454 changed();
2455 return completed(true);
2456 }
2457 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
2458 // Insert to start of list
2459 var firstChild = getChild(el, 0, options, true);
2460 if (firstChild === dragEl) {
2461 return completed(false);
2462 }
2463 target = firstChild;
2464 targetRect = getRect(target);
2465 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
2466 capture();
2467 el.insertBefore(dragEl, firstChild);
2468 parentEl = el; // actualization
2469
2470 changed();
2471 return completed(true);
2472 }
2473 } else if (target.parentNode === el) {
2474 targetRect = getRect(target);
2475 var direction = 0,
2476 targetBeforeFirstSwap,
2477 differentLevel = dragEl.parentNode !== el,
2478 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
2479 side1 = vertical ? 'top' : 'left',
2480 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
2481 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
2482 if (lastTarget !== target) {
2483 targetBeforeFirstSwap = targetRect[side1];
2484 pastFirstInvertThresh = false;
2485 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
2486 }
2487 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
2488 var sibling;
2489 if (direction !== 0) {
2490 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
2491 var dragIndex = index(dragEl);
2492 do {
2493 dragIndex -= direction;
2494 sibling = parentEl.children[dragIndex];
2495 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
2496 }
2497 // If dragEl is already beside target: Do not insert
2498 if (direction === 0 || sibling === target) {
2499 return completed(false);
2500 }
2501 lastTarget = target;
2502 lastDirection = direction;
2503 var nextSibling = target.nextElementSibling,
2504 after = false;
2505 after = direction === 1;
2506 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
2507 if (moveVector !== false) {
2508 if (moveVector === 1 || moveVector === -1) {
2509 after = moveVector === 1;
2510 }
2511 _silent = true;
2512 setTimeout(_unsilent, 30);
2513 capture();
2514 if (after && !nextSibling) {
2515 el.appendChild(dragEl);
2516 } else {
2517 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
2518 }
2519
2520 // Undo chrome's scroll adjustment (has no effect on other browsers)
2521 if (scrolledPastTop) {
2522 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
2523 }
2524 parentEl = dragEl.parentNode; // actualization
2525
2526 // must be done before animation
2527 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
2528 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
2529 }
2530 changed();
2531 return completed(true);
2532 }
2533 }
2534 if (el.contains(dragEl)) {
2535 return completed(false);
2536 }
2537 }
2538 return false;
2539 },
2540 _ignoreWhileAnimating: null,
2541 _offMoveEvents: function _offMoveEvents() {
2542 off(document, 'mousemove', this._onTouchMove);
2543 off(document, 'touchmove', this._onTouchMove);
2544 off(document, 'pointermove', this._onTouchMove);
2545 off(document, 'dragover', nearestEmptyInsertDetectEvent);
2546 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
2547 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
2548 },
2549 _offUpEvents: function _offUpEvents() {
2550 var ownerDocument = this.el.ownerDocument;
2551 off(ownerDocument, 'mouseup', this._onDrop);
2552 off(ownerDocument, 'touchend', this._onDrop);
2553 off(ownerDocument, 'pointerup', this._onDrop);
2554 off(ownerDocument, 'pointercancel', this._onDrop);
2555 off(ownerDocument, 'touchcancel', this._onDrop);
2556 off(document, 'selectstart', this);
2557 },
2558 _onDrop: function _onDrop( /**Event*/evt) {
2559 var el = this.el,
2560 options = this.options;
2561
2562 // Get the index of the dragged element within its parent
2563 newIndex = index(dragEl);
2564 newDraggableIndex = index(dragEl, options.draggable);
2565 pluginEvent('drop', this, {
2566 evt: evt
2567 });
2568 parentEl = dragEl && dragEl.parentNode;
2569
2570 // Get again after plugin event
2571 newIndex = index(dragEl);
2572 newDraggableIndex = index(dragEl, options.draggable);
2573 if (Sortable.eventCanceled) {
2574 this._nulling();
2575 return;
2576 }
2577 awaitingDragStarted = false;
2578 isCircumstantialInvert = false;
2579 pastFirstInvertThresh = false;
2580 clearInterval(this._loopId);
2581 clearTimeout(this._dragStartTimer);
2582 _cancelNextTick(this.cloneId);
2583 _cancelNextTick(this._dragStartId);
2584
2585 // Unbind events
2586 if (this.nativeDraggable) {
2587 off(document, 'drop', this);
2588 off(el, 'dragstart', this._onDragStart);
2589 }
2590 this._offMoveEvents();
2591 this._offUpEvents();
2592 if (Safari) {
2593 css(document.body, 'user-select', '');
2594 }
2595 css(dragEl, 'transform', '');
2596 if (evt) {
2597 if (moved) {
2598 evt.cancelable && evt.preventDefault();
2599 !options.dropBubble && evt.stopPropagation();
2600 }
2601 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
2602 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
2603 // Remove clone(s)
2604 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
2605 }
2606 if (dragEl) {
2607 if (this.nativeDraggable) {
2608 off(dragEl, 'dragend', this);
2609 }
2610 _disableDraggable(dragEl);
2611 dragEl.style['will-change'] = '';
2612
2613 // Remove classes
2614 // ghostClass is added in dragStarted
2615 if (moved && !awaitingDragStarted) {
2616 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
2617 }
2618 toggleClass(dragEl, this.options.chosenClass, false);
2619
2620 // Drag stop event
2621 _dispatchEvent({
2622 sortable: this,
2623 name: 'unchoose',
2624 toEl: parentEl,
2625 newIndex: null,
2626 newDraggableIndex: null,
2627 originalEvent: evt
2628 });
2629 if (rootEl !== parentEl) {
2630 if (newIndex >= 0) {
2631 // Add event
2632 _dispatchEvent({
2633 rootEl: parentEl,
2634 name: 'add',
2635 toEl: parentEl,
2636 fromEl: rootEl,
2637 originalEvent: evt
2638 });
2639
2640 // Remove event
2641 _dispatchEvent({
2642 sortable: this,
2643 name: 'remove',
2644 toEl: parentEl,
2645 originalEvent: evt
2646 });
2647
2648 // drag from one list and drop into another
2649 _dispatchEvent({
2650 rootEl: parentEl,
2651 name: 'sort',
2652 toEl: parentEl,
2653 fromEl: rootEl,
2654 originalEvent: evt
2655 });
2656 _dispatchEvent({
2657 sortable: this,
2658 name: 'sort',
2659 toEl: parentEl,
2660 originalEvent: evt
2661 });
2662 }
2663 putSortable && putSortable.save();
2664 } else {
2665 if (newIndex !== oldIndex) {
2666 if (newIndex >= 0) {
2667 // drag & drop within the same list
2668 _dispatchEvent({
2669 sortable: this,
2670 name: 'update',
2671 toEl: parentEl,
2672 originalEvent: evt
2673 });
2674 _dispatchEvent({
2675 sortable: this,
2676 name: 'sort',
2677 toEl: parentEl,
2678 originalEvent: evt
2679 });
2680 }
2681 }
2682 }
2683 if (Sortable.active) {
2684 /* jshint eqnull:true */
2685 if (newIndex == null || newIndex === -1) {
2686 newIndex = oldIndex;
2687 newDraggableIndex = oldDraggableIndex;
2688 }
2689 _dispatchEvent({
2690 sortable: this,
2691 name: 'end',
2692 toEl: parentEl,
2693 originalEvent: evt
2694 });
2695
2696 // Save sorting
2697 this.save();
2698 }
2699 }
2700 }
2701 this._nulling();
2702 },
2703 _nulling: function _nulling() {
2704 pluginEvent('nulling', this);
2705 rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
2706 var el = this.el;
2707 savedInputChecked.forEach(function (checkEl) {
2708 if (el.contains(checkEl)) {
2709 checkEl.checked = true;
2710 }
2711 });
2712 savedInputChecked.length = lastDx = lastDy = 0;
2713 },
2714 handleEvent: function handleEvent( /**Event*/evt) {
2715 switch (evt.type) {
2716 case 'drop':
2717 case 'dragend':
2718 this._onDrop(evt);
2719 break;
2720 case 'dragenter':
2721 case 'dragover':
2722 if (dragEl) {
2723 this._onDragOver(evt);
2724 _globalDragOver(evt);
2725 }
2726 break;
2727 case 'selectstart':
2728 evt.preventDefault();
2729 break;
2730 }
2731 },
2732 /**
2733 * Serializes the item into an array of string.
2734 * @returns {String[]}
2735 */
2736 toArray: function toArray() {
2737 var order = [],
2738 el,
2739 children = this.el.children,
2740 i = 0,
2741 n = children.length,
2742 options = this.options;
2743 for (; i < n; i++) {
2744 el = children[i];
2745 if (closest(el, options.draggable, this.el, false)) {
2746 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
2747 }
2748 }
2749 return order;
2750 },
2751 /**
2752 * Sorts the elements according to the array.
2753 * @param {String[]} order order of the items
2754 */
2755 sort: function sort(order, useAnimation) {
2756 var items = {},
2757 rootEl = this.el;
2758 this.toArray().forEach(function (id, i) {
2759 var el = rootEl.children[i];
2760 if (closest(el, this.options.draggable, rootEl, false)) {
2761 items[id] = el;
2762 }
2763 }, this);
2764 useAnimation && this.captureAnimationState();
2765 order.forEach(function (id) {
2766 if (items[id]) {
2767 rootEl.removeChild(items[id]);
2768 rootEl.appendChild(items[id]);
2769 }
2770 });
2771 useAnimation && this.animateAll();
2772 },
2773 /**
2774 * Save the current sorting
2775 */
2776 save: function save() {
2777 var store = this.options.store;
2778 store && store.set && store.set(this);
2779 },
2780 /**
2781 * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
2782 * @param {HTMLElement} el
2783 * @param {String} [selector] default: `options.draggable`
2784 * @returns {HTMLElement|null}
2785 */
2786 closest: function closest$1(el, selector) {
2787 return closest(el, selector || this.options.draggable, this.el, false);
2788 },
2789 /**
2790 * Set/get option
2791 * @param {string} name
2792 * @param {*} [value]
2793 * @returns {*}
2794 */
2795 option: function option(name, value) {
2796 var options = this.options;
2797 if (value === void 0) {
2798 return options[name];
2799 } else {
2800 var modifiedValue = PluginManager.modifyOption(this, name, value);
2801 if (typeof modifiedValue !== 'undefined') {
2802 options[name] = modifiedValue;
2803 } else {
2804 options[name] = value;
2805 }
2806 if (name === 'group') {
2807 _prepareGroup(options);
2808 }
2809 }
2810 },
2811 /**
2812 * Destroy
2813 */
2814 destroy: function destroy() {
2815 pluginEvent('destroy', this);
2816 var el = this.el;
2817 el[expando] = null;
2818 off(el, 'mousedown', this._onTapStart);
2819 off(el, 'touchstart', this._onTapStart);
2820 off(el, 'pointerdown', this._onTapStart);
2821 if (this.nativeDraggable) {
2822 off(el, 'dragover', this);
2823 off(el, 'dragenter', this);
2824 }
2825 // Remove draggable attributes
2826 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
2827 el.removeAttribute('draggable');
2828 });
2829 this._onDrop();
2830 this._disableDelayedDragEvents();
2831 sortables.splice(sortables.indexOf(this.el), 1);
2832 this.el = el = null;
2833 },
2834 _hideClone: function _hideClone() {
2835 if (!cloneHidden) {
2836 pluginEvent('hideClone', this);
2837 if (Sortable.eventCanceled) return;
2838 css(cloneEl, 'display', 'none');
2839 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
2840 cloneEl.parentNode.removeChild(cloneEl);
2841 }
2842 cloneHidden = true;
2843 }
2844 },
2845 _showClone: function _showClone(putSortable) {
2846 if (putSortable.lastPutMode !== 'clone') {
2847 this._hideClone();
2848 return;
2849 }
2850 if (cloneHidden) {
2851 pluginEvent('showClone', this);
2852 if (Sortable.eventCanceled) return;
2853
2854 // show clone at dragEl or original position
2855 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
2856 rootEl.insertBefore(cloneEl, dragEl);
2857 } else if (nextEl) {
2858 rootEl.insertBefore(cloneEl, nextEl);
2859 } else {
2860 rootEl.appendChild(cloneEl);
2861 }
2862 if (this.options.group.revertClone) {
2863 this.animate(dragEl, cloneEl);
2864 }
2865 css(cloneEl, 'display', '');
2866 cloneHidden = false;
2867 }
2868 }
2869 };
2870 function _globalDragOver( /**Event*/evt) {
2871 if (evt.dataTransfer) {
2872 evt.dataTransfer.dropEffect = 'move';
2873 }
2874 evt.cancelable && evt.preventDefault();
2875 }
2876 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
2877 var evt,
2878 sortable = fromEl[expando],
2879 onMoveFn = sortable.options.onMove,
2880 retVal;
2881 // Support for new CustomEvent feature
2882 if (window.CustomEvent && !IE11OrLess && !Edge) {
2883 evt = new CustomEvent('move', {
2884 bubbles: true,
2885 cancelable: true
2886 });
2887 } else {
2888 evt = document.createEvent('Event');
2889 evt.initEvent('move', true, true);
2890 }
2891 evt.to = toEl;
2892 evt.from = fromEl;
2893 evt.dragged = dragEl;
2894 evt.draggedRect = dragRect;
2895 evt.related = targetEl || toEl;
2896 evt.relatedRect = targetRect || getRect(toEl);
2897 evt.willInsertAfter = willInsertAfter;
2898 evt.originalEvent = originalEvent;
2899 fromEl.dispatchEvent(evt);
2900 if (onMoveFn) {
2901 retVal = onMoveFn.call(sortable, evt, originalEvent);
2902 }
2903 return retVal;
2904 }
2905 function _disableDraggable(el) {
2906 el.draggable = false;
2907 }
2908 function _unsilent() {
2909 _silent = false;
2910 }
2911 function _ghostIsFirst(evt, vertical, sortable) {
2912 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
2913 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
2914 var spacer = 10;
2915 return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left;
2916 }
2917 function _ghostIsLast(evt, vertical, sortable) {
2918 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
2919 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
2920 var spacer = 10;
2921 return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top;
2922 }
2923 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
2924 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
2925 targetLength = vertical ? targetRect.height : targetRect.width,
2926 targetS1 = vertical ? targetRect.top : targetRect.left,
2927 targetS2 = vertical ? targetRect.bottom : targetRect.right,
2928 invert = false;
2929 if (!invertSwap) {
2930 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
2931 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
2932 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
2933 // check if past first invert threshold on side opposite of lastDirection
2934 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
2935 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
2936 pastFirstInvertThresh = true;
2937 }
2938 if (!pastFirstInvertThresh) {
2939 // dragEl shadow (target move distance shadow)
2940 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
2941 : mouseOnAxis > targetS2 - targetMoveDistance) {
2942 return -lastDirection;
2943 }
2944 } else {
2945 invert = true;
2946 }
2947 } else {
2948 // Regular
2949 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
2950 return _getInsertDirection(target);
2951 }
2952 }
2953 }
2954 invert = invert || invertSwap;
2955 if (invert) {
2956 // Invert of regular
2957 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
2958 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
2959 }
2960 }
2961 return 0;
2962 }
2963
2964 /**
2965 * Gets the direction dragEl must be swapped relative to target in order to make it
2966 * seem that dragEl has been "inserted" into that element's position
2967 * @param {HTMLElement} target The target whose position dragEl is being inserted at
2968 * @return {Number} Direction dragEl must be swapped
2969 */
2970 function _getInsertDirection(target) {
2971 if (index(dragEl) < index(target)) {
2972 return 1;
2973 } else {
2974 return -1;
2975 }
2976 }
2977
2978 /**
2979 * Generate id
2980 * @param {HTMLElement} el
2981 * @returns {String}
2982 * @private
2983 */
2984 function _generateId(el) {
2985 var str = el.tagName + el.className + el.src + el.href + el.textContent,
2986 i = str.length,
2987 sum = 0;
2988 while (i--) {
2989 sum += str.charCodeAt(i);
2990 }
2991 return sum.toString(36);
2992 }
2993 function _saveInputCheckedState(root) {
2994 savedInputChecked.length = 0;
2995 var inputs = root.getElementsByTagName('input');
2996 var idx = inputs.length;
2997 while (idx--) {
2998 var el = inputs[idx];
2999 el.checked && savedInputChecked.push(el);
3000 }
3001 }
3002 function _nextTick(fn) {
3003 return setTimeout(fn, 0);
3004 }
3005 function _cancelNextTick(id) {
3006 return clearTimeout(id);
3007 }
3008
3009 // Fixed #973:
3010 if (documentExists) {
3011 on(document, 'touchmove', function (evt) {
3012 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
3013 evt.preventDefault();
3014 }
3015 });
3016 }
3017
3018 // Export utils
3019 Sortable.utils = {
3020 on: on,
3021 off: off,
3022 css: css,
3023 find: find,
3024 is: function is(el, selector) {
3025 return !!closest(el, selector, el, false);
3026 },
3027 extend: extend,
3028 throttle: throttle,
3029 closest: closest,
3030 toggleClass: toggleClass,
3031 clone: clone,
3032 index: index,
3033 nextTick: _nextTick,
3034 cancelNextTick: _cancelNextTick,
3035 detectDirection: _detectDirection,
3036 getChild: getChild,
3037 expando: expando
3038 };
3039
3040 /**
3041 * Get the Sortable instance of an element
3042 * @param {HTMLElement} element The element
3043 * @return {Sortable|undefined} The instance of Sortable
3044 */
3045 Sortable.get = function (element) {
3046 return element[expando];
3047 };
3048
3049 /**
3050 * Mount a plugin to Sortable
3051 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
3052 */
3053 Sortable.mount = function () {
3054 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
3055 plugins[_key] = arguments[_key];
3056 }
3057 if (plugins[0].constructor === Array) plugins = plugins[0];
3058 plugins.forEach(function (plugin) {
3059 if (!plugin.prototype || !plugin.prototype.constructor) {
3060 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
3061 }
3062 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
3063 PluginManager.mount(plugin);
3064 });
3065 };
3066
3067 /**
3068 * Create sortable instance
3069 * @param {HTMLElement} el
3070 * @param {Object} [options]
3071 */
3072 Sortable.create = function (el, options) {
3073 return new Sortable(el, options);
3074 };
3075
3076 // Export
3077 Sortable.version = version;
3078
3079 var autoScrolls = [],
3080 scrollEl,
3081 scrollRootEl,
3082 scrolling = false,
3083 lastAutoScrollX,
3084 lastAutoScrollY,
3085 touchEvt$1,
3086 pointerElemChangedInterval;
3087 function AutoScrollPlugin() {
3088 function AutoScroll() {
3089 this.defaults = {
3090 scroll: true,
3091 forceAutoScrollFallback: false,
3092 scrollSensitivity: 30,
3093 scrollSpeed: 10,
3094 bubbleScroll: true
3095 };
3096
3097 // Bind all private methods
3098 for (var fn in this) {
3099 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3100 this[fn] = this[fn].bind(this);
3101 }
3102 }
3103 }
3104 AutoScroll.prototype = {
3105 dragStarted: function dragStarted(_ref) {
3106 var originalEvent = _ref.originalEvent;
3107 if (this.sortable.nativeDraggable) {
3108 on(document, 'dragover', this._handleAutoScroll);
3109 } else {
3110 if (this.options.supportPointer) {
3111 on(document, 'pointermove', this._handleFallbackAutoScroll);
3112 } else if (originalEvent.touches) {
3113 on(document, 'touchmove', this._handleFallbackAutoScroll);
3114 } else {
3115 on(document, 'mousemove', this._handleFallbackAutoScroll);
3116 }
3117 }
3118 },
3119 dragOverCompleted: function dragOverCompleted(_ref2) {
3120 var originalEvent = _ref2.originalEvent;
3121 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
3122 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
3123 this._handleAutoScroll(originalEvent);
3124 }
3125 },
3126 drop: function drop() {
3127 if (this.sortable.nativeDraggable) {
3128 off(document, 'dragover', this._handleAutoScroll);
3129 } else {
3130 off(document, 'pointermove', this._handleFallbackAutoScroll);
3131 off(document, 'touchmove', this._handleFallbackAutoScroll);
3132 off(document, 'mousemove', this._handleFallbackAutoScroll);
3133 }
3134 clearPointerElemChangedInterval();
3135 clearAutoScrolls();
3136 cancelThrottle();
3137 },
3138 nulling: function nulling() {
3139 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
3140 autoScrolls.length = 0;
3141 },
3142 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
3143 this._handleAutoScroll(evt, true);
3144 },
3145 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
3146 var _this = this;
3147 var x = (evt.touches ? evt.touches[0] : evt).clientX,
3148 y = (evt.touches ? evt.touches[0] : evt).clientY,
3149 elem = document.elementFromPoint(x, y);
3150 touchEvt$1 = evt;
3151
3152 // IE does not seem to have native autoscroll,
3153 // Edge's autoscroll seems too conditional,
3154 // MACOS Safari does not have autoscroll,
3155 // Firefox and Chrome are good
3156 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
3157 autoScroll(evt, this.options, elem, fallback);
3158
3159 // Listener for pointer element change
3160 var ogElemScroller = getParentAutoScrollElement(elem, true);
3161 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
3162 pointerElemChangedInterval && clearPointerElemChangedInterval();
3163 // Detect for pointer elem change, emulating native DnD behaviour
3164 pointerElemChangedInterval = setInterval(function () {
3165 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
3166 if (newElem !== ogElemScroller) {
3167 ogElemScroller = newElem;
3168 clearAutoScrolls();
3169 }
3170 autoScroll(evt, _this.options, newElem, fallback);
3171 }, 10);
3172 lastAutoScrollX = x;
3173 lastAutoScrollY = y;
3174 }
3175 } else {
3176 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
3177 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
3178 clearAutoScrolls();
3179 return;
3180 }
3181 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
3182 }
3183 }
3184 };
3185 return _extends(AutoScroll, {
3186 pluginName: 'scroll',
3187 initializeByDefault: true
3188 });
3189 }
3190 function clearAutoScrolls() {
3191 autoScrolls.forEach(function (autoScroll) {
3192 clearInterval(autoScroll.pid);
3193 });
3194 autoScrolls = [];
3195 }
3196 function clearPointerElemChangedInterval() {
3197 clearInterval(pointerElemChangedInterval);
3198 }
3199 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
3200 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
3201 if (!options.scroll) return;
3202 var x = (evt.touches ? evt.touches[0] : evt).clientX,
3203 y = (evt.touches ? evt.touches[0] : evt).clientY,
3204 sens = options.scrollSensitivity,
3205 speed = options.scrollSpeed,
3206 winScroller = getWindowScrollingElement();
3207 var scrollThisInstance = false,
3208 scrollCustomFn;
3209
3210 // New scroll root, set scrollEl
3211 if (scrollRootEl !== rootEl) {
3212 scrollRootEl = rootEl;
3213 clearAutoScrolls();
3214 scrollEl = options.scroll;
3215 scrollCustomFn = options.scrollFn;
3216 if (scrollEl === true) {
3217 scrollEl = getParentAutoScrollElement(rootEl, true);
3218 }
3219 }
3220 var layersOut = 0;
3221 var currentParent = scrollEl;
3222 do {
3223 var el = currentParent,
3224 rect = getRect(el),
3225 top = rect.top,
3226 bottom = rect.bottom,
3227 left = rect.left,
3228 right = rect.right,
3229 width = rect.width,
3230 height = rect.height,
3231 canScrollX = void 0,
3232 canScrollY = void 0,
3233 scrollWidth = el.scrollWidth,
3234 scrollHeight = el.scrollHeight,
3235 elCSS = css(el),
3236 scrollPosX = el.scrollLeft,
3237 scrollPosY = el.scrollTop;
3238 if (el === winScroller) {
3239 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
3240 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
3241 } else {
3242 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
3243 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
3244 }
3245 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
3246 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
3247 if (!autoScrolls[layersOut]) {
3248 for (var i = 0; i <= layersOut; i++) {
3249 if (!autoScrolls[i]) {
3250 autoScrolls[i] = {};
3251 }
3252 }
3253 }
3254 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
3255 autoScrolls[layersOut].el = el;
3256 autoScrolls[layersOut].vx = vx;
3257 autoScrolls[layersOut].vy = vy;
3258 clearInterval(autoScrolls[layersOut].pid);
3259 if (vx != 0 || vy != 0) {
3260 scrollThisInstance = true;
3261 /* jshint loopfunc:true */
3262 autoScrolls[layersOut].pid = setInterval(function () {
3263 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
3264 if (isFallback && this.layer === 0) {
3265 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
3266 }
3267 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
3268 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
3269 if (typeof scrollCustomFn === 'function') {
3270 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
3271 return;
3272 }
3273 }
3274 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
3275 }.bind({
3276 layer: layersOut
3277 }), 24);
3278 }
3279 }
3280 layersOut++;
3281 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
3282 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
3283 }, 30);
3284
3285 var drop = function drop(_ref) {
3286 var originalEvent = _ref.originalEvent,
3287 putSortable = _ref.putSortable,
3288 dragEl = _ref.dragEl,
3289 activeSortable = _ref.activeSortable,
3290 dispatchSortableEvent = _ref.dispatchSortableEvent,
3291 hideGhostForTarget = _ref.hideGhostForTarget,
3292 unhideGhostForTarget = _ref.unhideGhostForTarget;
3293 if (!originalEvent) return;
3294 var toSortable = putSortable || activeSortable;
3295 hideGhostForTarget();
3296 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
3297 var target = document.elementFromPoint(touch.clientX, touch.clientY);
3298 unhideGhostForTarget();
3299 if (toSortable && !toSortable.el.contains(target)) {
3300 dispatchSortableEvent('spill');
3301 this.onSpill({
3302 dragEl: dragEl,
3303 putSortable: putSortable
3304 });
3305 }
3306 };
3307 function Revert() {}
3308 Revert.prototype = {
3309 startIndex: null,
3310 dragStart: function dragStart(_ref2) {
3311 var oldDraggableIndex = _ref2.oldDraggableIndex;
3312 this.startIndex = oldDraggableIndex;
3313 },
3314 onSpill: function onSpill(_ref3) {
3315 var dragEl = _ref3.dragEl,
3316 putSortable = _ref3.putSortable;
3317 this.sortable.captureAnimationState();
3318 if (putSortable) {
3319 putSortable.captureAnimationState();
3320 }
3321 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
3322 if (nextSibling) {
3323 this.sortable.el.insertBefore(dragEl, nextSibling);
3324 } else {
3325 this.sortable.el.appendChild(dragEl);
3326 }
3327 this.sortable.animateAll();
3328 if (putSortable) {
3329 putSortable.animateAll();
3330 }
3331 },
3332 drop: drop
3333 };
3334 _extends(Revert, {
3335 pluginName: 'revertOnSpill'
3336 });
3337 function Remove() {}
3338 Remove.prototype = {
3339 onSpill: function onSpill(_ref4) {
3340 var dragEl = _ref4.dragEl,
3341 putSortable = _ref4.putSortable;
3342 var parentSortable = putSortable || this.sortable;
3343 parentSortable.captureAnimationState();
3344 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
3345 parentSortable.animateAll();
3346 },
3347 drop: drop
3348 };
3349 _extends(Remove, {
3350 pluginName: 'removeOnSpill'
3351 });
3352
3353 var lastSwapEl;
3354 function SwapPlugin() {
3355 function Swap() {
3356 this.defaults = {
3357 swapClass: 'sortable-swap-highlight'
3358 };
3359 }
3360 Swap.prototype = {
3361 dragStart: function dragStart(_ref) {
3362 var dragEl = _ref.dragEl;
3363 lastSwapEl = dragEl;
3364 },
3365 dragOverValid: function dragOverValid(_ref2) {
3366 var completed = _ref2.completed,
3367 target = _ref2.target,
3368 onMove = _ref2.onMove,
3369 activeSortable = _ref2.activeSortable,
3370 changed = _ref2.changed,
3371 cancel = _ref2.cancel;
3372 if (!activeSortable.options.swap) return;
3373 var el = this.sortable.el,
3374 options = this.options;
3375 if (target && target !== el) {
3376 var prevSwapEl = lastSwapEl;
3377 if (onMove(target) !== false) {
3378 toggleClass(target, options.swapClass, true);
3379 lastSwapEl = target;
3380 } else {
3381 lastSwapEl = null;
3382 }
3383 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
3384 toggleClass(prevSwapEl, options.swapClass, false);
3385 }
3386 }
3387 changed();
3388 completed(true);
3389 cancel();
3390 },
3391 drop: function drop(_ref3) {
3392 var activeSortable = _ref3.activeSortable,
3393 putSortable = _ref3.putSortable,
3394 dragEl = _ref3.dragEl;
3395 var toSortable = putSortable || this.sortable;
3396 var options = this.options;
3397 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
3398 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
3399 if (dragEl !== lastSwapEl) {
3400 toSortable.captureAnimationState();
3401 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
3402 swapNodes(dragEl, lastSwapEl);
3403 toSortable.animateAll();
3404 if (toSortable !== activeSortable) activeSortable.animateAll();
3405 }
3406 }
3407 },
3408 nulling: function nulling() {
3409 lastSwapEl = null;
3410 }
3411 };
3412 return _extends(Swap, {
3413 pluginName: 'swap',
3414 eventProperties: function eventProperties() {
3415 return {
3416 swapItem: lastSwapEl
3417 };
3418 }
3419 });
3420 }
3421 function swapNodes(n1, n2) {
3422 var p1 = n1.parentNode,
3423 p2 = n2.parentNode,
3424 i1,
3425 i2;
3426 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
3427 i1 = index(n1);
3428 i2 = index(n2);
3429 if (p1.isEqualNode(p2) && i1 < i2) {
3430 i2++;
3431 }
3432 p1.insertBefore(n2, p1.children[i1]);
3433 p2.insertBefore(n1, p2.children[i2]);
3434 }
3435
3436 var multiDragElements = [],
3437 multiDragClones = [],
3438 lastMultiDragSelect,
3439 // for selection with modifier key down (SHIFT)
3440 multiDragSortable,
3441 initialFolding = false,
3442 // Initial multi-drag fold when drag started
3443 folding = false,
3444 // Folding any other time
3445 dragStarted = false,
3446 dragEl$1,
3447 clonesFromRect,
3448 clonesHidden;
3449 function MultiDragPlugin() {
3450 function MultiDrag(sortable) {
3451 // Bind all private methods
3452 for (var fn in this) {
3453 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3454 this[fn] = this[fn].bind(this);
3455 }
3456 }
3457 if (!sortable.options.avoidImplicitDeselect) {
3458 if (sortable.options.supportPointer) {
3459 on(document, 'pointerup', this._deselectMultiDrag);
3460 } else {
3461 on(document, 'mouseup', this._deselectMultiDrag);
3462 on(document, 'touchend', this._deselectMultiDrag);
3463 }
3464 }
3465 on(document, 'keydown', this._checkKeyDown);
3466 on(document, 'keyup', this._checkKeyUp);
3467 this.defaults = {
3468 selectedClass: 'sortable-selected',
3469 multiDragKey: null,
3470 avoidImplicitDeselect: false,
3471 setData: function setData(dataTransfer, dragEl) {
3472 var data = '';
3473 if (multiDragElements.length && multiDragSortable === sortable) {
3474 multiDragElements.forEach(function (multiDragElement, i) {
3475 data += (!i ? '' : ', ') + multiDragElement.textContent;
3476 });
3477 } else {
3478 data = dragEl.textContent;
3479 }
3480 dataTransfer.setData('Text', data);
3481 }
3482 };
3483 }
3484 MultiDrag.prototype = {
3485 multiDragKeyDown: false,
3486 isMultiDrag: false,
3487 delayStartGlobal: function delayStartGlobal(_ref) {
3488 var dragged = _ref.dragEl;
3489 dragEl$1 = dragged;
3490 },
3491 delayEnded: function delayEnded() {
3492 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
3493 },
3494 setupClone: function setupClone(_ref2) {
3495 var sortable = _ref2.sortable,
3496 cancel = _ref2.cancel;
3497 if (!this.isMultiDrag) return;
3498 for (var i = 0; i < multiDragElements.length; i++) {
3499 multiDragClones.push(clone(multiDragElements[i]));
3500 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
3501 multiDragClones[i].draggable = false;
3502 multiDragClones[i].style['will-change'] = '';
3503 toggleClass(multiDragClones[i], this.options.selectedClass, false);
3504 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
3505 }
3506 sortable._hideClone();
3507 cancel();
3508 },
3509 clone: function clone(_ref3) {
3510 var sortable = _ref3.sortable,
3511 rootEl = _ref3.rootEl,
3512 dispatchSortableEvent = _ref3.dispatchSortableEvent,
3513 cancel = _ref3.cancel;
3514 if (!this.isMultiDrag) return;
3515 if (!this.options.removeCloneOnHide) {
3516 if (multiDragElements.length && multiDragSortable === sortable) {
3517 insertMultiDragClones(true, rootEl);
3518 dispatchSortableEvent('clone');
3519 cancel();
3520 }
3521 }
3522 },
3523 showClone: function showClone(_ref4) {
3524 var cloneNowShown = _ref4.cloneNowShown,
3525 rootEl = _ref4.rootEl,
3526 cancel = _ref4.cancel;
3527 if (!this.isMultiDrag) return;
3528 insertMultiDragClones(false, rootEl);
3529 multiDragClones.forEach(function (clone) {
3530 css(clone, 'display', '');
3531 });
3532 cloneNowShown();
3533 clonesHidden = false;
3534 cancel();
3535 },
3536 hideClone: function hideClone(_ref5) {
3537 var _this = this;
3538 var sortable = _ref5.sortable,
3539 cloneNowHidden = _ref5.cloneNowHidden,
3540 cancel = _ref5.cancel;
3541 if (!this.isMultiDrag) return;
3542 multiDragClones.forEach(function (clone) {
3543 css(clone, 'display', 'none');
3544 if (_this.options.removeCloneOnHide && clone.parentNode) {
3545 clone.parentNode.removeChild(clone);
3546 }
3547 });
3548 cloneNowHidden();
3549 clonesHidden = true;
3550 cancel();
3551 },
3552 dragStartGlobal: function dragStartGlobal(_ref6) {
3553 var sortable = _ref6.sortable;
3554 if (!this.isMultiDrag && multiDragSortable) {
3555 multiDragSortable.multiDrag._deselectMultiDrag();
3556 }
3557 multiDragElements.forEach(function (multiDragElement) {
3558 multiDragElement.sortableIndex = index(multiDragElement);
3559 });
3560
3561 // Sort multi-drag elements
3562 multiDragElements = multiDragElements.sort(function (a, b) {
3563 return a.sortableIndex - b.sortableIndex;
3564 });
3565 dragStarted = true;
3566 },
3567 dragStarted: function dragStarted(_ref7) {
3568 var _this2 = this;
3569 var sortable = _ref7.sortable;
3570 if (!this.isMultiDrag) return;
3571 if (this.options.sort) {
3572 // Capture rects,
3573 // hide multi drag elements (by positioning them absolute),
3574 // set multi drag elements rects to dragRect,
3575 // show multi drag elements,
3576 // animate to rects,
3577 // unset rects & remove from DOM
3578
3579 sortable.captureAnimationState();
3580 if (this.options.animation) {
3581 multiDragElements.forEach(function (multiDragElement) {
3582 if (multiDragElement === dragEl$1) return;
3583 css(multiDragElement, 'position', 'absolute');
3584 });
3585 var dragRect = getRect(dragEl$1, false, true, true);
3586 multiDragElements.forEach(function (multiDragElement) {
3587 if (multiDragElement === dragEl$1) return;
3588 setRect(multiDragElement, dragRect);
3589 });
3590 folding = true;
3591 initialFolding = true;
3592 }
3593 }
3594 sortable.animateAll(function () {
3595 folding = false;
3596 initialFolding = false;
3597 if (_this2.options.animation) {
3598 multiDragElements.forEach(function (multiDragElement) {
3599 unsetRect(multiDragElement);
3600 });
3601 }
3602
3603 // Remove all auxiliary multidrag items from el, if sorting enabled
3604 if (_this2.options.sort) {
3605 removeMultiDragElements();
3606 }
3607 });
3608 },
3609 dragOver: function dragOver(_ref8) {
3610 var target = _ref8.target,
3611 completed = _ref8.completed,
3612 cancel = _ref8.cancel;
3613 if (folding && ~multiDragElements.indexOf(target)) {
3614 completed(false);
3615 cancel();
3616 }
3617 },
3618 revert: function revert(_ref9) {
3619 var fromSortable = _ref9.fromSortable,
3620 rootEl = _ref9.rootEl,
3621 sortable = _ref9.sortable,
3622 dragRect = _ref9.dragRect;
3623 if (multiDragElements.length > 1) {
3624 // Setup unfold animation
3625 multiDragElements.forEach(function (multiDragElement) {
3626 sortable.addAnimationState({
3627 target: multiDragElement,
3628 rect: folding ? getRect(multiDragElement) : dragRect
3629 });
3630 unsetRect(multiDragElement);
3631 multiDragElement.fromRect = dragRect;
3632 fromSortable.removeAnimationState(multiDragElement);
3633 });
3634 folding = false;
3635 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
3636 }
3637 },
3638 dragOverCompleted: function dragOverCompleted(_ref10) {
3639 var sortable = _ref10.sortable,
3640 isOwner = _ref10.isOwner,
3641 insertion = _ref10.insertion,
3642 activeSortable = _ref10.activeSortable,
3643 parentEl = _ref10.parentEl,
3644 putSortable = _ref10.putSortable;
3645 var options = this.options;
3646 if (insertion) {
3647 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3648 if (isOwner) {
3649 activeSortable._hideClone();
3650 }
3651 initialFolding = false;
3652 // If leaving sort:false root, or already folding - Fold to new location
3653 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
3654 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
3655 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
3656 multiDragElements.forEach(function (multiDragElement) {
3657 if (multiDragElement === dragEl$1) return;
3658 setRect(multiDragElement, dragRectAbsolute);
3659
3660 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
3661 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
3662 parentEl.appendChild(multiDragElement);
3663 });
3664 folding = true;
3665 }
3666
3667 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
3668 if (!isOwner) {
3669 // Only remove if not folding (folding will remove them anyways)
3670 if (!folding) {
3671 removeMultiDragElements();
3672 }
3673 if (multiDragElements.length > 1) {
3674 var clonesHiddenBefore = clonesHidden;
3675 activeSortable._showClone(sortable);
3676
3677 // Unfold animation for clones if showing from hidden
3678 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
3679 multiDragClones.forEach(function (clone) {
3680 activeSortable.addAnimationState({
3681 target: clone,
3682 rect: clonesFromRect
3683 });
3684 clone.fromRect = clonesFromRect;
3685 clone.thisAnimationDuration = null;
3686 });
3687 }
3688 } else {
3689 activeSortable._showClone(sortable);
3690 }
3691 }
3692 }
3693 },
3694 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
3695 var dragRect = _ref11.dragRect,
3696 isOwner = _ref11.isOwner,
3697 activeSortable = _ref11.activeSortable;
3698 multiDragElements.forEach(function (multiDragElement) {
3699 multiDragElement.thisAnimationDuration = null;
3700 });
3701 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
3702 clonesFromRect = _extends({}, dragRect);
3703 var dragMatrix = matrix(dragEl$1, true);
3704 clonesFromRect.top -= dragMatrix.f;
3705 clonesFromRect.left -= dragMatrix.e;
3706 }
3707 },
3708 dragOverAnimationComplete: function dragOverAnimationComplete() {
3709 if (folding) {
3710 folding = false;
3711 removeMultiDragElements();
3712 }
3713 },
3714 drop: function drop(_ref12) {
3715 var evt = _ref12.originalEvent,
3716 rootEl = _ref12.rootEl,
3717 parentEl = _ref12.parentEl,
3718 sortable = _ref12.sortable,
3719 dispatchSortableEvent = _ref12.dispatchSortableEvent,
3720 oldIndex = _ref12.oldIndex,
3721 putSortable = _ref12.putSortable;
3722 var toSortable = putSortable || this.sortable;
3723 if (!evt) return;
3724 var options = this.options,
3725 children = parentEl.children;
3726
3727 // Multi-drag selection
3728 if (!dragStarted) {
3729 if (options.multiDragKey && !this.multiDragKeyDown) {
3730 this._deselectMultiDrag();
3731 }
3732 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
3733 if (!~multiDragElements.indexOf(dragEl$1)) {
3734 multiDragElements.push(dragEl$1);
3735 dispatchEvent({
3736 sortable: sortable,
3737 rootEl: rootEl,
3738 name: 'select',
3739 targetEl: dragEl$1,
3740 originalEvent: evt
3741 });
3742
3743 // Modifier activated, select from last to dragEl
3744 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
3745 var lastIndex = index(lastMultiDragSelect),
3746 currentIndex = index(dragEl$1);
3747 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
3748 (function () {
3749 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
3750 // (but previous selection existed)
3751 var n, i;
3752 if (currentIndex > lastIndex) {
3753 i = lastIndex;
3754 n = currentIndex;
3755 } else {
3756 i = currentIndex;
3757 n = lastIndex + 1;
3758 }
3759 var filter = options.filter;
3760 for (; i < n; i++) {
3761 if (~multiDragElements.indexOf(children[i])) continue;
3762 // Check if element is draggable
3763 if (!closest(children[i], options.draggable, parentEl, false)) continue;
3764 // Check if element is filtered
3765 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
3766 return closest(children[i], criteria.trim(), parentEl, false);
3767 }));
3768 if (filtered) continue;
3769 toggleClass(children[i], options.selectedClass, true);
3770 multiDragElements.push(children[i]);
3771 dispatchEvent({
3772 sortable: sortable,
3773 rootEl: rootEl,
3774 name: 'select',
3775 targetEl: children[i],
3776 originalEvent: evt
3777 });
3778 }
3779 })();
3780 }
3781 } else {
3782 lastMultiDragSelect = dragEl$1;
3783 }
3784 multiDragSortable = toSortable;
3785 } else {
3786 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
3787 lastMultiDragSelect = null;
3788 dispatchEvent({
3789 sortable: sortable,
3790 rootEl: rootEl,
3791 name: 'deselect',
3792 targetEl: dragEl$1,
3793 originalEvent: evt
3794 });
3795 }
3796 }
3797
3798 // Multi-drag drop
3799 if (dragStarted && this.isMultiDrag) {
3800 folding = false;
3801 // Do not "unfold" after around dragEl if reverted
3802 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
3803 var dragRect = getRect(dragEl$1),
3804 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
3805 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
3806 toSortable.captureAnimationState();
3807 if (!initialFolding) {
3808 if (options.animation) {
3809 dragEl$1.fromRect = dragRect;
3810 multiDragElements.forEach(function (multiDragElement) {
3811 multiDragElement.thisAnimationDuration = null;
3812 if (multiDragElement !== dragEl$1) {
3813 var rect = folding ? getRect(multiDragElement) : dragRect;
3814 multiDragElement.fromRect = rect;
3815
3816 // Prepare unfold animation
3817 toSortable.addAnimationState({
3818 target: multiDragElement,
3819 rect: rect
3820 });
3821 }
3822 });
3823 }
3824
3825 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
3826 // properly they must all be removed
3827 removeMultiDragElements();
3828 multiDragElements.forEach(function (multiDragElement) {
3829 if (children[multiDragIndex]) {
3830 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
3831 } else {
3832 parentEl.appendChild(multiDragElement);
3833 }
3834 multiDragIndex++;
3835 });
3836
3837 // If initial folding is done, the elements may have changed position because they are now
3838 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
3839 // must be fired here as Sortable will not.
3840 if (oldIndex === index(dragEl$1)) {
3841 var update = false;
3842 multiDragElements.forEach(function (multiDragElement) {
3843 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
3844 update = true;
3845 return;
3846 }
3847 });
3848 if (update) {
3849 dispatchSortableEvent('update');
3850 dispatchSortableEvent('sort');
3851 }
3852 }
3853 }
3854
3855 // Must be done after capturing individual rects (scroll bar)
3856 multiDragElements.forEach(function (multiDragElement) {
3857 unsetRect(multiDragElement);
3858 });
3859 toSortable.animateAll();
3860 }
3861 multiDragSortable = toSortable;
3862 }
3863
3864 // Remove clones if necessary
3865 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
3866 multiDragClones.forEach(function (clone) {
3867 clone.parentNode && clone.parentNode.removeChild(clone);
3868 });
3869 }
3870 },
3871 nullingGlobal: function nullingGlobal() {
3872 this.isMultiDrag = dragStarted = false;
3873 multiDragClones.length = 0;
3874 },
3875 destroyGlobal: function destroyGlobal() {
3876 this._deselectMultiDrag();
3877 off(document, 'pointerup', this._deselectMultiDrag);
3878 off(document, 'mouseup', this._deselectMultiDrag);
3879 off(document, 'touchend', this._deselectMultiDrag);
3880 off(document, 'keydown', this._checkKeyDown);
3881 off(document, 'keyup', this._checkKeyUp);
3882 },
3883 _deselectMultiDrag: function _deselectMultiDrag(evt) {
3884 if (typeof dragStarted !== "undefined" && dragStarted) return;
3885
3886 // Only deselect if selection is in this sortable
3887 if (multiDragSortable !== this.sortable) return;
3888
3889 // Only deselect if target is not item in this sortable
3890 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
3891
3892 // Only deselect if left click
3893 if (evt && evt.button !== 0) return;
3894 while (multiDragElements.length) {
3895 var el = multiDragElements[0];
3896 toggleClass(el, this.options.selectedClass, false);
3897 multiDragElements.shift();
3898 dispatchEvent({
3899 sortable: this.sortable,
3900 rootEl: this.sortable.el,
3901 name: 'deselect',
3902 targetEl: el,
3903 originalEvent: evt
3904 });
3905 }
3906 },
3907 _checkKeyDown: function _checkKeyDown(evt) {
3908 if (evt.key === this.options.multiDragKey) {
3909 this.multiDragKeyDown = true;
3910 }
3911 },
3912 _checkKeyUp: function _checkKeyUp(evt) {
3913 if (evt.key === this.options.multiDragKey) {
3914 this.multiDragKeyDown = false;
3915 }
3916 }
3917 };
3918 return _extends(MultiDrag, {
3919 // Static methods & properties
3920 pluginName: 'multiDrag',
3921 utils: {
3922 /**
3923 * Selects the provided multi-drag item
3924 * @param {HTMLElement} el The element to be selected
3925 */
3926 select: function select(el) {
3927 var sortable = el.parentNode[expando];
3928 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
3929 if (multiDragSortable && multiDragSortable !== sortable) {
3930 multiDragSortable.multiDrag._deselectMultiDrag();
3931 multiDragSortable = sortable;
3932 }
3933 toggleClass(el, sortable.options.selectedClass, true);
3934 multiDragElements.push(el);
3935 },
3936 /**
3937 * Deselects the provided multi-drag item
3938 * @param {HTMLElement} el The element to be deselected
3939 */
3940 deselect: function deselect(el) {
3941 var sortable = el.parentNode[expando],
3942 index = multiDragElements.indexOf(el);
3943 if (!sortable || !sortable.options.multiDrag || !~index) return;
3944 toggleClass(el, sortable.options.selectedClass, false);
3945 multiDragElements.splice(index, 1);
3946 }
3947 },
3948 eventProperties: function eventProperties() {
3949 var _this3 = this;
3950 var oldIndicies = [],
3951 newIndicies = [];
3952 multiDragElements.forEach(function (multiDragElement) {
3953 oldIndicies.push({
3954 multiDragElement: multiDragElement,
3955 index: multiDragElement.sortableIndex
3956 });
3957
3958 // multiDragElements will already be sorted if folding
3959 var newIndex;
3960 if (folding && multiDragElement !== dragEl$1) {
3961 newIndex = -1;
3962 } else if (folding) {
3963 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
3964 } else {
3965 newIndex = index(multiDragElement);
3966 }
3967 newIndicies.push({
3968 multiDragElement: multiDragElement,
3969 index: newIndex
3970 });
3971 });
3972 return {
3973 items: _toConsumableArray(multiDragElements),
3974 clones: [].concat(multiDragClones),
3975 oldIndicies: oldIndicies,
3976 newIndicies: newIndicies
3977 };
3978 },
3979 optionListeners: {
3980 multiDragKey: function multiDragKey(key) {
3981 key = key.toLowerCase();
3982 if (key === 'ctrl') {
3983 key = 'Control';
3984 } else if (key.length > 1) {
3985 key = key.charAt(0).toUpperCase() + key.substr(1);
3986 }
3987 return key;
3988 }
3989 }
3990 });
3991 }
3992 function insertMultiDragElements(clonesInserted, rootEl) {
3993 multiDragElements.forEach(function (multiDragElement, i) {
3994 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
3995 if (target) {
3996 rootEl.insertBefore(multiDragElement, target);
3997 } else {
3998 rootEl.appendChild(multiDragElement);
3999 }
4000 });
4001 }
4002
4003 /**
4004 * Insert multi-drag clones
4005 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
4006 * @param {HTMLElement} rootEl
4007 */
4008 function insertMultiDragClones(elementsInserted, rootEl) {
4009 multiDragClones.forEach(function (clone, i) {
4010 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
4011 if (target) {
4012 rootEl.insertBefore(clone, target);
4013 } else {
4014 rootEl.appendChild(clone);
4015 }
4016 });
4017 }
4018 function removeMultiDragElements() {
4019 multiDragElements.forEach(function (multiDragElement) {
4020 if (multiDragElement === dragEl$1) return;
4021 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
4022 });
4023 }
4024
4025 Sortable.mount(new AutoScrollPlugin());
4026 Sortable.mount(Remove, Revert);
4027
4028 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
4029
4030
4031
4032 /***/ },
4033
4034 /***/ "./node_modules/toastify-js/src/toastify.css"
4035 /*!***************************************************!*\
4036 !*** ./node_modules/toastify-js/src/toastify.css ***!
4037 \***************************************************/
4038 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
4039
4040 "use strict";
4041 __webpack_require__.r(__webpack_exports__);
4042 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4043 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
4044 /* harmony export */ });
4045 /* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
4046 /* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);
4047 /* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../../style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js");
4048 /* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);
4049 /* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../../style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js");
4050 /* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);
4051 /* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../../style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js");
4052 /* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);
4053 /* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../../style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js");
4054 /* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);
4055 /* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../../style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js");
4056 /* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);
4057 /* harmony import */ var _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../../css-loader/dist/cjs.js!./toastify.css */ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css");
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069 var options = {};
4070
4071 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
4072 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
4073
4074 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
4075
4076 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
4077 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
4078
4079 var update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
4080
4081
4082
4083
4084 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
4085
4086
4087 /***/ },
4088
4089 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
4090 /*!****************************************************************************!*\
4091 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
4092 \****************************************************************************/
4093 (module) {
4094
4095 "use strict";
4096
4097
4098 var stylesInDOM = [];
4099 function getIndexByIdentifier(identifier) {
4100 var result = -1;
4101 for (var i = 0; i < stylesInDOM.length; i++) {
4102 if (stylesInDOM[i].identifier === identifier) {
4103 result = i;
4104 break;
4105 }
4106 }
4107 return result;
4108 }
4109 function modulesToDom(list, options) {
4110 var idCountMap = {};
4111 var identifiers = [];
4112 for (var i = 0; i < list.length; i++) {
4113 var item = list[i];
4114 var id = options.base ? item[0] + options.base : item[0];
4115 var count = idCountMap[id] || 0;
4116 var identifier = "".concat(id, " ").concat(count);
4117 idCountMap[id] = count + 1;
4118 var indexByIdentifier = getIndexByIdentifier(identifier);
4119 var obj = {
4120 css: item[1],
4121 media: item[2],
4122 sourceMap: item[3],
4123 supports: item[4],
4124 layer: item[5]
4125 };
4126 if (indexByIdentifier !== -1) {
4127 stylesInDOM[indexByIdentifier].references++;
4128 stylesInDOM[indexByIdentifier].updater(obj);
4129 } else {
4130 var updater = addElementStyle(obj, options);
4131 options.byIndex = i;
4132 stylesInDOM.splice(i, 0, {
4133 identifier: identifier,
4134 updater: updater,
4135 references: 1
4136 });
4137 }
4138 identifiers.push(identifier);
4139 }
4140 return identifiers;
4141 }
4142 function addElementStyle(obj, options) {
4143 var api = options.domAPI(options);
4144 api.update(obj);
4145 var updater = function updater(newObj) {
4146 if (newObj) {
4147 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
4148 return;
4149 }
4150 api.update(obj = newObj);
4151 } else {
4152 api.remove();
4153 }
4154 };
4155 return updater;
4156 }
4157 module.exports = function (list, options) {
4158 options = options || {};
4159 list = list || [];
4160 var lastIdentifiers = modulesToDom(list, options);
4161 return function update(newList) {
4162 newList = newList || [];
4163 for (var i = 0; i < lastIdentifiers.length; i++) {
4164 var identifier = lastIdentifiers[i];
4165 var index = getIndexByIdentifier(identifier);
4166 stylesInDOM[index].references--;
4167 }
4168 var newLastIdentifiers = modulesToDom(newList, options);
4169 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
4170 var _identifier = lastIdentifiers[_i];
4171 var _index = getIndexByIdentifier(_identifier);
4172 if (stylesInDOM[_index].references === 0) {
4173 stylesInDOM[_index].updater();
4174 stylesInDOM.splice(_index, 1);
4175 }
4176 }
4177 lastIdentifiers = newLastIdentifiers;
4178 };
4179 };
4180
4181 /***/ },
4182
4183 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
4184 /*!********************************************************************!*\
4185 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
4186 \********************************************************************/
4187 (module) {
4188
4189 "use strict";
4190
4191
4192 var memo = {};
4193
4194 /* istanbul ignore next */
4195 function getTarget(target) {
4196 if (typeof memo[target] === "undefined") {
4197 var styleTarget = document.querySelector(target);
4198
4199 // Special case to return head of iframe instead of iframe itself
4200 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
4201 try {
4202 // This will throw an exception if access to iframe is blocked
4203 // due to cross-origin restrictions
4204 styleTarget = styleTarget.contentDocument.head;
4205 } catch (e) {
4206 // istanbul ignore next
4207 styleTarget = null;
4208 }
4209 }
4210 memo[target] = styleTarget;
4211 }
4212 return memo[target];
4213 }
4214
4215 /* istanbul ignore next */
4216 function insertBySelector(insert, style) {
4217 var target = getTarget(insert);
4218 if (!target) {
4219 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
4220 }
4221 target.appendChild(style);
4222 }
4223 module.exports = insertBySelector;
4224
4225 /***/ },
4226
4227 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
4228 /*!**********************************************************************!*\
4229 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
4230 \**********************************************************************/
4231 (module) {
4232
4233 "use strict";
4234
4235
4236 /* istanbul ignore next */
4237 function insertStyleElement(options) {
4238 var element = document.createElement("style");
4239 options.setAttributes(element, options.attributes);
4240 options.insert(element, options.options);
4241 return element;
4242 }
4243 module.exports = insertStyleElement;
4244
4245 /***/ },
4246
4247 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
4248 /*!**********************************************************************************!*\
4249 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
4250 \**********************************************************************************/
4251 (module, __unused_webpack_exports, __webpack_require__) {
4252
4253 "use strict";
4254
4255
4256 /* istanbul ignore next */
4257 function setAttributesWithoutAttributes(styleElement) {
4258 var nonce = true ? __webpack_require__.nc : 0;
4259 if (nonce) {
4260 styleElement.setAttribute("nonce", nonce);
4261 }
4262 }
4263 module.exports = setAttributesWithoutAttributes;
4264
4265 /***/ },
4266
4267 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
4268 /*!***************************************************************!*\
4269 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
4270 \***************************************************************/
4271 (module) {
4272
4273 "use strict";
4274
4275
4276 /* istanbul ignore next */
4277 function apply(styleElement, options, obj) {
4278 var css = "";
4279 if (obj.supports) {
4280 css += "@supports (".concat(obj.supports, ") {");
4281 }
4282 if (obj.media) {
4283 css += "@media ".concat(obj.media, " {");
4284 }
4285 var needLayer = typeof obj.layer !== "undefined";
4286 if (needLayer) {
4287 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
4288 }
4289 css += obj.css;
4290 if (needLayer) {
4291 css += "}";
4292 }
4293 if (obj.media) {
4294 css += "}";
4295 }
4296 if (obj.supports) {
4297 css += "}";
4298 }
4299 var sourceMap = obj.sourceMap;
4300 if (sourceMap && typeof btoa !== "undefined") {
4301 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
4302 }
4303
4304 // For old IE
4305 /* istanbul ignore if */
4306 options.styleTagTransform(css, styleElement, options.options);
4307 }
4308 function removeStyleElement(styleElement) {
4309 // istanbul ignore if
4310 if (styleElement.parentNode === null) {
4311 return false;
4312 }
4313 styleElement.parentNode.removeChild(styleElement);
4314 }
4315
4316 /* istanbul ignore next */
4317 function domAPI(options) {
4318 if (typeof document === "undefined") {
4319 return {
4320 update: function update() {},
4321 remove: function remove() {}
4322 };
4323 }
4324 var styleElement = options.insertStyleElement(options);
4325 return {
4326 update: function update(obj) {
4327 apply(styleElement, options, obj);
4328 },
4329 remove: function remove() {
4330 removeStyleElement(styleElement);
4331 }
4332 };
4333 }
4334 module.exports = domAPI;
4335
4336 /***/ },
4337
4338 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
4339 /*!*********************************************************************!*\
4340 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
4341 \*********************************************************************/
4342 (module) {
4343
4344 "use strict";
4345
4346
4347 /* istanbul ignore next */
4348 function styleTagTransform(css, styleElement) {
4349 if (styleElement.styleSheet) {
4350 styleElement.styleSheet.cssText = css;
4351 } else {
4352 while (styleElement.firstChild) {
4353 styleElement.removeChild(styleElement.firstChild);
4354 }
4355 styleElement.appendChild(document.createTextNode(css));
4356 }
4357 }
4358 module.exports = styleTagTransform;
4359
4360 /***/ },
4361
4362 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
4363 /*!**********************************************************!*\
4364 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
4365 \**********************************************************/
4366 (module) {
4367
4368 /*!
4369 * sweetalert2 v11.26.25
4370 * Released under the MIT License.
4371 */
4372 (function (global, factory) {
4373 true ? module.exports = factory() :
4374 0;
4375 })(this, (function () { 'use strict';
4376
4377 function _assertClassBrand(e, t, n) {
4378 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
4379 throw new TypeError("Private element is not present on this object");
4380 }
4381 function _checkPrivateRedeclaration(e, t) {
4382 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
4383 }
4384 function _classPrivateFieldGet2(s, a) {
4385 return s.get(_assertClassBrand(s, a));
4386 }
4387 function _classPrivateFieldInitSpec(e, t, a) {
4388 _checkPrivateRedeclaration(e, t), t.set(e, a);
4389 }
4390 function _classPrivateFieldSet2(s, a, r) {
4391 return s.set(_assertClassBrand(s, a), r), r;
4392 }
4393
4394 const RESTORE_FOCUS_TIMEOUT = 100;
4395
4396 /** @type {GlobalState} */
4397 const globalState = {};
4398 const focusPreviousActiveElement = () => {
4399 if (globalState.previousActiveElement instanceof HTMLElement) {
4400 globalState.previousActiveElement.focus();
4401 globalState.previousActiveElement = null;
4402 } else if (document.body) {
4403 document.body.focus();
4404 }
4405 };
4406
4407 /**
4408 * Restore previous active (focused) element
4409 *
4410 * @param {boolean} returnFocus
4411 * @returns {Promise<void>}
4412 */
4413 const restoreActiveElement = returnFocus => {
4414 return new Promise(resolve => {
4415 if (!returnFocus) {
4416 return resolve();
4417 }
4418 const x = window.scrollX;
4419 const y = window.scrollY;
4420 globalState.restoreFocusTimeout = setTimeout(() => {
4421 focusPreviousActiveElement();
4422 resolve();
4423 }, RESTORE_FOCUS_TIMEOUT); // issues/900
4424
4425 window.scrollTo(x, y);
4426 });
4427 };
4428
4429 const swalPrefix = 'swal2-';
4430
4431 /**
4432 * @typedef {Record<SwalClass, string>} SwalClasses
4433 */
4434
4435 /**
4436 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
4437 * @typedef {Record<SwalIcon, string>} SwalIcons
4438 */
4439
4440 /** @type {SwalClass[]} */
4441 const classNames = ['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error', 'draggable', 'dragging'];
4442 const swalClasses = classNames.reduce((acc, className) => {
4443 acc[className] = swalPrefix + className;
4444 return acc;
4445 }, /** @type {SwalClasses} */{});
4446
4447 /** @type {SwalIcon[]} */
4448 const icons = ['success', 'warning', 'info', 'question', 'error'];
4449 const iconTypes = icons.reduce((acc, icon) => {
4450 acc[icon] = swalPrefix + icon;
4451 return acc;
4452 }, /** @type {SwalIcons} */{});
4453
4454 const consolePrefix = 'SweetAlert2:';
4455
4456 /**
4457 * Capitalize the first letter of a string
4458 *
4459 * @param {string} str
4460 * @returns {string}
4461 */
4462 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
4463
4464 /**
4465 * Standardize console warnings
4466 *
4467 * @param {string | string[]} message
4468 */
4469 const warn = message => {
4470 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
4471 };
4472
4473 /**
4474 * Standardize console errors
4475 *
4476 * @param {string} message
4477 */
4478 const error = message => {
4479 console.error(`${consolePrefix} ${message}`);
4480 };
4481
4482 /**
4483 * Private global state for `warnOnce`
4484 *
4485 * @type {string[]}
4486 * @private
4487 */
4488 const previousWarnOnceMessages = [];
4489
4490 /**
4491 * Show a console warning, but only if it hasn't already been shown
4492 *
4493 * @param {string} message
4494 */
4495 const warnOnce = message => {
4496 if (!previousWarnOnceMessages.includes(message)) {
4497 previousWarnOnceMessages.push(message);
4498 warn(message);
4499 }
4500 };
4501
4502 /**
4503 * Show a one-time console warning about deprecated params/methods
4504 *
4505 * @param {string} deprecatedParam
4506 * @param {string?} useInstead
4507 */
4508 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
4509 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
4510 };
4511
4512 /**
4513 * If `arg` is a function, call it (with no arguments or context) and return the result.
4514 * Otherwise, just pass the value through
4515 *
4516 * @param {(() => *) | *} arg
4517 * @returns {*}
4518 */
4519 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
4520
4521 /**
4522 * @param {*} arg
4523 * @returns {boolean}
4524 */
4525 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
4526
4527 /**
4528 * @param {*} arg
4529 * @returns {Promise<*>}
4530 */
4531 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
4532
4533 /**
4534 * @param {*} arg
4535 * @returns {boolean}
4536 */
4537 const isPromise = arg => arg && Promise.resolve(arg) === arg;
4538
4539 /**
4540 * @returns {boolean}
4541 */
4542 const isFirefox = () => navigator.userAgent.includes('Firefox');
4543
4544 /**
4545 * Gets the popup container which contains the backdrop and the popup itself.
4546 *
4547 * @returns {HTMLElement | null}
4548 */
4549 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
4550
4551 /**
4552 * @param {string} selectorString
4553 * @returns {HTMLElement | null}
4554 */
4555 const elementBySelector = selectorString => {
4556 const container = getContainer();
4557 return container ? container.querySelector(selectorString) : null;
4558 };
4559
4560 /**
4561 * @param {string} className
4562 * @returns {HTMLElement | null}
4563 */
4564 const elementByClass = className => {
4565 return elementBySelector(`.${className}`);
4566 };
4567
4568 /**
4569 * @returns {HTMLElement | null}
4570 */
4571 const getPopup = () => elementByClass(swalClasses.popup);
4572
4573 /**
4574 * @returns {HTMLElement | null}
4575 */
4576 const getIcon = () => elementByClass(swalClasses.icon);
4577
4578 /**
4579 * @returns {HTMLElement | null}
4580 */
4581 const getIconContent = () => elementByClass(swalClasses['icon-content']);
4582
4583 /**
4584 * @returns {HTMLElement | null}
4585 */
4586 const getTitle = () => elementByClass(swalClasses.title);
4587
4588 /**
4589 * @returns {HTMLElement | null}
4590 */
4591 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
4592
4593 /**
4594 * @returns {HTMLElement | null}
4595 */
4596 const getImage = () => elementByClass(swalClasses.image);
4597
4598 /**
4599 * @returns {HTMLElement | null}
4600 */
4601 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
4602
4603 /**
4604 * @returns {HTMLElement | null}
4605 */
4606 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
4607
4608 /**
4609 * @returns {HTMLButtonElement | null}
4610 */
4611 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
4612
4613 /**
4614 * @returns {HTMLButtonElement | null}
4615 */
4616 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
4617
4618 /**
4619 * @returns {HTMLButtonElement | null}
4620 */
4621 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
4622
4623 /**
4624 * @returns {HTMLElement | null}
4625 */
4626 const getInputLabel = () => elementByClass(swalClasses['input-label']);
4627
4628 /**
4629 * @returns {HTMLElement | null}
4630 */
4631 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
4632
4633 /**
4634 * @returns {HTMLElement | null}
4635 */
4636 const getActions = () => elementByClass(swalClasses.actions);
4637
4638 /**
4639 * @returns {HTMLElement | null}
4640 */
4641 const getFooter = () => elementByClass(swalClasses.footer);
4642
4643 /**
4644 * @returns {HTMLElement | null}
4645 */
4646 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
4647
4648 /**
4649 * @returns {HTMLElement | null}
4650 */
4651 const getCloseButton = () => elementByClass(swalClasses.close);
4652
4653 // https://github.com/jkup/focusable/blob/master/index.js
4654 const focusable = `
4655 a[href],
4656 area[href],
4657 input:not([disabled]),
4658 select:not([disabled]),
4659 textarea:not([disabled]),
4660 button:not([disabled]),
4661 iframe,
4662 object,
4663 embed,
4664 [tabindex="0"],
4665 [contenteditable],
4666 audio[controls],
4667 video[controls],
4668 summary
4669 `;
4670 /**
4671 * @returns {HTMLElement[]}
4672 */
4673 const getFocusableElements = () => {
4674 const popup = getPopup();
4675 if (!popup) {
4676 return [];
4677 }
4678 /** @type {NodeListOf<HTMLElement>} */
4679 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
4680 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
4681 // sort according to tabindex
4682 .sort((a, b) => {
4683 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
4684 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
4685 if (tabindexA > tabindexB) {
4686 return 1;
4687 } else if (tabindexA < tabindexB) {
4688 return -1;
4689 }
4690 return 0;
4691 });
4692
4693 /** @type {NodeListOf<HTMLElement>} */
4694 const otherFocusableElements = popup.querySelectorAll(focusable);
4695 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
4696 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
4697 };
4698
4699 /**
4700 * @returns {boolean}
4701 */
4702 const isModal = () => {
4703 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
4704 };
4705
4706 /**
4707 * @returns {boolean}
4708 */
4709 const isToast = () => {
4710 const popup = getPopup();
4711 if (!popup) {
4712 return false;
4713 }
4714 return hasClass(popup, swalClasses.toast);
4715 };
4716
4717 /**
4718 * @returns {boolean}
4719 */
4720 const isLoading = () => {
4721 const popup = getPopup();
4722 if (!popup) {
4723 return false;
4724 }
4725 return popup.hasAttribute('data-loading');
4726 };
4727
4728 /**
4729 * Securely set innerHTML of an element
4730 * https://github.com/sweetalert2/sweetalert2/issues/1926
4731 *
4732 * @param {HTMLElement} elem
4733 * @param {string} html
4734 */
4735 const setInnerHtml = (elem, html) => {
4736 elem.textContent = '';
4737 if (html) {
4738 const parser = new DOMParser();
4739 const parsed = parser.parseFromString(html, `text/html`);
4740 const head = parsed.querySelector('head');
4741 if (head) {
4742 Array.from(head.childNodes).forEach(child => {
4743 elem.appendChild(child);
4744 });
4745 }
4746 const body = parsed.querySelector('body');
4747 if (body) {
4748 Array.from(body.childNodes).forEach(child => {
4749 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
4750 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
4751 } else {
4752 elem.appendChild(child);
4753 }
4754 });
4755 }
4756 }
4757 };
4758
4759 /**
4760 * @param {HTMLElement} elem
4761 * @param {string} className
4762 * @returns {boolean}
4763 */
4764 const hasClass = (elem, className) => {
4765 if (!className) {
4766 return false;
4767 }
4768 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
4769 };
4770
4771 /**
4772 * @param {HTMLElement} elem
4773 * @param {SweetAlertOptions} params
4774 */
4775 const removeCustomClasses = (elem, params) => {
4776 Array.from(elem.classList).forEach(className => {
4777 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
4778 elem.classList.remove(className);
4779 }
4780 });
4781 };
4782
4783 /**
4784 * @param {HTMLElement} elem
4785 * @param {SweetAlertOptions} params
4786 * @param {string} className
4787 */
4788 const applyCustomClass = (elem, params, className) => {
4789 removeCustomClasses(elem, params);
4790 if (!params.customClass) {
4791 return;
4792 }
4793 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
4794 if (!customClass) {
4795 return;
4796 }
4797 if (typeof customClass !== 'string' && !customClass.forEach) {
4798 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
4799 return;
4800 }
4801 addClass(elem, customClass);
4802 };
4803
4804 /**
4805 * @param {HTMLElement} popup
4806 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
4807 * @returns {HTMLInputElement | null}
4808 */
4809 const getInput$1 = (popup, inputClass) => {
4810 if (!inputClass) {
4811 return null;
4812 }
4813 switch (inputClass) {
4814 case 'select':
4815 case 'textarea':
4816 case 'file':
4817 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
4818 case 'checkbox':
4819 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
4820 case 'radio':
4821 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
4822 case 'range':
4823 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
4824 default:
4825 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
4826 }
4827 };
4828
4829 /**
4830 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
4831 */
4832 const focusInput = input => {
4833 input.focus();
4834
4835 // place cursor at end of text in text input
4836 if (input.type !== 'file') {
4837 // http://stackoverflow.com/a/2345915
4838 const val = input.value;
4839 input.value = '';
4840 input.value = val;
4841 }
4842 };
4843
4844 /**
4845 * @param {HTMLElement | HTMLElement[] | null} target
4846 * @param {string | string[] | readonly string[] | undefined} classList
4847 * @param {boolean} condition
4848 */
4849 const toggleClass = (target, classList, condition) => {
4850 if (!target || !classList) {
4851 return;
4852 }
4853 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
4854 const targets = Array.isArray(target) ? target : [target];
4855 targets.forEach(elem => {
4856 classes.forEach(className => {
4857 if (condition) {
4858 elem.classList.add(className);
4859 } else {
4860 elem.classList.remove(className);
4861 }
4862 });
4863 });
4864 };
4865
4866 /**
4867 * @param {HTMLElement | HTMLElement[] | null} target
4868 * @param {string | string[] | readonly string[] | undefined} classList
4869 */
4870 const addClass = (target, classList) => {
4871 toggleClass(target, classList, true);
4872 };
4873
4874 /**
4875 * @param {HTMLElement | HTMLElement[] | null} target
4876 * @param {string | string[] | readonly string[] | undefined} classList
4877 */
4878 const removeClass = (target, classList) => {
4879 toggleClass(target, classList, false);
4880 };
4881
4882 /**
4883 * Get direct child of an element by class name
4884 *
4885 * @param {HTMLElement} elem
4886 * @param {string} className
4887 * @returns {HTMLElement | undefined}
4888 */
4889 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
4890 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
4891
4892 /**
4893 * @param {HTMLElement} elem
4894 * @param {string} property
4895 * @param {string | number | null | undefined} value
4896 */
4897 const applyNumericalStyle = (elem, property, value) => {
4898 if (value === `${parseInt(`${value}`)}`) {
4899 value = parseInt(value);
4900 }
4901 if (value || value === 0) {
4902 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
4903 } else {
4904 elem.style.removeProperty(property);
4905 }
4906 };
4907
4908 /**
4909 * @param {HTMLElement | null} elem
4910 * @param {string} display
4911 */
4912 const show = (elem, display = 'flex') => {
4913 if (!elem) {
4914 return;
4915 }
4916 elem.style.display = display;
4917 };
4918
4919 /**
4920 * @param {HTMLElement | null} elem
4921 */
4922 const hide = elem => {
4923 if (!elem) {
4924 return;
4925 }
4926 elem.style.display = 'none';
4927 };
4928
4929 /**
4930 * @param {HTMLElement | null} elem
4931 * @param {string} display
4932 */
4933 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
4934 if (!elem) {
4935 return;
4936 }
4937 new MutationObserver(() => {
4938 toggle(elem, elem.innerHTML, display);
4939 }).observe(elem, {
4940 childList: true,
4941 subtree: true
4942 });
4943 };
4944
4945 /**
4946 * @param {HTMLElement} parent
4947 * @param {string} selector
4948 * @param {string} property
4949 * @param {string} value
4950 */
4951 const setStyle = (parent, selector, property, value) => {
4952 /** @type {HTMLElement | null} */
4953 const el = parent.querySelector(selector);
4954 if (el) {
4955 el.style.setProperty(property, value);
4956 }
4957 };
4958
4959 /**
4960 * @param {HTMLElement} elem
4961 * @param {boolean | string | null | undefined} condition
4962 * @param {string} display
4963 */
4964 const toggle = (elem, condition, display = 'flex') => {
4965 if (condition) {
4966 show(elem, display);
4967 } else {
4968 hide(elem);
4969 }
4970 };
4971
4972 /**
4973 * borrowed from jquery $(elem).is(':visible') implementation
4974 *
4975 * @param {HTMLElement | null} elem
4976 * @returns {boolean}
4977 */
4978 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
4979
4980 /**
4981 * @returns {boolean}
4982 */
4983 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
4984
4985 /**
4986 * @param {HTMLElement} elem
4987 * @returns {boolean}
4988 */
4989 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
4990
4991 /**
4992 * @param {HTMLElement} element
4993 * @param {HTMLElement} stopElement
4994 * @returns {boolean}
4995 */
4996 const selfOrParentIsScrollable = (element, stopElement) => {
4997 let parent = /** @type {HTMLElement | null} */element;
4998 while (parent && parent !== stopElement) {
4999 if (isScrollable(parent)) {
5000 return true;
5001 }
5002 parent = parent.parentElement;
5003 }
5004 return false;
5005 };
5006
5007 /**
5008 * borrowed from https://stackoverflow.com/a/46352119
5009 *
5010 * @param {HTMLElement} elem
5011 * @returns {boolean}
5012 */
5013 const hasCssAnimation = elem => {
5014 const style = window.getComputedStyle(elem);
5015 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
5016 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
5017 return animDuration > 0 || transDuration > 0;
5018 };
5019
5020 /**
5021 * @param {number} timer
5022 * @param {boolean} reset
5023 */
5024 const animateTimerProgressBar = (timer, reset = false) => {
5025 const timerProgressBar = getTimerProgressBar();
5026 if (!timerProgressBar) {
5027 return;
5028 }
5029 if (isVisible$1(timerProgressBar)) {
5030 if (reset) {
5031 timerProgressBar.style.transition = 'none';
5032 timerProgressBar.style.width = '100%';
5033 }
5034 setTimeout(() => {
5035 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
5036 timerProgressBar.style.width = '0%';
5037 }, 10);
5038 }
5039 };
5040 const stopTimerProgressBar = () => {
5041 const timerProgressBar = getTimerProgressBar();
5042 if (!timerProgressBar) {
5043 return;
5044 }
5045 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5046 timerProgressBar.style.removeProperty('transition');
5047 timerProgressBar.style.width = '100%';
5048 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5049 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
5050 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
5051 };
5052
5053 /**
5054 * Detect Node env
5055 *
5056 * @returns {boolean}
5057 */
5058 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
5059
5060 const sweetHTML = `
5061 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
5062 <button type="button" class="${swalClasses.close}"></button>
5063 <ul class="${swalClasses['progress-steps']}"></ul>
5064 <div class="${swalClasses.icon}"></div>
5065 <img class="${swalClasses.image}" />
5066 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
5067 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
5068 <input class="${swalClasses.input}" id="${swalClasses.input}" />
5069 <input type="file" class="${swalClasses.file}" />
5070 <div class="${swalClasses.range}">
5071 <input type="range" />
5072 <output></output>
5073 </div>
5074 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
5075 <div class="${swalClasses.radio}"></div>
5076 <label class="${swalClasses.checkbox}">
5077 <input type="checkbox" id="${swalClasses.checkbox}" />
5078 <span class="${swalClasses.label}"></span>
5079 </label>
5080 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
5081 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
5082 <div class="${swalClasses.actions}">
5083 <div class="${swalClasses.loader}"></div>
5084 <button type="button" class="${swalClasses.confirm}"></button>
5085 <button type="button" class="${swalClasses.deny}"></button>
5086 <button type="button" class="${swalClasses.cancel}"></button>
5087 </div>
5088 <div class="${swalClasses.footer}"></div>
5089 <div class="${swalClasses['timer-progress-bar-container']}">
5090 <div class="${swalClasses['timer-progress-bar']}"></div>
5091 </div>
5092 </div>
5093 `.replace(/(^|\n)\s*/g, '');
5094
5095 /**
5096 * @returns {boolean}
5097 */
5098 const resetOldContainer = () => {
5099 const oldContainer = getContainer();
5100 if (!oldContainer) {
5101 return false;
5102 }
5103 oldContainer.remove();
5104 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
5105 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
5106 swalClasses['has-column']]);
5107 return true;
5108 };
5109 const resetValidationMessage$1 = () => {
5110 if (globalState.currentInstance) {
5111 globalState.currentInstance.resetValidationMessage();
5112 }
5113 };
5114 const addInputChangeListeners = () => {
5115 const popup = getPopup();
5116 if (!popup) {
5117 return;
5118 }
5119 const input = getDirectChildByClass(popup, swalClasses.input);
5120 const file = getDirectChildByClass(popup, swalClasses.file);
5121 /** @type {HTMLInputElement | null} */
5122 const range = popup.querySelector(`.${swalClasses.range} input`);
5123 /** @type {HTMLOutputElement | null} */
5124 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
5125 const select = getDirectChildByClass(popup, swalClasses.select);
5126 /** @type {HTMLInputElement | null} */
5127 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
5128 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
5129 if (input) {
5130 input.oninput = resetValidationMessage$1;
5131 }
5132 if (file) {
5133 file.onchange = resetValidationMessage$1;
5134 }
5135 if (select) {
5136 select.onchange = resetValidationMessage$1;
5137 }
5138 if (checkbox) {
5139 checkbox.onchange = resetValidationMessage$1;
5140 }
5141 if (textarea) {
5142 textarea.oninput = resetValidationMessage$1;
5143 }
5144 if (range && rangeOutput) {
5145 range.oninput = () => {
5146 resetValidationMessage$1();
5147 rangeOutput.value = range.value;
5148 };
5149 range.onchange = () => {
5150 resetValidationMessage$1();
5151 rangeOutput.value = range.value;
5152 };
5153 }
5154 };
5155
5156 /**
5157 * @param {string | HTMLElement} target
5158 * @returns {HTMLElement}
5159 */
5160 const getTarget = target => {
5161 if (typeof target === 'string') {
5162 const element = document.querySelector(target);
5163 if (!element) {
5164 throw new Error(`Target element "${target}" not found`);
5165 }
5166 return /** @type {HTMLElement} */element;
5167 }
5168 return target;
5169 };
5170
5171 /**
5172 * @param {SweetAlertOptions} params
5173 */
5174 const setupAccessibility = params => {
5175 const popup = getPopup();
5176 if (!popup) {
5177 return;
5178 }
5179 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
5180 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
5181 if (!params.toast) {
5182 popup.setAttribute('aria-modal', 'true');
5183 }
5184 };
5185
5186 /**
5187 * @param {HTMLElement} targetElement
5188 */
5189 const setupRTL = targetElement => {
5190 if (window.getComputedStyle(targetElement).direction === 'rtl') {
5191 addClass(getContainer(), swalClasses.rtl);
5192 globalState.isRTL = true;
5193 }
5194 };
5195
5196 /**
5197 * Add modal + backdrop to DOM
5198 *
5199 * @param {SweetAlertOptions} params
5200 */
5201 const init = params => {
5202 // Clean up the old popup container if it exists
5203 const oldContainerExisted = resetOldContainer();
5204 if (isNodeEnv()) {
5205 error('SweetAlert2 requires document to initialize');
5206 return;
5207 }
5208 const container = document.createElement('div');
5209 container.className = swalClasses.container;
5210 if (oldContainerExisted) {
5211 addClass(container, swalClasses['no-transition']);
5212 }
5213 setInnerHtml(container, sweetHTML);
5214 container.dataset['swal2Theme'] = params.theme;
5215 const targetElement = getTarget(params.target || 'body');
5216 targetElement.appendChild(container);
5217 if (params.topLayer) {
5218 container.setAttribute('popover', '');
5219 container.showPopover();
5220 }
5221 setupAccessibility(params);
5222 setupRTL(targetElement);
5223 addInputChangeListeners();
5224 };
5225
5226 /**
5227 * @param {HTMLElement | object | string} param
5228 * @param {HTMLElement} target
5229 */
5230 const parseHtmlToContainer = (param, target) => {
5231 // DOM element
5232 if (param instanceof HTMLElement) {
5233 target.appendChild(param);
5234 }
5235
5236 // Object
5237 else if (typeof param === 'object') {
5238 handleObject(param, target);
5239 }
5240
5241 // Plain string
5242 else if (param) {
5243 setInnerHtml(target, param);
5244 }
5245 };
5246
5247 /**
5248 * @param {object} param
5249 * @param {HTMLElement} target
5250 */
5251 const handleObject = (param, target) => {
5252 // JQuery element(s)
5253 if ('jquery' in param) {
5254 handleJqueryElem(target, param);
5255 }
5256
5257 // For other objects use their string representation
5258 else {
5259 setInnerHtml(target, param.toString());
5260 }
5261 };
5262
5263 /**
5264 * @param {HTMLElement} target
5265 * @param {any} elem
5266 */
5267 const handleJqueryElem = (target, elem) => {
5268 target.textContent = '';
5269 if (0 in elem) {
5270 for (let i = 0; i in elem; i++) {
5271 target.appendChild(elem[i].cloneNode(true));
5272 }
5273 } else {
5274 target.appendChild(elem.cloneNode(true));
5275 }
5276 };
5277
5278 /**
5279 * @param {SweetAlert} instance
5280 * @param {SweetAlertOptions} params
5281 */
5282 const renderActions = (instance, params) => {
5283 const actions = getActions();
5284 const loader = getLoader();
5285 if (!actions || !loader) {
5286 return;
5287 }
5288
5289 // Actions (buttons) wrapper
5290 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
5291 hide(actions);
5292 } else {
5293 show(actions);
5294 }
5295
5296 // Custom class
5297 applyCustomClass(actions, params, 'actions');
5298
5299 // Render all the buttons
5300 renderButtons(actions, loader, params);
5301
5302 // Loader
5303 setInnerHtml(loader, params.loaderHtml || '');
5304 applyCustomClass(loader, params, 'loader');
5305 };
5306
5307 /**
5308 * @param {HTMLElement} actions
5309 * @param {HTMLElement} loader
5310 * @param {SweetAlertOptions} params
5311 */
5312 function renderButtons(actions, loader, params) {
5313 const confirmButton = getConfirmButton();
5314 const denyButton = getDenyButton();
5315 const cancelButton = getCancelButton();
5316 if (!confirmButton || !denyButton || !cancelButton) {
5317 return;
5318 }
5319
5320 // Render buttons
5321 renderButton(confirmButton, 'confirm', params);
5322 renderButton(denyButton, 'deny', params);
5323 renderButton(cancelButton, 'cancel', params);
5324 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
5325 if (params.reverseButtons) {
5326 if (params.toast) {
5327 actions.insertBefore(cancelButton, confirmButton);
5328 actions.insertBefore(denyButton, confirmButton);
5329 } else {
5330 actions.insertBefore(cancelButton, loader);
5331 actions.insertBefore(denyButton, loader);
5332 actions.insertBefore(confirmButton, loader);
5333 }
5334 }
5335 }
5336
5337 /**
5338 * @param {HTMLElement} confirmButton
5339 * @param {HTMLElement} denyButton
5340 * @param {HTMLElement} cancelButton
5341 * @param {SweetAlertOptions} params
5342 */
5343 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
5344 if (!params.buttonsStyling) {
5345 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5346 return;
5347 }
5348 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5349
5350 // Apply custom background colors and outline colors to action buttons
5351 /** @type {[HTMLElement, string, string | undefined][]} */
5352 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
5353 buttons.forEach(([button, type, color]) => {
5354 if (color) {
5355 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
5356 }
5357 applyOutlineColor(button);
5358 });
5359 }
5360
5361 /**
5362 * @param {HTMLElement} button
5363 */
5364 function applyOutlineColor(button) {
5365 const buttonStyle = window.getComputedStyle(button);
5366 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
5367 // If the button already has a custom outline color, no need to change it
5368 return;
5369 }
5370 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
5371 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
5372 }
5373
5374 /**
5375 * @param {HTMLElement} button
5376 * @param {'confirm' | 'deny' | 'cancel'} buttonType
5377 * @param {SweetAlertOptions} params
5378 */
5379 function renderButton(button, buttonType, params) {
5380 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
5381 toggle(button, params[`show${buttonName}Button`], 'inline-block');
5382 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
5383 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
5384
5385 // Add buttons custom classes
5386 button.className = swalClasses[buttonType];
5387 applyCustomClass(button, params, `${buttonType}Button`);
5388 }
5389
5390 /**
5391 * @param {SweetAlert} instance
5392 * @param {SweetAlertOptions} params
5393 */
5394 const renderCloseButton = (instance, params) => {
5395 const closeButton = getCloseButton();
5396 if (!closeButton) {
5397 return;
5398 }
5399 setInnerHtml(closeButton, params.closeButtonHtml || '');
5400
5401 // Custom class
5402 applyCustomClass(closeButton, params, 'closeButton');
5403 toggle(closeButton, params.showCloseButton);
5404 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
5405 };
5406
5407 /**
5408 * @param {SweetAlert} instance
5409 * @param {SweetAlertOptions} params
5410 */
5411 const renderContainer = (instance, params) => {
5412 const container = getContainer();
5413 if (!container) {
5414 return;
5415 }
5416 handleBackdropParam(container, params.backdrop);
5417 handlePositionParam(container, params.position);
5418 handleGrowParam(container, params.grow);
5419
5420 // Custom class
5421 applyCustomClass(container, params, 'container');
5422 };
5423
5424 /**
5425 * @param {HTMLElement} container
5426 * @param {SweetAlertOptions['backdrop']} backdrop
5427 */
5428 function handleBackdropParam(container, backdrop) {
5429 if (typeof backdrop === 'string') {
5430 container.style.background = backdrop;
5431 } else if (!backdrop) {
5432 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
5433 }
5434 }
5435
5436 /**
5437 * @param {HTMLElement} container
5438 * @param {SweetAlertOptions['position']} position
5439 */
5440 function handlePositionParam(container, position) {
5441 if (!position) {
5442 return;
5443 }
5444 if (position in swalClasses) {
5445 addClass(container, swalClasses[position]);
5446 } else {
5447 warn('The "position" parameter is not valid, defaulting to "center"');
5448 addClass(container, swalClasses.center);
5449 }
5450 }
5451
5452 /**
5453 * @param {HTMLElement} container
5454 * @param {SweetAlertOptions['grow']} grow
5455 */
5456 function handleGrowParam(container, grow) {
5457 if (!grow) {
5458 return;
5459 }
5460 addClass(container, swalClasses[`grow-${grow}`]);
5461 }
5462
5463 /**
5464 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
5465 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
5466 * This is the approach that Babel will probably take to implement private methods/fields
5467 * https://github.com/tc39/proposal-private-methods
5468 * https://github.com/babel/babel/pull/7555
5469 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
5470 * then we can use that language feature.
5471 */
5472
5473 var privateProps = {
5474 innerParams: new WeakMap(),
5475 domCache: new WeakMap(),
5476 focusedElement: new WeakMap()
5477 };
5478
5479 /// <reference path="../../../../sweetalert2.d.ts"/>
5480
5481
5482 /** @type {InputClass[]} */
5483 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
5484
5485 /**
5486 * @param {SweetAlert} instance
5487 * @param {SweetAlertOptions} params
5488 */
5489 const renderInput = (instance, params) => {
5490 const popup = getPopup();
5491 if (!popup) {
5492 return;
5493 }
5494 const innerParams = privateProps.innerParams.get(instance);
5495 const rerender = !innerParams || params.input !== innerParams.input;
5496 inputClasses.forEach(inputClass => {
5497 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
5498 if (!inputContainer) {
5499 return;
5500 }
5501
5502 // set attributes
5503 setAttributes(inputClass, params.inputAttributes);
5504
5505 // set class
5506 inputContainer.className = swalClasses[inputClass];
5507 if (rerender) {
5508 hide(inputContainer);
5509 }
5510 });
5511 if (params.input) {
5512 if (rerender) {
5513 showInput(params);
5514 }
5515 // set custom class
5516 setCustomClass(params);
5517 }
5518 };
5519
5520 /**
5521 * @param {SweetAlertOptions} params
5522 */
5523 const showInput = params => {
5524 if (!params.input) {
5525 return;
5526 }
5527 if (!renderInputType[params.input]) {
5528 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
5529 return;
5530 }
5531 const inputContainer = getInputContainer(params.input);
5532 if (!inputContainer) {
5533 return;
5534 }
5535 const input = renderInputType[params.input](inputContainer, params);
5536 show(inputContainer);
5537
5538 // input autofocus
5539 if (params.inputAutoFocus) {
5540 setTimeout(() => {
5541 focusInput(input);
5542 });
5543 }
5544 };
5545
5546 /**
5547 * @param {HTMLInputElement} input
5548 */
5549 const removeAttributes = input => {
5550 for (const {
5551 name
5552 } of Array.from(input.attributes)) {
5553 if (!['id', 'type', 'value', 'style'].includes(name)) {
5554 input.removeAttribute(name);
5555 }
5556 }
5557 };
5558
5559 /**
5560 * @param {InputClass} inputClass
5561 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
5562 */
5563 const setAttributes = (inputClass, inputAttributes) => {
5564 const popup = getPopup();
5565 if (!popup) {
5566 return;
5567 }
5568 const input = getInput$1(popup, inputClass);
5569 if (!input) {
5570 return;
5571 }
5572 removeAttributes(input);
5573 for (const attr in inputAttributes) {
5574 input.setAttribute(attr, inputAttributes[attr]);
5575 }
5576 };
5577
5578 /**
5579 * @param {SweetAlertOptions} params
5580 */
5581 const setCustomClass = params => {
5582 if (!params.input) {
5583 return;
5584 }
5585 const inputContainer = getInputContainer(params.input);
5586 if (inputContainer) {
5587 applyCustomClass(inputContainer, params, 'input');
5588 }
5589 };
5590
5591 /**
5592 * @param {HTMLInputElement | HTMLTextAreaElement} input
5593 * @param {SweetAlertOptions} params
5594 */
5595 const setInputPlaceholder = (input, params) => {
5596 if (!input.placeholder && params.inputPlaceholder) {
5597 input.placeholder = params.inputPlaceholder;
5598 }
5599 };
5600
5601 /**
5602 * @param {Input} input
5603 * @param {Input} prependTo
5604 * @param {SweetAlertOptions} params
5605 */
5606 const setInputLabel = (input, prependTo, params) => {
5607 if (params.inputLabel) {
5608 const label = document.createElement('label');
5609 const labelClass = swalClasses['input-label'];
5610 label.setAttribute('for', input.id);
5611 label.className = labelClass;
5612 if (typeof params.customClass === 'object') {
5613 addClass(label, params.customClass.inputLabel);
5614 }
5615 label.innerText = params.inputLabel;
5616 prependTo.insertAdjacentElement('beforebegin', label);
5617 }
5618 };
5619
5620 /**
5621 * @param {SweetAlertInput} inputType
5622 * @returns {HTMLElement | undefined}
5623 */
5624 const getInputContainer = inputType => {
5625 const popup = getPopup();
5626 if (!popup) {
5627 return;
5628 }
5629 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
5630 };
5631
5632 /**
5633 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
5634 * @param {SweetAlertOptions['inputValue']} inputValue
5635 */
5636 const checkAndSetInputValue = (input, inputValue) => {
5637 if (['string', 'number'].includes(typeof inputValue)) {
5638 input.value = `${inputValue}`;
5639 } else if (!isPromise(inputValue)) {
5640 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
5641 }
5642 };
5643
5644 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
5645 const renderInputType = {};
5646
5647 /**
5648 * @param {Input | HTMLElement} input
5649 * @param {SweetAlertOptions} params
5650 * @returns {Input}
5651 */
5652 renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = renderInputType.search = renderInputType.date = renderInputType['datetime-local'] = renderInputType.time = renderInputType.week = renderInputType.month = /** @type {(input: Input | HTMLElement, params: SweetAlertOptions) => Input} */
5653 (input, params) => {
5654 // oxfmt-ignore
5655 const inputElement = /** @type {HTMLInputElement} */input;
5656 checkAndSetInputValue(inputElement, params.inputValue);
5657 setInputLabel(inputElement, inputElement, params);
5658 setInputPlaceholder(inputElement, params);
5659 // oxfmt-ignore
5660 inputElement.type = /** @type {string} */params.input;
5661 return inputElement;
5662 };
5663
5664 /**
5665 * @param {Input | HTMLElement} input
5666 * @param {SweetAlertOptions} params
5667 * @returns {Input}
5668 */
5669 renderInputType.file = (input, params) => {
5670 const inputElement = /** @type {HTMLInputElement} */input;
5671 setInputLabel(inputElement, inputElement, params);
5672 setInputPlaceholder(inputElement, params);
5673 return inputElement;
5674 };
5675
5676 /**
5677 * @param {Input | HTMLElement} range
5678 * @param {SweetAlertOptions} params
5679 * @returns {Input}
5680 */
5681 renderInputType.range = (range, params) => {
5682 const rangeContainer = /** @type {HTMLElement} */range;
5683 const rangeInput = rangeContainer.querySelector('input');
5684 const rangeOutput = rangeContainer.querySelector('output');
5685 if (rangeInput) {
5686 checkAndSetInputValue(rangeInput, params.inputValue);
5687 rangeInput.type = /** @type {string} */params.input;
5688 setInputLabel(rangeInput, /** @type {Input} */range, params);
5689 }
5690 if (rangeOutput) {
5691 checkAndSetInputValue(rangeOutput, params.inputValue);
5692 }
5693 return /** @type {Input} */range;
5694 };
5695
5696 /**
5697 * @param {Input | HTMLElement} select
5698 * @param {SweetAlertOptions} params
5699 * @returns {Input}
5700 */
5701 renderInputType.select = (select, params) => {
5702 const selectElement = /** @type {HTMLSelectElement} */select;
5703 selectElement.textContent = '';
5704 if (params.inputPlaceholder) {
5705 const placeholder = document.createElement('option');
5706 setInnerHtml(placeholder, params.inputPlaceholder);
5707 placeholder.value = '';
5708 placeholder.disabled = true;
5709 placeholder.selected = true;
5710 selectElement.appendChild(placeholder);
5711 }
5712 setInputLabel(selectElement, selectElement, params);
5713 return selectElement;
5714 };
5715
5716 /**
5717 * @param {Input | HTMLElement} radio
5718 * @returns {Input}
5719 */
5720 renderInputType.radio = radio => {
5721 const radioElement = /** @type {HTMLElement} */radio;
5722 radioElement.textContent = '';
5723 return /** @type {Input} */radio;
5724 };
5725
5726 /**
5727 * @param {Input | HTMLElement} checkboxContainer
5728 * @param {SweetAlertOptions} params
5729 * @returns {Input}
5730 */
5731 renderInputType.checkbox = (checkboxContainer, params) => {
5732 const popup = getPopup();
5733 if (!popup) {
5734 throw new Error('Popup not found');
5735 }
5736 const checkbox = getInput$1(popup, 'checkbox');
5737 if (!checkbox) {
5738 throw new Error('Checkbox input not found');
5739 }
5740 checkbox.value = '1';
5741 checkbox.checked = Boolean(params.inputValue);
5742 const containerElement = /** @type {HTMLElement} */checkboxContainer;
5743 const label = containerElement.querySelector('span');
5744 if (label) {
5745 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
5746 if (placeholderOrLabel) {
5747 setInnerHtml(label, placeholderOrLabel);
5748 }
5749 }
5750 return checkbox;
5751 };
5752
5753 /**
5754 * @param {Input | HTMLElement} textarea
5755 * @param {SweetAlertOptions} params
5756 * @returns {Input}
5757 */
5758 renderInputType.textarea = (textarea, params) => {
5759 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
5760 checkAndSetInputValue(textareaElement, params.inputValue);
5761 setInputPlaceholder(textareaElement, params);
5762 setInputLabel(textareaElement, textareaElement, params);
5763
5764 /**
5765 * @param {HTMLElement} el
5766 * @returns {number}
5767 */
5768 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
5769
5770 // https://github.com/sweetalert2/sweetalert2/issues/2291
5771 setTimeout(() => {
5772 // https://github.com/sweetalert2/sweetalert2/issues/1699
5773 if ('MutationObserver' in window) {
5774 const popup = getPopup();
5775 if (!popup) {
5776 return;
5777 }
5778 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
5779 const textareaResizeHandler = () => {
5780 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
5781 if (!document.body.contains(textareaElement)) {
5782 return;
5783 }
5784 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
5785 const popupElement = getPopup();
5786 if (popupElement) {
5787 if (textareaWidth > initialPopupWidth) {
5788 popupElement.style.width = `${textareaWidth}px`;
5789 } else {
5790 applyNumericalStyle(popupElement, 'width', params.width);
5791 }
5792 }
5793 };
5794 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
5795 attributes: true,
5796 attributeFilter: ['style']
5797 });
5798 }
5799 });
5800 return textareaElement;
5801 };
5802
5803 /**
5804 * @param {SweetAlert} instance
5805 * @param {SweetAlertOptions} params
5806 */
5807 const renderContent = (instance, params) => {
5808 const htmlContainer = getHtmlContainer();
5809 if (!htmlContainer) {
5810 return;
5811 }
5812 showWhenInnerHtmlPresent(htmlContainer);
5813 applyCustomClass(htmlContainer, params, 'htmlContainer');
5814
5815 // Content as HTML
5816 if (params.html) {
5817 parseHtmlToContainer(params.html, htmlContainer);
5818 show(htmlContainer, 'block');
5819 }
5820
5821 // Content as plain text
5822 else if (params.text) {
5823 htmlContainer.textContent = params.text;
5824 show(htmlContainer, 'block');
5825 }
5826
5827 // No content
5828 else {
5829 hide(htmlContainer);
5830 }
5831 renderInput(instance, params);
5832 };
5833
5834 /**
5835 * @param {SweetAlert} instance
5836 * @param {SweetAlertOptions} params
5837 */
5838 const renderFooter = (instance, params) => {
5839 const footer = getFooter();
5840 if (!footer) {
5841 return;
5842 }
5843 showWhenInnerHtmlPresent(footer);
5844 toggle(footer, Boolean(params.footer), 'block');
5845 if (params.footer) {
5846 parseHtmlToContainer(params.footer, footer);
5847 }
5848
5849 // Custom class
5850 applyCustomClass(footer, params, 'footer');
5851 };
5852
5853 /**
5854 * @param {SweetAlert} instance
5855 * @param {SweetAlertOptions} params
5856 */
5857 const renderIcon = (instance, params) => {
5858 const innerParams = privateProps.innerParams.get(instance);
5859 const icon = getIcon();
5860 if (!icon) {
5861 return;
5862 }
5863
5864 // if the given icon already rendered, apply the styling without re-rendering the icon
5865 if (innerParams && params.icon === innerParams.icon) {
5866 // Custom or default content
5867 setContent(icon, params);
5868 applyStyles(icon, params);
5869 return;
5870 }
5871 if (!params.icon && !params.iconHtml) {
5872 hide(icon);
5873 return;
5874 }
5875 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
5876 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
5877 hide(icon);
5878 return;
5879 }
5880 show(icon);
5881
5882 // Custom or default content
5883 setContent(icon, params);
5884 applyStyles(icon, params);
5885
5886 // Animate icon
5887 addClass(icon, params.showClass && params.showClass.icon);
5888
5889 // Re-adjust the success icon on system theme change
5890 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
5891 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
5892 };
5893
5894 /**
5895 * @param {HTMLElement} icon
5896 * @param {SweetAlertOptions} params
5897 */
5898 const applyStyles = (icon, params) => {
5899 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
5900 if (params.icon !== iconType) {
5901 removeClass(icon, iconClassName);
5902 }
5903 }
5904 addClass(icon, params.icon && iconTypes[params.icon]);
5905
5906 // Icon color
5907 setColor(icon, params);
5908
5909 // Success icon background color
5910 adjustSuccessIconBackgroundColor();
5911
5912 // Custom class
5913 applyCustomClass(icon, params, 'icon');
5914 };
5915
5916 // Adjust success icon background color to match the popup background color
5917 const adjustSuccessIconBackgroundColor = () => {
5918 const popup = getPopup();
5919 if (!popup) {
5920 return;
5921 }
5922 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
5923 /** @type {NodeListOf<HTMLElement>} */
5924 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
5925 successIconParts.forEach(part => {
5926 part.style.backgroundColor = popupBackgroundColor;
5927 });
5928 };
5929
5930 /**
5931 *
5932 * @param {SweetAlertOptions} params
5933 * @returns {string}
5934 */
5935 const successIconHtml = params => `
5936 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
5937 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
5938 <div class="swal2-success-ring"></div>
5939 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
5940 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
5941 `;
5942 const errorIconHtml = `
5943 <span class="swal2-x-mark">
5944 <span class="swal2-x-mark-line-left"></span>
5945 <span class="swal2-x-mark-line-right"></span>
5946 </span>
5947 `;
5948
5949 /**
5950 * @param {HTMLElement} icon
5951 * @param {SweetAlertOptions} params
5952 */
5953 const setContent = (icon, params) => {
5954 if (!params.icon && !params.iconHtml) {
5955 return;
5956 }
5957 let oldContent = icon.innerHTML;
5958 let newContent = '';
5959 if (params.iconHtml) {
5960 newContent = iconContent(params.iconHtml);
5961 } else if (params.icon === 'success') {
5962 newContent = successIconHtml(params);
5963 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
5964 } else if (params.icon === 'error') {
5965 newContent = errorIconHtml;
5966 } else if (params.icon) {
5967 const defaultIconHtml = {
5968 question: '?',
5969 warning: '!',
5970 info: 'i'
5971 };
5972 newContent = iconContent(defaultIconHtml[params.icon]);
5973 }
5974 if (oldContent.trim() !== newContent.trim()) {
5975 setInnerHtml(icon, newContent);
5976 }
5977 };
5978
5979 /**
5980 * @param {HTMLElement} icon
5981 * @param {SweetAlertOptions} params
5982 */
5983 const setColor = (icon, params) => {
5984 if (!params.iconColor) {
5985 return;
5986 }
5987 icon.style.color = params.iconColor;
5988 icon.style.borderColor = params.iconColor;
5989 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
5990 setStyle(icon, sel, 'background-color', params.iconColor);
5991 }
5992 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
5993 };
5994
5995 /**
5996 * @param {string} content
5997 * @returns {string}
5998 */
5999 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
6000
6001 /**
6002 * @param {SweetAlert} instance
6003 * @param {SweetAlertOptions} params
6004 */
6005 const renderImage = (instance, params) => {
6006 const image = getImage();
6007 if (!image) {
6008 return;
6009 }
6010 if (!params.imageUrl) {
6011 hide(image);
6012 return;
6013 }
6014 show(image, '');
6015
6016 // Src, alt
6017 image.setAttribute('src', params.imageUrl);
6018 image.setAttribute('alt', params.imageAlt || '');
6019
6020 // Width, height
6021 applyNumericalStyle(image, 'width', params.imageWidth);
6022 applyNumericalStyle(image, 'height', params.imageHeight);
6023
6024 // Class
6025 image.className = swalClasses.image;
6026 applyCustomClass(image, params, 'image');
6027 };
6028
6029 let dragging = false;
6030 let mousedownX = 0;
6031 let mousedownY = 0;
6032 let initialX = 0;
6033 let initialY = 0;
6034
6035 /**
6036 * @param {HTMLElement} popup
6037 */
6038 const addDraggableListeners = popup => {
6039 popup.addEventListener('mousedown', down);
6040 document.body.addEventListener('mousemove', move);
6041 popup.addEventListener('mouseup', up);
6042 popup.addEventListener('touchstart', down);
6043 document.body.addEventListener('touchmove', move);
6044 popup.addEventListener('touchend', up);
6045 };
6046
6047 /**
6048 * @param {HTMLElement} popup
6049 */
6050 const removeDraggableListeners = popup => {
6051 popup.removeEventListener('mousedown', down);
6052 document.body.removeEventListener('mousemove', move);
6053 popup.removeEventListener('mouseup', up);
6054 popup.removeEventListener('touchstart', down);
6055 document.body.removeEventListener('touchmove', move);
6056 popup.removeEventListener('touchend', up);
6057 };
6058
6059 /**
6060 * @param {MouseEvent | TouchEvent} event
6061 */
6062 const down = event => {
6063 const popup = getPopup();
6064 if (!popup) {
6065 return;
6066 }
6067 const icon = getIcon();
6068 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
6069 dragging = true;
6070 const clientXY = getClientXY(event);
6071 mousedownX = clientXY.clientX;
6072 mousedownY = clientXY.clientY;
6073 initialX = parseInt(popup.style.insetInlineStart) || 0;
6074 initialY = parseInt(popup.style.insetBlockStart) || 0;
6075 addClass(popup, 'swal2-dragging');
6076 }
6077 };
6078
6079 /**
6080 * @param {MouseEvent | TouchEvent} event
6081 */
6082 const move = event => {
6083 const popup = getPopup();
6084 if (!popup) {
6085 return;
6086 }
6087 if (dragging) {
6088 let {
6089 clientX,
6090 clientY
6091 } = getClientXY(event);
6092 const deltaX = clientX - mousedownX;
6093 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
6094 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
6095 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
6096 }
6097 };
6098 const up = () => {
6099 const popup = getPopup();
6100 dragging = false;
6101 removeClass(popup, 'swal2-dragging');
6102 };
6103
6104 /**
6105 * @param {MouseEvent | TouchEvent} event
6106 * @returns {{ clientX: number, clientY: number }}
6107 */
6108 const getClientXY = event => {
6109 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
6110 return {
6111 clientX: source.clientX,
6112 clientY: source.clientY
6113 };
6114 };
6115
6116 /**
6117 * @param {SweetAlert} instance
6118 * @param {SweetAlertOptions} params
6119 */
6120 const renderPopup = (instance, params) => {
6121 const container = getContainer();
6122 const popup = getPopup();
6123 if (!container || !popup) {
6124 return;
6125 }
6126
6127 // Width
6128 // https://github.com/sweetalert2/sweetalert2/issues/2170
6129 if (params.toast) {
6130 applyNumericalStyle(container, 'width', params.width);
6131 popup.style.width = '100%';
6132 const loader = getLoader();
6133 if (loader) {
6134 popup.insertBefore(loader, getIcon());
6135 }
6136 } else {
6137 applyNumericalStyle(popup, 'width', params.width);
6138 }
6139
6140 // Padding
6141 applyNumericalStyle(popup, 'padding', params.padding);
6142
6143 // Color
6144 if (params.color) {
6145 popup.style.color = params.color;
6146 }
6147
6148 // Background
6149 if (params.background) {
6150 popup.style.background = params.background;
6151 }
6152 hide(getValidationMessage());
6153
6154 // Classes
6155 addClasses$1(popup, params);
6156 if (params.draggable && !params.toast) {
6157 addClass(popup, swalClasses.draggable);
6158 addDraggableListeners(popup);
6159 } else {
6160 removeClass(popup, swalClasses.draggable);
6161 removeDraggableListeners(popup);
6162 }
6163 };
6164
6165 /**
6166 * @param {HTMLElement} popup
6167 * @param {SweetAlertOptions} params
6168 */
6169 const addClasses$1 = (popup, params) => {
6170 const showClass = params.showClass || {};
6171 // Default Class + showClass when updating Swal.update({})
6172 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
6173 if (params.toast) {
6174 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
6175 addClass(popup, swalClasses.toast);
6176 } else {
6177 addClass(popup, swalClasses.modal);
6178 }
6179
6180 // Custom class
6181 applyCustomClass(popup, params, 'popup');
6182 // TODO: remove in the next major
6183 if (typeof params.customClass === 'string') {
6184 addClass(popup, params.customClass);
6185 }
6186
6187 // Icon class (#1842)
6188 if (params.icon) {
6189 addClass(popup, swalClasses[`icon-${params.icon}`]);
6190 }
6191 };
6192
6193 /**
6194 * @param {SweetAlert} instance
6195 * @param {SweetAlertOptions} params
6196 */
6197 const renderProgressSteps = (instance, params) => {
6198 const progressStepsContainer = getProgressSteps();
6199 if (!progressStepsContainer) {
6200 return;
6201 }
6202 const {
6203 progressSteps,
6204 currentProgressStep
6205 } = params;
6206 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
6207 hide(progressStepsContainer);
6208 return;
6209 }
6210 show(progressStepsContainer);
6211 progressStepsContainer.textContent = '';
6212 if (currentProgressStep >= progressSteps.length) {
6213 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
6214 }
6215 progressSteps.forEach((step, index) => {
6216 const stepEl = createStepElement(step);
6217 progressStepsContainer.appendChild(stepEl);
6218 if (index === currentProgressStep) {
6219 addClass(stepEl, swalClasses['active-progress-step']);
6220 }
6221 if (index !== progressSteps.length - 1) {
6222 const lineEl = createLineElement(params);
6223 progressStepsContainer.appendChild(lineEl);
6224 }
6225 });
6226 };
6227
6228 /**
6229 * @param {string} step
6230 * @returns {HTMLLIElement}
6231 */
6232 const createStepElement = step => {
6233 const stepEl = document.createElement('li');
6234 addClass(stepEl, swalClasses['progress-step']);
6235 setInnerHtml(stepEl, step);
6236 return stepEl;
6237 };
6238
6239 /**
6240 * @param {SweetAlertOptions} params
6241 * @returns {HTMLLIElement}
6242 */
6243 const createLineElement = params => {
6244 const lineEl = document.createElement('li');
6245 addClass(lineEl, swalClasses['progress-step-line']);
6246 if (params.progressStepsDistance) {
6247 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
6248 }
6249 return lineEl;
6250 };
6251
6252 /**
6253 * @param {SweetAlert} instance
6254 * @param {SweetAlertOptions} params
6255 */
6256 const renderTitle = (instance, params) => {
6257 const title = getTitle();
6258 if (!title) {
6259 return;
6260 }
6261 showWhenInnerHtmlPresent(title);
6262 toggle(title, Boolean(params.title || params.titleText), 'block');
6263 if (params.title) {
6264 parseHtmlToContainer(params.title, title);
6265 }
6266 if (params.titleText) {
6267 title.innerText = params.titleText;
6268 }
6269
6270 // Custom class
6271 applyCustomClass(title, params, 'title');
6272 };
6273
6274 /**
6275 * @param {SweetAlert} instance
6276 * @param {SweetAlertOptions} params
6277 */
6278 const render = (instance, params) => {
6279 var _globalState$eventEmi;
6280 renderPopup(instance, params);
6281 renderContainer(instance, params);
6282 renderProgressSteps(instance, params);
6283 renderIcon(instance, params);
6284 renderImage(instance, params);
6285 renderTitle(instance, params);
6286 renderCloseButton(instance, params);
6287 renderContent(instance, params);
6288 renderActions(instance, params);
6289 renderFooter(instance, params);
6290 const popup = getPopup();
6291 if (typeof params.didRender === 'function' && popup) {
6292 params.didRender(popup);
6293 }
6294 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
6295 };
6296
6297 /*
6298 * Global function to determine if SweetAlert2 popup is shown
6299 */
6300 const isVisible = () => {
6301 return isVisible$1(getPopup());
6302 };
6303
6304 /*
6305 * Global function to click 'Confirm' button
6306 */
6307 const clickConfirm = () => {
6308 var _dom$getConfirmButton;
6309 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
6310 };
6311
6312 /*
6313 * Global function to click 'Deny' button
6314 */
6315 const clickDeny = () => {
6316 var _dom$getDenyButton;
6317 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
6318 };
6319
6320 /*
6321 * Global function to click 'Cancel' button
6322 */
6323 const clickCancel = () => {
6324 var _dom$getCancelButton;
6325 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
6326 };
6327
6328 /** @type {Record<DismissReason, DismissReason>} */
6329 const DismissReason = Object.freeze({
6330 cancel: 'cancel',
6331 backdrop: 'backdrop',
6332 close: 'close',
6333 esc: 'esc',
6334 timer: 'timer'
6335 });
6336
6337 /**
6338 * @param {GlobalState} globalState
6339 */
6340 const removeKeydownHandler = globalState => {
6341 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
6342 const handler = /** @type {EventListenerOrEventListenerObject} */
6343 /** @type {unknown} */globalState.keydownHandler;
6344 globalState.keydownTarget.removeEventListener('keydown', handler, {
6345 capture: globalState.keydownListenerCapture
6346 });
6347 globalState.keydownHandlerAdded = false;
6348 }
6349 };
6350
6351 /**
6352 * @param {GlobalState} globalState
6353 * @param {SweetAlertOptions} innerParams
6354 * @param {(dismiss: DismissReason) => void} dismissWith
6355 */
6356 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
6357 removeKeydownHandler(globalState);
6358 if (!innerParams.toast) {
6359 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
6360 const handler = e => keydownHandler(innerParams, e, dismissWith);
6361 globalState.keydownHandler = handler;
6362 const target = innerParams.keydownListenerCapture ? window : getPopup();
6363 if (target) {
6364 globalState.keydownTarget = target;
6365 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
6366 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
6367 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
6368 capture: globalState.keydownListenerCapture
6369 });
6370 globalState.keydownHandlerAdded = true;
6371 }
6372 }
6373 };
6374
6375 /**
6376 * @param {number} index
6377 * @param {number} increment
6378 * @returns {boolean} shouldPreventDefault
6379 */
6380 const setFocus = (index, increment) => {
6381 var _dom$getPopup;
6382 const focusableElements = getFocusableElements();
6383 // search for visible elements and select the next possible match
6384 if (focusableElements.length) {
6385 index = index + increment;
6386
6387 // shift + tab when .swal2-popup is focused
6388 if (index === -2) {
6389 index = focusableElements.length - 1;
6390 }
6391
6392 // rollover to first item
6393 if (index === focusableElements.length) {
6394 index = 0;
6395
6396 // go to last item
6397 } else if (index === -1) {
6398 index = focusableElements.length - 1;
6399 }
6400 focusableElements[index].focus();
6401
6402 // don't prevent default for iframes (Firefox fix)
6403 // https://github.com/sweetalert2/sweetalert2/issues/2931
6404 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
6405 return false;
6406 }
6407 return true;
6408 }
6409 // no visible focusable elements, focus the popup
6410 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
6411 return true;
6412 };
6413 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
6414 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
6415
6416 /**
6417 * @param {SweetAlertOptions} innerParams
6418 * @param {KeyboardEvent} event
6419 * @param {(dismiss: DismissReason) => void} dismissWith
6420 */
6421 const keydownHandler = (innerParams, event, dismissWith) => {
6422 if (!innerParams) {
6423 return; // This instance has already been destroyed
6424 }
6425
6426 // Ignore keydown during IME composition
6427 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
6428 // https://github.com/sweetalert2/sweetalert2/issues/720
6429 // https://github.com/sweetalert2/sweetalert2/issues/2406
6430 if (event.isComposing || event.keyCode === 229) {
6431 return;
6432 }
6433 if (innerParams.stopKeydownPropagation) {
6434 event.stopPropagation();
6435 }
6436
6437 // ENTER
6438 if (event.key === 'Enter') {
6439 handleEnter(event, innerParams);
6440 }
6441
6442 // TAB
6443 else if (event.key === 'Tab') {
6444 handleTab(event);
6445 }
6446
6447 // ARROWS - switch focus between buttons
6448 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
6449 handleArrows(event.key);
6450 }
6451
6452 // ESC
6453 else if (event.key === 'Escape') {
6454 handleEsc(event, innerParams, dismissWith);
6455 }
6456 };
6457
6458 /**
6459 * @param {KeyboardEvent} event
6460 * @param {SweetAlertOptions} innerParams
6461 */
6462 const handleEnter = (event, innerParams) => {
6463 // https://github.com/sweetalert2/sweetalert2/issues/2386
6464 if (!callIfFunction(innerParams.allowEnterKey)) {
6465 return;
6466 }
6467 const popup = getPopup();
6468 if (!popup || !innerParams.input) {
6469 return;
6470 }
6471 const input = getInput$1(popup, innerParams.input);
6472 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
6473 if (['textarea', 'file'].includes(innerParams.input)) {
6474 return; // do not submit
6475 }
6476 clickConfirm();
6477 event.preventDefault();
6478 }
6479 };
6480
6481 /**
6482 * @param {KeyboardEvent} event
6483 */
6484 const handleTab = event => {
6485 const targetElement = event.target;
6486 const focusableElements = getFocusableElements();
6487 const btnIndex = focusableElements.findIndex(el => el === targetElement);
6488
6489 // don't prevent default for iframes (Firefox fix)
6490 // https://github.com/sweetalert2/sweetalert2/issues/2931
6491 let shouldPreventDefault = true;
6492
6493 // Cycle to the next button
6494 if (!event.shiftKey) {
6495 shouldPreventDefault = setFocus(btnIndex, 1);
6496 }
6497
6498 // Cycle to the prev button
6499 else {
6500 shouldPreventDefault = setFocus(btnIndex, -1);
6501 }
6502 event.stopPropagation();
6503 if (shouldPreventDefault) {
6504 event.preventDefault();
6505 }
6506 };
6507
6508 /**
6509 * @param {string} key
6510 */
6511 const handleArrows = key => {
6512 const actions = getActions();
6513 const confirmButton = getConfirmButton();
6514 const denyButton = getDenyButton();
6515 const cancelButton = getCancelButton();
6516 if (!actions || !confirmButton || !denyButton || !cancelButton) {
6517 return;
6518 }
6519 /** @type HTMLElement[] */
6520 const buttons = [confirmButton, denyButton, cancelButton];
6521 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
6522 return;
6523 }
6524 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
6525 let buttonToFocus = document.activeElement;
6526 if (!buttonToFocus) {
6527 return;
6528 }
6529 for (let i = 0; i < actions.children.length; i++) {
6530 buttonToFocus = buttonToFocus[sibling];
6531 if (!buttonToFocus) {
6532 return;
6533 }
6534 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
6535 break;
6536 }
6537 }
6538 if (buttonToFocus instanceof HTMLButtonElement) {
6539 buttonToFocus.focus();
6540 }
6541 };
6542
6543 /**
6544 * @param {KeyboardEvent} event
6545 * @param {SweetAlertOptions} innerParams
6546 * @param {(dismiss: DismissReason) => void} dismissWith
6547 */
6548 const handleEsc = (event, innerParams, dismissWith) => {
6549 event.preventDefault();
6550 if (callIfFunction(innerParams.allowEscapeKey)) {
6551 dismissWith(DismissReason.esc);
6552 }
6553 };
6554
6555 /**
6556 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
6557 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
6558 * This is the approach that Babel will probably take to implement private methods/fields
6559 * https://github.com/tc39/proposal-private-methods
6560 * https://github.com/babel/babel/pull/7555
6561 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
6562 * then we can use that language feature.
6563 */
6564
6565 var privateMethods = {
6566 swalPromiseResolve: new WeakMap(),
6567 swalPromiseReject: new WeakMap()
6568 };
6569
6570 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
6571 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
6572 // elements not within the active modal dialog will not be surfaced if a user opens a screen
6573 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
6574
6575 const setAriaHidden = () => {
6576 const container = getContainer();
6577 const bodyChildren = Array.from(document.body.children);
6578 bodyChildren.forEach(el => {
6579 if (el.contains(container)) {
6580 return;
6581 }
6582 if (el.hasAttribute('aria-hidden')) {
6583 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
6584 }
6585 el.setAttribute('aria-hidden', 'true');
6586 });
6587 };
6588 const unsetAriaHidden = () => {
6589 const bodyChildren = Array.from(document.body.children);
6590 bodyChildren.forEach(el => {
6591 if (el.hasAttribute('data-previous-aria-hidden')) {
6592 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
6593 el.removeAttribute('data-previous-aria-hidden');
6594 } else {
6595 el.removeAttribute('aria-hidden');
6596 }
6597 });
6598 };
6599
6600 // @ts-ignore
6601 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
6602
6603 // @ts-ignore
6604 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
6605
6606 /**
6607 * Fix iOS scrolling
6608 * http://stackoverflow.com/q/39626302
6609 */
6610 const iOSfix = () => {
6611 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
6612 const offset = document.body.scrollTop;
6613 document.body.style.top = `${offset * -1}px`;
6614 addClass(document.body, swalClasses.iosfix);
6615 lockBodyScroll();
6616 }
6617 };
6618
6619 /**
6620 * https://github.com/sweetalert2/sweetalert2/issues/1246
6621 */
6622 const lockBodyScroll = () => {
6623 const container = getContainer();
6624 if (!container) {
6625 return;
6626 }
6627 /** @type {boolean} */
6628 let preventTouchMove;
6629 /**
6630 * @param {TouchEvent} event
6631 */
6632 container.ontouchstart = event => {
6633 preventTouchMove = shouldPreventTouchMove(event);
6634 };
6635 /**
6636 * @param {TouchEvent} event
6637 */
6638 container.ontouchmove = event => {
6639 if (preventTouchMove) {
6640 event.preventDefault();
6641 event.stopPropagation();
6642 }
6643 };
6644 };
6645
6646 /**
6647 * @param {TouchEvent} event
6648 * @returns {boolean}
6649 */
6650 const shouldPreventTouchMove = event => {
6651 const target = event.target;
6652 const container = getContainer();
6653 const htmlContainer = getHtmlContainer();
6654 if (!container || !htmlContainer) {
6655 return false;
6656 }
6657 if (isStylus(event) || isZoom(event)) {
6658 return false;
6659 }
6660 if (target === container) {
6661 return true;
6662 }
6663 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
6664 // #2823
6665 target.tagName !== 'INPUT' &&
6666 // #1603
6667 target.tagName !== 'TEXTAREA' &&
6668 // #2266
6669 !(isScrollable(htmlContainer) &&
6670 // #1944
6671 htmlContainer.contains(target))) {
6672 return true;
6673 }
6674 return false;
6675 };
6676
6677 /**
6678 * https://github.com/sweetalert2/sweetalert2/issues/1786
6679 *
6680 * @param {TouchEvent} event
6681 * @returns {boolean}
6682 */
6683 const isStylus = event => {
6684 return Boolean(event.touches && event.touches.length &&
6685 // @ts-ignore - touchType is not a standard property
6686 event.touches[0].touchType === 'stylus');
6687 };
6688
6689 /**
6690 * https://github.com/sweetalert2/sweetalert2/issues/1891
6691 *
6692 * @param {TouchEvent} event
6693 * @returns {boolean}
6694 */
6695 const isZoom = event => {
6696 return event.touches && event.touches.length > 1;
6697 };
6698 const undoIOSfix = () => {
6699 if (hasClass(document.body, swalClasses.iosfix)) {
6700 const offset = parseInt(document.body.style.top, 10);
6701 removeClass(document.body, swalClasses.iosfix);
6702 document.body.style.top = '';
6703 document.body.scrollTop = offset * -1;
6704 }
6705 };
6706
6707 /**
6708 * Measure scrollbar width for padding body during modal show/hide
6709 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
6710 *
6711 * @returns {number}
6712 */
6713 const measureScrollbar = () => {
6714 const scrollDiv = document.createElement('div');
6715 scrollDiv.className = swalClasses['scrollbar-measure'];
6716 document.body.appendChild(scrollDiv);
6717 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
6718 document.body.removeChild(scrollDiv);
6719 return scrollbarWidth;
6720 };
6721
6722 /**
6723 * Remember state in cases where opening and handling a modal will fiddle with it.
6724 * @type {number | null}
6725 */
6726 let previousBodyPadding = null;
6727
6728 /**
6729 * @param {string} initialBodyOverflow
6730 */
6731 const replaceScrollbarWithPadding = initialBodyOverflow => {
6732 // for queues, do not do this more than once
6733 if (previousBodyPadding !== null) {
6734 return;
6735 }
6736 // if the body has overflow
6737 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
6738 ) {
6739 // add padding so the content doesn't shift after removal of scrollbar
6740 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
6741 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
6742 }
6743 };
6744 const undoReplaceScrollbarWithPadding = () => {
6745 if (previousBodyPadding !== null) {
6746 document.body.style.paddingRight = `${previousBodyPadding}px`;
6747 previousBodyPadding = null;
6748 }
6749 };
6750
6751 /**
6752 * @param {SweetAlert} instance
6753 * @param {HTMLElement} container
6754 * @param {boolean} returnFocus
6755 * @param {(() => void) | undefined} didClose
6756 */
6757 function removePopupAndResetState(instance, container, returnFocus, didClose) {
6758 if (isToast()) {
6759 triggerDidCloseAndDispose(instance, didClose);
6760 } else {
6761 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
6762 removeKeydownHandler(globalState);
6763 }
6764
6765 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
6766 // for some reason removing the container in Safari will scroll the document to bottom
6767 if (isSafariOrIOS) {
6768 container.setAttribute('style', 'display:none !important');
6769 container.removeAttribute('class');
6770 container.innerHTML = '';
6771 } else {
6772 container.remove();
6773 }
6774 if (isModal()) {
6775 undoReplaceScrollbarWithPadding();
6776 undoIOSfix();
6777 unsetAriaHidden();
6778 }
6779 removeBodyClasses();
6780 }
6781
6782 /**
6783 * Remove SweetAlert2 classes from body
6784 */
6785 function removeBodyClasses() {
6786 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
6787 }
6788
6789 /**
6790 * Instance method to close sweetAlert
6791 *
6792 * @param {SweetAlertResult | undefined} resolveValue
6793 * @this {SweetAlert}
6794 */
6795 function close(resolveValue) {
6796 resolveValue = prepareResolveValue(resolveValue);
6797 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
6798 const didClose = triggerClosePopup(this);
6799 if (this.isAwaitingPromise) {
6800 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
6801 if (!resolveValue.isDismissed) {
6802 handleAwaitingPromise(this);
6803 swalPromiseResolve(resolveValue);
6804 }
6805 } else if (didClose) {
6806 // Resolve Swal promise
6807 swalPromiseResolve(resolveValue);
6808 }
6809 }
6810
6811 /**
6812 * @param {SweetAlert} instance
6813 * @returns {boolean}
6814 */
6815 const triggerClosePopup = instance => {
6816 const popup = getPopup();
6817 if (!popup) {
6818 return false;
6819 }
6820 const innerParams = privateProps.innerParams.get(instance);
6821 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
6822 return false;
6823 }
6824 removeClass(popup, innerParams.showClass.popup);
6825 addClass(popup, innerParams.hideClass.popup);
6826 const backdrop = getContainer();
6827 removeClass(backdrop, innerParams.showClass.backdrop);
6828 addClass(backdrop, innerParams.hideClass.backdrop);
6829 handlePopupAnimation(instance, popup, innerParams);
6830 return true;
6831 };
6832
6833 /**
6834 * @param {Error | string} error
6835 * @this {SweetAlert}
6836 */
6837 function rejectPromise(error) {
6838 const rejectPromise = privateMethods.swalPromiseReject.get(this);
6839 handleAwaitingPromise(this);
6840 if (rejectPromise) {
6841 // Reject Swal promise
6842 rejectPromise(error);
6843 }
6844 }
6845
6846 /**
6847 * @param {SweetAlert} instance
6848 */
6849 const handleAwaitingPromise = instance => {
6850 if (instance.isAwaitingPromise) {
6851 // @ts-ignore
6852 delete instance.isAwaitingPromise;
6853 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
6854 if (!privateProps.innerParams.get(instance)) {
6855 instance._destroy();
6856 }
6857 }
6858 };
6859
6860 /**
6861 * @param {SweetAlertResult | undefined} resolveValue
6862 * @returns {SweetAlertResult}
6863 */
6864 const prepareResolveValue = resolveValue => {
6865 // When user calls Swal.close()
6866 if (typeof resolveValue === 'undefined') {
6867 return {
6868 isConfirmed: false,
6869 isDenied: false,
6870 isDismissed: true
6871 };
6872 }
6873 return Object.assign({
6874 isConfirmed: false,
6875 isDenied: false,
6876 isDismissed: false
6877 }, resolveValue);
6878 };
6879
6880 /**
6881 * @param {SweetAlert} instance
6882 * @param {HTMLElement} popup
6883 * @param {SweetAlertOptions} innerParams
6884 */
6885 const handlePopupAnimation = (instance, popup, innerParams) => {
6886 var _globalState$eventEmi;
6887 const container = getContainer();
6888 // If animation is supported, animate
6889 const animationIsSupported = hasCssAnimation(popup);
6890 if (typeof innerParams.willClose === 'function') {
6891 innerParams.willClose(popup);
6892 }
6893 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
6894 if (animationIsSupported && container) {
6895 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
6896 } else if (container) {
6897 // Otherwise, remove immediately
6898 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
6899 }
6900 };
6901
6902 /**
6903 * @param {SweetAlert} instance
6904 * @param {HTMLElement} popup
6905 * @param {HTMLElement} container
6906 * @param {boolean} returnFocus
6907 * @param {(() => void) | undefined} didClose
6908 */
6909 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
6910 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
6911 /**
6912 * @param {AnimationEvent | TransitionEvent} e
6913 */
6914 const swalCloseAnimationFinished = function (e) {
6915 if (e.target === popup) {
6916 var _globalState$swalClos;
6917 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
6918 delete globalState.swalCloseEventFinishedCallback;
6919 popup.removeEventListener('animationend', swalCloseAnimationFinished);
6920 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
6921 }
6922 };
6923 popup.addEventListener('animationend', swalCloseAnimationFinished);
6924 popup.addEventListener('transitionend', swalCloseAnimationFinished);
6925 };
6926
6927 /**
6928 * @param {SweetAlert} instance
6929 * @param {(() => void) | undefined} didClose
6930 */
6931 const triggerDidCloseAndDispose = (instance, didClose) => {
6932 setTimeout(() => {
6933 var _globalState$eventEmi2;
6934 if (typeof didClose === 'function') {
6935 didClose.bind(instance.params)();
6936 }
6937 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
6938 // instance might have been destroyed already
6939 if (instance._destroy) {
6940 instance._destroy();
6941 }
6942 });
6943 };
6944
6945 /**
6946 * Shows loader (spinner), this is useful with AJAX requests.
6947 * By default the loader be shown instead of the "Confirm" button.
6948 *
6949 * @param {HTMLButtonElement | null} [buttonToReplace]
6950 */
6951 const showLoading = buttonToReplace => {
6952 let popup = getPopup();
6953 if (!popup) {
6954 new Swal();
6955 }
6956 popup = getPopup();
6957 if (!popup) {
6958 return;
6959 }
6960 const loader = getLoader();
6961 if (isToast()) {
6962 hide(getIcon());
6963 } else {
6964 replaceButton(popup, buttonToReplace);
6965 }
6966 show(loader);
6967 popup.setAttribute('data-loading', 'true');
6968 popup.setAttribute('aria-busy', 'true');
6969 popup.focus();
6970 };
6971
6972 /**
6973 * @param {HTMLElement} popup
6974 * @param {HTMLButtonElement | null} [buttonToReplace]
6975 */
6976 const replaceButton = (popup, buttonToReplace) => {
6977 const actions = getActions();
6978 const loader = getLoader();
6979 if (!actions || !loader) {
6980 return;
6981 }
6982 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
6983 buttonToReplace = getConfirmButton();
6984 }
6985 show(actions);
6986 if (buttonToReplace) {
6987 hide(buttonToReplace);
6988 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
6989 actions.insertBefore(loader, buttonToReplace);
6990 }
6991 addClass([popup, actions], swalClasses.loading);
6992 };
6993
6994 /**
6995 * @param {SweetAlert} instance
6996 * @param {SweetAlertOptions} params
6997 */
6998 const handleInputOptionsAndValue = (instance, params) => {
6999 if (params.input === 'select' || params.input === 'radio') {
7000 handleInputOptions(instance, params);
7001 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
7002 showLoading(getConfirmButton());
7003 handleInputValue(instance, params);
7004 }
7005 };
7006
7007 /**
7008 * @param {SweetAlert} instance
7009 * @param {SweetAlertOptions} innerParams
7010 * @returns {SweetAlertInputValue}
7011 */
7012 const getInputValue = (instance, innerParams) => {
7013 const input = instance.getInput();
7014 if (!input) {
7015 return null;
7016 }
7017 switch (innerParams.input) {
7018 case 'checkbox':
7019 return getCheckboxValue(input);
7020 case 'radio':
7021 return getRadioValue(input);
7022 case 'file':
7023 return getFileValue(input);
7024 default:
7025 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
7026 }
7027 };
7028
7029 /**
7030 * @param {HTMLInputElement} input
7031 * @returns {number}
7032 */
7033 const getCheckboxValue = input => input.checked ? 1 : 0;
7034
7035 /**
7036 * @param {HTMLInputElement} input
7037 * @returns {string | null}
7038 */
7039 const getRadioValue = input => input.checked ? input.value : null;
7040
7041 /**
7042 * @param {HTMLInputElement} input
7043 * @returns {FileList | File | null}
7044 */
7045 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
7046
7047 /**
7048 * @param {SweetAlert} instance
7049 * @param {SweetAlertOptions} params
7050 */
7051 const handleInputOptions = (instance, params) => {
7052 const popup = getPopup();
7053 if (!popup) {
7054 return;
7055 }
7056 /**
7057 * @param {*} inputOptions
7058 */
7059 const processInputOptions = inputOptions => {
7060 if (params.input === 'select') {
7061 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
7062 } else if (params.input === 'radio') {
7063 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
7064 }
7065 };
7066 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
7067 showLoading(getConfirmButton());
7068 asPromise(params.inputOptions).then(inputOptions => {
7069 instance.hideLoading();
7070 processInputOptions(inputOptions);
7071 });
7072 } else if (typeof params.inputOptions === 'object') {
7073 processInputOptions(params.inputOptions);
7074 } else {
7075 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
7076 }
7077 };
7078
7079 /**
7080 * @param {SweetAlert} instance
7081 * @param {SweetAlertOptions} params
7082 */
7083 const handleInputValue = (instance, params) => {
7084 const input = instance.getInput();
7085 if (!input) {
7086 return;
7087 }
7088 hide(input);
7089 asPromise(params.inputValue).then(inputValue => {
7090 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
7091 show(input);
7092 input.focus();
7093 instance.hideLoading();
7094 }).catch(err => {
7095 error(`Error in inputValue promise: ${err}`);
7096 input.value = '';
7097 show(input);
7098 input.focus();
7099 instance.hideLoading();
7100 });
7101 };
7102
7103 /**
7104 * @param {HTMLElement} popup
7105 * @param {InputOptionFlattened[]} inputOptions
7106 * @param {SweetAlertOptions} params
7107 */
7108 function populateSelectOptions(popup, inputOptions, params) {
7109 const select = getDirectChildByClass(popup, swalClasses.select);
7110 if (!select) {
7111 return;
7112 }
7113 /**
7114 * @param {HTMLElement} parent
7115 * @param {string} optionLabel
7116 * @param {string} optionValue
7117 */
7118 const renderOption = (parent, optionLabel, optionValue) => {
7119 const option = document.createElement('option');
7120 option.value = optionValue;
7121 setInnerHtml(option, optionLabel);
7122 option.selected = isSelected(optionValue, params.inputValue);
7123 parent.appendChild(option);
7124 };
7125 inputOptions.forEach(inputOption => {
7126 const optionValue = inputOption[0];
7127 const optionLabel = inputOption[1];
7128 // <optgroup> spec:
7129 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
7130 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
7131 // check whether this is a <optgroup>
7132 if (Array.isArray(optionLabel)) {
7133 // if it is an array, then it is an <optgroup>
7134 const optgroup = document.createElement('optgroup');
7135 optgroup.label = optionValue;
7136 optgroup.disabled = false; // not configurable for now
7137 select.appendChild(optgroup);
7138 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
7139 } else {
7140 // case of <option>
7141 renderOption(select, optionLabel, optionValue);
7142 }
7143 });
7144 select.focus();
7145 }
7146
7147 /**
7148 * @param {HTMLElement} popup
7149 * @param {InputOptionFlattened[]} inputOptions
7150 * @param {SweetAlertOptions} params
7151 */
7152 function populateRadioOptions(popup, inputOptions, params) {
7153 const radio = getDirectChildByClass(popup, swalClasses.radio);
7154 if (!radio) {
7155 return;
7156 }
7157 inputOptions.forEach(inputOption => {
7158 const radioValue = inputOption[0];
7159 const radioLabel = inputOption[1];
7160 const radioInput = document.createElement('input');
7161 const radioLabelElement = document.createElement('label');
7162 radioInput.type = 'radio';
7163 radioInput.name = swalClasses.radio;
7164 radioInput.value = radioValue;
7165 if (isSelected(radioValue, params.inputValue)) {
7166 radioInput.checked = true;
7167 }
7168 const label = document.createElement('span');
7169 setInnerHtml(label, radioLabel);
7170 label.className = swalClasses.label;
7171 radioLabelElement.appendChild(radioInput);
7172 radioLabelElement.appendChild(label);
7173 radio.appendChild(radioLabelElement);
7174 });
7175 const radios = radio.querySelectorAll('input');
7176 if (radios.length) {
7177 radios[0].focus();
7178 }
7179 }
7180
7181 /**
7182 * Converts `inputOptions` into an array of `[value, label]`s
7183 *
7184 * @param {*} inputOptions
7185 * @typedef {string[]} InputOptionFlattened
7186 * @returns {InputOptionFlattened[]}
7187 */
7188 const formatInputOptions = inputOptions => {
7189 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
7190 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
7191 };
7192
7193 /**
7194 * @param {string} optionValue
7195 * @param {SweetAlertInputValue} inputValue
7196 * @returns {boolean}
7197 */
7198 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
7199
7200 /**
7201 * @param {SweetAlert} instance
7202 */
7203 const handleConfirmButtonClick = instance => {
7204 const innerParams = privateProps.innerParams.get(instance);
7205 instance.disableButtons();
7206 if (innerParams.input) {
7207 handleConfirmOrDenyWithInput(instance, 'confirm');
7208 } else {
7209 confirm(instance, true);
7210 }
7211 };
7212
7213 /**
7214 * @param {SweetAlert} instance
7215 */
7216 const handleDenyButtonClick = instance => {
7217 const innerParams = privateProps.innerParams.get(instance);
7218 instance.disableButtons();
7219 if (innerParams.returnInputValueOnDeny) {
7220 handleConfirmOrDenyWithInput(instance, 'deny');
7221 } else {
7222 deny(instance, false);
7223 }
7224 };
7225
7226 /**
7227 * @param {SweetAlert} instance
7228 * @param {(dismiss: DismissReason) => void} dismissWith
7229 */
7230 const handleCancelButtonClick = (instance, dismissWith) => {
7231 instance.disableButtons();
7232 dismissWith(DismissReason.cancel);
7233 };
7234
7235 /**
7236 * @param {SweetAlert} instance
7237 * @param {'confirm' | 'deny'} type
7238 */
7239 const handleConfirmOrDenyWithInput = (instance, type) => {
7240 const innerParams = privateProps.innerParams.get(instance);
7241 if (!innerParams.input) {
7242 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
7243 return;
7244 }
7245 const input = instance.getInput();
7246 const inputValue = getInputValue(instance, innerParams);
7247 if (innerParams.inputValidator) {
7248 handleInputValidator(instance, inputValue, type);
7249 } else if (input && !input.checkValidity()) {
7250 instance.enableButtons();
7251 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
7252 } else if (type === 'deny') {
7253 deny(instance, inputValue);
7254 } else {
7255 confirm(instance, inputValue);
7256 }
7257 };
7258
7259 /**
7260 * @param {SweetAlert} instance
7261 * @param {SweetAlertInputValue} inputValue
7262 * @param {'confirm' | 'deny'} type
7263 */
7264 const handleInputValidator = (instance, inputValue, type) => {
7265 const innerParams = privateProps.innerParams.get(instance);
7266 instance.disableInput();
7267 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
7268 validationPromise.then(validationMessage => {
7269 instance.enableButtons();
7270 instance.enableInput();
7271 if (validationMessage) {
7272 instance.showValidationMessage(validationMessage);
7273 } else if (type === 'deny') {
7274 deny(instance, inputValue);
7275 } else {
7276 confirm(instance, inputValue);
7277 }
7278 });
7279 };
7280
7281 /**
7282 * @param {SweetAlert} instance
7283 * @param {*} value
7284 */
7285 const deny = (instance, value) => {
7286 const innerParams = privateProps.innerParams.get(instance);
7287 if (innerParams.showLoaderOnDeny) {
7288 showLoading(getDenyButton());
7289 }
7290 if (innerParams.preDeny) {
7291 instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preDeny's promise is received
7292 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
7293 preDenyPromise.then(preDenyValue => {
7294 if (preDenyValue === false) {
7295 instance.hideLoading();
7296 handleAwaitingPromise(instance);
7297 } else {
7298 instance.close(/** @type SweetAlertResult */{
7299 isDenied: true,
7300 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
7301 });
7302 }
7303 }).catch(error => rejectWith(instance, error));
7304 } else {
7305 instance.close(/** @type SweetAlertResult */{
7306 isDenied: true,
7307 value
7308 });
7309 }
7310 };
7311
7312 /**
7313 * @param {SweetAlert} instance
7314 * @param {*} value
7315 */
7316 const succeedWith = (instance, value) => {
7317 instance.close(/** @type SweetAlertResult */{
7318 isConfirmed: true,
7319 value
7320 });
7321 };
7322
7323 /**
7324 *
7325 * @param {SweetAlert} instance
7326 * @param {string} error
7327 */
7328 const rejectWith = (instance, error) => {
7329 instance.rejectPromise(error);
7330 };
7331
7332 /**
7333 *
7334 * @param {SweetAlert} instance
7335 * @param {*} value
7336 */
7337 const confirm = (instance, value) => {
7338 const innerParams = privateProps.innerParams.get(instance);
7339 if (innerParams.showLoaderOnConfirm) {
7340 showLoading();
7341 }
7342 if (innerParams.preConfirm) {
7343 instance.resetValidationMessage();
7344 instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preConfirm's promise is received
7345 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
7346 preConfirmPromise.then(preConfirmValue => {
7347 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
7348 instance.hideLoading();
7349 handleAwaitingPromise(instance);
7350 } else {
7351 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
7352 }
7353 }).catch(error => rejectWith(instance, error));
7354 } else {
7355 succeedWith(instance, value);
7356 }
7357 };
7358
7359 /**
7360 * Hides loader and shows back the button which was hidden by .showLoading()
7361 * @this {SweetAlert}
7362 */
7363 function hideLoading() {
7364 // do nothing if popup is closed
7365 const innerParams = privateProps.innerParams.get(this);
7366 if (!innerParams) {
7367 return;
7368 }
7369 const domCache = privateProps.domCache.get(this);
7370 hide(domCache.loader);
7371 if (isToast()) {
7372 if (innerParams.icon) {
7373 show(getIcon());
7374 }
7375 } else {
7376 showRelatedButton(domCache);
7377 }
7378 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
7379 domCache.popup.removeAttribute('aria-busy');
7380 domCache.popup.removeAttribute('data-loading');
7381 this.enableButtons();
7382 }
7383
7384 /**
7385 * @param {DomCache} domCache
7386 */
7387 const showRelatedButton = domCache => {
7388 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
7389 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
7390 if (buttonToReplace.length) {
7391 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
7392 } else if (allButtonsAreHidden()) {
7393 hide(domCache.actions);
7394 }
7395 };
7396
7397 /**
7398 * Gets the input DOM node, this method works with input parameter.
7399 *
7400 * @returns {HTMLInputElement | null}
7401 * @this {SweetAlert}
7402 */
7403 function getInput() {
7404 const innerParams = privateProps.innerParams.get(this);
7405 const domCache = privateProps.domCache.get(this);
7406 if (!domCache) {
7407 return null;
7408 }
7409 return getInput$1(domCache.popup, innerParams.input);
7410 }
7411
7412 /**
7413 * @param {SweetAlert} instance
7414 * @param {string[]} buttons
7415 * @param {boolean} disabled
7416 */
7417 function setButtonsDisabled(instance, buttons, disabled) {
7418 const domCache = privateProps.domCache.get(instance);
7419 buttons.forEach(button => {
7420 domCache[button].disabled = disabled;
7421 });
7422 }
7423
7424 /**
7425 * @param {HTMLInputElement | null} input
7426 * @param {boolean} disabled
7427 */
7428 function setInputDisabled(input, disabled) {
7429 const popup = getPopup();
7430 if (!popup || !input) {
7431 return;
7432 }
7433 if (input.type === 'radio') {
7434 /** @type {NodeListOf<HTMLInputElement>} */
7435 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
7436 radios.forEach(radio => {
7437 radio.disabled = disabled;
7438 });
7439 } else {
7440 input.disabled = disabled;
7441 }
7442 }
7443
7444 /**
7445 * Enable all the buttons
7446 * @this {SweetAlert}
7447 */
7448 function enableButtons() {
7449 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
7450 const focusedElement = privateProps.focusedElement.get(this);
7451 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
7452 focusedElement.focus();
7453 }
7454 privateProps.focusedElement.delete(this);
7455 }
7456
7457 /**
7458 * Disable all the buttons
7459 * @this {SweetAlert}
7460 */
7461 function disableButtons() {
7462 privateProps.focusedElement.set(this, document.activeElement);
7463 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
7464 }
7465
7466 /**
7467 * Enable the input field
7468 * @this {SweetAlert}
7469 */
7470 function enableInput() {
7471 setInputDisabled(this.getInput(), false);
7472 }
7473
7474 /**
7475 * Disable the input field
7476 * @this {SweetAlert}
7477 */
7478 function disableInput() {
7479 setInputDisabled(this.getInput(), true);
7480 }
7481
7482 /**
7483 * Show block with validation message
7484 *
7485 * @param {string} error
7486 * @this {SweetAlert}
7487 */
7488 function showValidationMessage(error) {
7489 const domCache = privateProps.domCache.get(this);
7490 const params = privateProps.innerParams.get(this);
7491 setInnerHtml(domCache.validationMessage, error);
7492 domCache.validationMessage.className = swalClasses['validation-message'];
7493 if (params.customClass && params.customClass.validationMessage) {
7494 addClass(domCache.validationMessage, params.customClass.validationMessage);
7495 }
7496 show(domCache.validationMessage);
7497 const input = this.getInput();
7498 if (input) {
7499 input.setAttribute('aria-invalid', 'true');
7500 input.setAttribute('aria-describedby', swalClasses['validation-message']);
7501 focusInput(input);
7502 addClass(input, swalClasses.inputerror);
7503 }
7504 }
7505
7506 /**
7507 * Hide block with validation message
7508 *
7509 * @this {SweetAlert}
7510 */
7511 function resetValidationMessage() {
7512 const domCache = privateProps.domCache.get(this);
7513 if (domCache.validationMessage) {
7514 hide(domCache.validationMessage);
7515 }
7516 const input = this.getInput();
7517 if (input) {
7518 input.removeAttribute('aria-invalid');
7519 input.removeAttribute('aria-describedby');
7520 removeClass(input, swalClasses.inputerror);
7521 }
7522 }
7523
7524 const defaultParams = {
7525 title: '',
7526 titleText: '',
7527 text: '',
7528 html: '',
7529 footer: '',
7530 icon: undefined,
7531 iconColor: undefined,
7532 iconHtml: undefined,
7533 template: undefined,
7534 toast: false,
7535 draggable: false,
7536 animation: true,
7537 theme: 'light',
7538 showClass: {
7539 popup: 'swal2-show',
7540 backdrop: 'swal2-backdrop-show',
7541 icon: 'swal2-icon-show'
7542 },
7543 hideClass: {
7544 popup: 'swal2-hide',
7545 backdrop: 'swal2-backdrop-hide',
7546 icon: 'swal2-icon-hide'
7547 },
7548 customClass: {},
7549 target: 'body',
7550 color: undefined,
7551 backdrop: true,
7552 heightAuto: true,
7553 allowOutsideClick: true,
7554 allowEscapeKey: true,
7555 allowEnterKey: true,
7556 stopKeydownPropagation: true,
7557 keydownListenerCapture: false,
7558 showConfirmButton: true,
7559 showDenyButton: false,
7560 showCancelButton: false,
7561 preConfirm: undefined,
7562 preDeny: undefined,
7563 confirmButtonText: 'OK',
7564 confirmButtonAriaLabel: '',
7565 confirmButtonColor: undefined,
7566 denyButtonText: 'No',
7567 denyButtonAriaLabel: '',
7568 denyButtonColor: undefined,
7569 cancelButtonText: 'Cancel',
7570 cancelButtonAriaLabel: '',
7571 cancelButtonColor: undefined,
7572 buttonsStyling: true,
7573 reverseButtons: false,
7574 focusConfirm: true,
7575 focusDeny: false,
7576 focusCancel: false,
7577 returnFocus: true,
7578 showCloseButton: false,
7579 closeButtonHtml: '&times;',
7580 closeButtonAriaLabel: 'Close this dialog',
7581 loaderHtml: '',
7582 showLoaderOnConfirm: false,
7583 showLoaderOnDeny: false,
7584 imageUrl: undefined,
7585 imageWidth: undefined,
7586 imageHeight: undefined,
7587 imageAlt: '',
7588 timer: undefined,
7589 timerProgressBar: false,
7590 width: undefined,
7591 padding: undefined,
7592 background: undefined,
7593 input: undefined,
7594 inputPlaceholder: '',
7595 inputLabel: '',
7596 inputValue: '',
7597 inputOptions: {},
7598 inputAutoFocus: true,
7599 inputAutoTrim: true,
7600 inputAttributes: {},
7601 inputValidator: undefined,
7602 returnInputValueOnDeny: false,
7603 validationMessage: undefined,
7604 grow: false,
7605 position: 'center',
7606 progressSteps: [],
7607 currentProgressStep: undefined,
7608 progressStepsDistance: undefined,
7609 willOpen: undefined,
7610 didOpen: undefined,
7611 didRender: undefined,
7612 willClose: undefined,
7613 didClose: undefined,
7614 didDestroy: undefined,
7615 scrollbarPadding: true,
7616 topLayer: false
7617 };
7618 const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'draggable', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'theme', 'willClose'];
7619
7620 /** @type {Record<string, string | undefined>} */
7621 const deprecatedParams = {
7622 allowEnterKey: undefined
7623 };
7624 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
7625
7626 /**
7627 * Is valid parameter
7628 *
7629 * @param {string} paramName
7630 * @returns {boolean}
7631 */
7632 const isValidParameter = paramName => {
7633 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
7634 };
7635
7636 /**
7637 * Is valid parameter for Swal.update() method
7638 *
7639 * @param {string} paramName
7640 * @returns {boolean}
7641 */
7642 const isUpdatableParameter = paramName => {
7643 return updatableParams.indexOf(paramName) !== -1;
7644 };
7645
7646 /**
7647 * Is deprecated parameter
7648 *
7649 * @param {string} paramName
7650 * @returns {string | undefined}
7651 */
7652 const isDeprecatedParameter = paramName => {
7653 return deprecatedParams[paramName];
7654 };
7655
7656 /**
7657 * @param {string} param
7658 */
7659 const checkIfParamIsValid = param => {
7660 if (!isValidParameter(param)) {
7661 warn(`Unknown parameter "${param}"`);
7662 }
7663 };
7664
7665 /**
7666 * @param {string} param
7667 */
7668 const checkIfToastParamIsValid = param => {
7669 if (toastIncompatibleParams.includes(param)) {
7670 warn(`The parameter "${param}" is incompatible with toasts`);
7671 }
7672 };
7673
7674 /**
7675 * @param {string} param
7676 */
7677 const checkIfParamIsDeprecated = param => {
7678 const isDeprecated = isDeprecatedParameter(param);
7679 if (isDeprecated) {
7680 warnAboutDeprecation(param, isDeprecated);
7681 }
7682 };
7683
7684 /**
7685 * Show relevant warnings for given params
7686 *
7687 * @param {SweetAlertOptions} params
7688 */
7689 const showWarningsForParams = params => {
7690 if (params.backdrop === false && params.allowOutsideClick) {
7691 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
7692 }
7693 if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'bootstrap-4', 'bootstrap-4-light', 'bootstrap-4-dark', 'bootstrap-5', 'bootstrap-5-light', 'bootstrap-5-dark', 'material-ui', 'material-ui-light', 'material-ui-dark', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
7694 warn(`Invalid theme "${params.theme}"`);
7695 }
7696 for (const param in params) {
7697 checkIfParamIsValid(param);
7698 if (params.toast) {
7699 checkIfToastParamIsValid(param);
7700 }
7701 checkIfParamIsDeprecated(param);
7702 }
7703 };
7704
7705 /**
7706 * Updates popup parameters.
7707 *
7708 * @this {any}
7709 * @param {SweetAlertOptions} params
7710 */
7711 function update(params) {
7712 const container = getContainer();
7713 const popup = getPopup();
7714 const innerParams = privateProps.innerParams.get(this);
7715 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
7716 warn(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`);
7717 return;
7718 }
7719 const validUpdatableParams = filterValidParams(params);
7720 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
7721 showWarningsForParams(updatedParams);
7722 if (container) {
7723 container.dataset['swal2Theme'] = updatedParams.theme;
7724 }
7725 render(this, updatedParams);
7726 privateProps.innerParams.set(this, updatedParams);
7727 Object.defineProperties(this, {
7728 params: {
7729 value: Object.assign({}, this.params, params),
7730 writable: false,
7731 enumerable: true
7732 }
7733 });
7734 }
7735
7736 /**
7737 * @param {SweetAlertOptions} params
7738 * @returns {SweetAlertOptions}
7739 */
7740 const filterValidParams = params => {
7741 /** @type {Record<string, any>} */
7742 const validUpdatableParams = {};
7743 Object.keys(params).forEach(param => {
7744 if (isUpdatableParameter(param)) {
7745 const typedParams = /** @type {Record<string, any>} */params;
7746 validUpdatableParams[param] = typedParams[param];
7747 } else {
7748 warn(`Invalid parameter to update: ${param}`);
7749 }
7750 });
7751 return validUpdatableParams;
7752 };
7753
7754 /**
7755 * Dispose the current SweetAlert2 instance
7756 * @this {SweetAlert}
7757 */
7758 function _destroy() {
7759 var _globalState$eventEmi;
7760 const domCache = privateProps.domCache.get(this);
7761 const innerParams = privateProps.innerParams.get(this);
7762 if (!innerParams) {
7763 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
7764 return; // This instance has already been destroyed
7765 }
7766
7767 // Check if there is another Swal closing
7768 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
7769 globalState.swalCloseEventFinishedCallback();
7770 delete globalState.swalCloseEventFinishedCallback;
7771 }
7772 if (typeof innerParams.didDestroy === 'function') {
7773 innerParams.didDestroy();
7774 }
7775 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
7776 disposeSwal(this);
7777 }
7778
7779 /**
7780 * @param {SweetAlert} instance
7781 */
7782 const disposeSwal = instance => {
7783 disposeWeakMaps(instance);
7784 // Unset this.params so GC will dispose it (#1569)
7785 // @ts-ignore
7786 delete instance.params;
7787 // Unset globalState props so GC will dispose globalState (#1569)
7788 delete globalState.keydownHandler;
7789 delete globalState.keydownTarget;
7790 // Unset currentInstance
7791 delete globalState.currentInstance;
7792 };
7793
7794 /**
7795 * @param {SweetAlert} instance
7796 */
7797 const disposeWeakMaps = instance => {
7798 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
7799 if (instance.isAwaitingPromise) {
7800 unsetWeakMaps(privateProps, instance);
7801 instance.isAwaitingPromise = true;
7802 } else {
7803 unsetWeakMaps(privateMethods, instance);
7804 unsetWeakMaps(privateProps, instance);
7805
7806 // @ts-ignore
7807 delete instance.isAwaitingPromise;
7808 // Unset instance methods
7809 // @ts-ignore
7810 delete instance.disableButtons;
7811 // @ts-ignore
7812 delete instance.enableButtons;
7813 // @ts-ignore
7814 delete instance.getInput;
7815 // @ts-ignore
7816 delete instance.disableInput;
7817 // @ts-ignore
7818 delete instance.enableInput;
7819 // @ts-ignore
7820 delete instance.hideLoading;
7821 // @ts-ignore
7822 delete instance.disableLoading;
7823 // @ts-ignore
7824 delete instance.showValidationMessage;
7825 // @ts-ignore
7826 delete instance.resetValidationMessage;
7827 // @ts-ignore
7828 delete instance.close;
7829 // @ts-ignore
7830 delete instance.closePopup;
7831 // @ts-ignore
7832 delete instance.closeModal;
7833 // @ts-ignore
7834 delete instance.closeToast;
7835 // @ts-ignore
7836 delete instance.rejectPromise;
7837 // @ts-ignore
7838 delete instance.update;
7839 // @ts-ignore
7840 delete instance._destroy;
7841 }
7842 };
7843
7844 /**
7845 * @param {Record<string, WeakMap<any, any>>} obj
7846 * @param {SweetAlert} instance
7847 */
7848 const unsetWeakMaps = (obj, instance) => {
7849 for (const i in obj) {
7850 obj[i].delete(instance);
7851 }
7852 };
7853
7854 var instanceMethods = /*#__PURE__*/Object.freeze({
7855 __proto__: null,
7856 _destroy: _destroy,
7857 close: close,
7858 closeModal: close,
7859 closePopup: close,
7860 closeToast: close,
7861 disableButtons: disableButtons,
7862 disableInput: disableInput,
7863 disableLoading: hideLoading,
7864 enableButtons: enableButtons,
7865 enableInput: enableInput,
7866 getInput: getInput,
7867 handleAwaitingPromise: handleAwaitingPromise,
7868 hideLoading: hideLoading,
7869 rejectPromise: rejectPromise,
7870 resetValidationMessage: resetValidationMessage,
7871 showValidationMessage: showValidationMessage,
7872 update: update
7873 });
7874
7875 /**
7876 * @param {SweetAlertOptions} innerParams
7877 * @param {DomCache} domCache
7878 * @param {(dismiss: DismissReason) => void} dismissWith
7879 */
7880 const handlePopupClick = (innerParams, domCache, dismissWith) => {
7881 if (innerParams.toast) {
7882 handleToastClick(innerParams, domCache, dismissWith);
7883 } else {
7884 // Ignore click events that had mousedown on the popup but mouseup on the container
7885 // This can happen when the user drags a slider
7886 handleModalMousedown(domCache);
7887
7888 // Ignore click events that had mousedown on the container but mouseup on the popup
7889 handleContainerMousedown(domCache);
7890 handleModalClick(innerParams, domCache, dismissWith);
7891 }
7892 };
7893
7894 /**
7895 * @param {SweetAlertOptions} innerParams
7896 * @param {DomCache} domCache
7897 * @param {(dismiss: DismissReason) => void} dismissWith
7898 */
7899 const handleToastClick = (innerParams, domCache, dismissWith) => {
7900 // Closing toast by internal click
7901 domCache.popup.onclick = () => {
7902 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
7903 return;
7904 }
7905 dismissWith(DismissReason.close);
7906 };
7907 };
7908
7909 /**
7910 * @param {SweetAlertOptions} innerParams
7911 * @returns {boolean}
7912 */
7913 const isAnyButtonShown = innerParams => {
7914 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
7915 };
7916 let ignoreOutsideClick = false;
7917
7918 /**
7919 * @param {DomCache} domCache
7920 */
7921 const handleModalMousedown = domCache => {
7922 domCache.popup.onmousedown = () => {
7923 domCache.container.onmouseup = function (e) {
7924 domCache.container.onmouseup = () => {};
7925 // We only check if the mouseup target is the container because usually it doesn't
7926 // have any other direct children aside of the popup
7927 if (e.target === domCache.container) {
7928 ignoreOutsideClick = true;
7929 }
7930 };
7931 };
7932 };
7933
7934 /**
7935 * @param {DomCache} domCache
7936 */
7937 const handleContainerMousedown = domCache => {
7938 domCache.container.onmousedown = e => {
7939 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
7940 if (e.target === domCache.container) {
7941 e.preventDefault();
7942 }
7943 domCache.popup.onmouseup = function (e) {
7944 domCache.popup.onmouseup = () => {};
7945 // We also need to check if the mouseup target is a child of the popup
7946 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
7947 ignoreOutsideClick = true;
7948 }
7949 };
7950 };
7951 };
7952
7953 /**
7954 * @param {SweetAlertOptions} innerParams
7955 * @param {DomCache} domCache
7956 * @param {(dismiss: DismissReason) => void} dismissWith
7957 */
7958 const handleModalClick = (innerParams, domCache, dismissWith) => {
7959 domCache.container.onclick = e => {
7960 if (ignoreOutsideClick) {
7961 ignoreOutsideClick = false;
7962 return;
7963 }
7964 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
7965 dismissWith(DismissReason.backdrop);
7966 }
7967 };
7968 };
7969
7970 /**
7971 * @param {unknown} elem
7972 * @returns {boolean}
7973 */
7974 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
7975
7976 /**
7977 * @param {unknown} elem
7978 * @returns {boolean}
7979 */
7980 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
7981
7982 /**
7983 * @param {ReadonlyArray<unknown>} args
7984 * @returns {SweetAlertOptions}
7985 */
7986 const argsToParams = args => {
7987 /** @type {Record<string, unknown>} */
7988 const params = {};
7989 if (typeof args[0] === 'object' && !isElement(args[0])) {
7990 Object.assign(params, args[0]);
7991 } else {
7992 ['title', 'html', 'icon'].forEach((name, index) => {
7993 const arg = args[index];
7994 if (typeof arg === 'string' || isElement(arg)) {
7995 params[name] = arg;
7996 } else if (arg !== undefined) {
7997 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
7998 }
7999 });
8000 }
8001 return /** @type {SweetAlertOptions} */params;
8002 };
8003
8004 /**
8005 * Main method to create a new SweetAlert2 popup
8006 *
8007 * @this {new (...args: any[]) => any}
8008 * @param {...SweetAlertOptions} args
8009 * @returns {Promise<SweetAlertResult>}
8010 */
8011 function fire(...args) {
8012 return new this(...args);
8013 }
8014
8015 /**
8016 * Returns an extended version of `Swal` containing `params` as defaults.
8017 * Useful for reusing Swal configuration.
8018 *
8019 * For example:
8020 *
8021 * Before:
8022 * const textPromptOptions = { input: 'text', showCancelButton: true }
8023 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
8024 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
8025 *
8026 * After:
8027 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
8028 * const {value: firstName} = await TextPrompt('What is your first name?')
8029 * const {value: lastName} = await TextPrompt('What is your last name?')
8030 *
8031 * @param {SweetAlertOptions} mixinParams
8032 * @returns {SweetAlert}
8033 * @this {typeof import('../SweetAlert.js').SweetAlert}
8034 */
8035 function mixin(mixinParams) {
8036 // @ts-ignore: 'this' refers to the SweetAlert constructor
8037 class MixinSwal extends this {
8038 /**
8039 * @param {any} params
8040 * @param {any} priorityMixinParams
8041 */
8042 _main(params, priorityMixinParams) {
8043 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
8044 }
8045 }
8046 // @ts-ignore
8047 return MixinSwal;
8048 }
8049
8050 /**
8051 * If `timer` parameter is set, returns number of milliseconds of timer remained.
8052 * Otherwise, returns undefined.
8053 *
8054 * @returns {number | undefined}
8055 */
8056 const getTimerLeft = () => {
8057 return globalState.timeout && globalState.timeout.getTimerLeft();
8058 };
8059
8060 /**
8061 * Stop timer. Returns number of milliseconds of timer remained.
8062 * If `timer` parameter isn't set, returns undefined.
8063 *
8064 * @returns {number | undefined}
8065 */
8066 const stopTimer = () => {
8067 if (globalState.timeout) {
8068 stopTimerProgressBar();
8069 return globalState.timeout.stop();
8070 }
8071 };
8072
8073 /**
8074 * Resume timer. Returns number of milliseconds of timer remained.
8075 * If `timer` parameter isn't set, returns undefined.
8076 *
8077 * @returns {number | undefined}
8078 */
8079 const resumeTimer = () => {
8080 if (globalState.timeout) {
8081 const remaining = globalState.timeout.start();
8082 animateTimerProgressBar(remaining);
8083 return remaining;
8084 }
8085 };
8086
8087 /**
8088 * Resume timer. Returns number of milliseconds of timer remained.
8089 * If `timer` parameter isn't set, returns undefined.
8090 *
8091 * @returns {number | undefined}
8092 */
8093 const toggleTimer = () => {
8094 const timer = globalState.timeout;
8095 return timer && (timer.running ? stopTimer() : resumeTimer());
8096 };
8097
8098 /**
8099 * Increase timer. Returns number of milliseconds of an updated timer.
8100 * If `timer` parameter isn't set, returns undefined.
8101 *
8102 * @param {number} ms
8103 * @returns {number | undefined}
8104 */
8105 const increaseTimer = ms => {
8106 if (globalState.timeout) {
8107 const remaining = globalState.timeout.increase(ms);
8108 animateTimerProgressBar(remaining, true);
8109 return remaining;
8110 }
8111 };
8112
8113 /**
8114 * Check if timer is running. Returns true if timer is running
8115 * or false if timer is paused or stopped.
8116 * If `timer` parameter isn't set, returns undefined
8117 *
8118 * @returns {boolean}
8119 */
8120 const isTimerRunning = () => {
8121 return Boolean(globalState.timeout && globalState.timeout.isRunning());
8122 };
8123
8124 let bodyClickListenerAdded = false;
8125 /** @type {Record<string, any>} */
8126 const clickHandlers = {};
8127
8128 /**
8129 * @this {any}
8130 * @param {string} attr
8131 */
8132 function bindClickHandler(attr = 'data-swal-template') {
8133 clickHandlers[attr] = this;
8134 if (!bodyClickListenerAdded) {
8135 document.body.addEventListener('click', bodyClickListener);
8136 bodyClickListenerAdded = true;
8137 }
8138 }
8139
8140 /**
8141 * @param {MouseEvent} event
8142 */
8143 const bodyClickListener = event => {
8144 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
8145 for (const attr in clickHandlers) {
8146 const template = el.getAttribute && el.getAttribute(attr);
8147 if (template) {
8148 clickHandlers[attr].fire({
8149 template
8150 });
8151 return;
8152 }
8153 }
8154 }
8155 };
8156
8157 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
8158
8159 class EventEmitter {
8160 constructor() {
8161 /** @type {Events} */
8162 this.events = {};
8163 }
8164
8165 /**
8166 * @param {string} eventName
8167 * @returns {EventHandlers}
8168 */
8169 _getHandlersByEventName(eventName) {
8170 if (typeof this.events[eventName] === 'undefined') {
8171 // not Set because we need to keep the FIFO order
8172 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
8173 this.events[eventName] = [];
8174 }
8175 return this.events[eventName];
8176 }
8177
8178 /**
8179 * @param {string} eventName
8180 * @param {EventHandler} eventHandler
8181 */
8182 on(eventName, eventHandler) {
8183 const currentHandlers = this._getHandlersByEventName(eventName);
8184 if (!currentHandlers.includes(eventHandler)) {
8185 currentHandlers.push(eventHandler);
8186 }
8187 }
8188
8189 /**
8190 * @param {string} eventName
8191 * @param {EventHandler} eventHandler
8192 */
8193 once(eventName, eventHandler) {
8194 /**
8195 * @param {...any} args
8196 */
8197 const onceFn = (...args) => {
8198 this.removeListener(eventName, onceFn);
8199 // @ts-ignore
8200 eventHandler.apply(this, args);
8201 };
8202 this.on(eventName, onceFn);
8203 }
8204
8205 /**
8206 * @param {string} eventName
8207 * @param {...any} args
8208 */
8209 emit(eventName, ...args) {
8210 this._getHandlersByEventName(eventName).forEach(
8211 /**
8212 * @param {EventHandler} eventHandler
8213 */
8214 eventHandler => {
8215 try {
8216 // @ts-ignore
8217 eventHandler.apply(this, args);
8218 } catch (error) {
8219 console.error(error);
8220 }
8221 });
8222 }
8223
8224 /**
8225 * @param {string} eventName
8226 * @param {EventHandler} eventHandler
8227 */
8228 removeListener(eventName, eventHandler) {
8229 const currentHandlers = this._getHandlersByEventName(eventName);
8230 const index = currentHandlers.indexOf(eventHandler);
8231 if (index > -1) {
8232 currentHandlers.splice(index, 1);
8233 }
8234 }
8235
8236 /**
8237 * @param {string} eventName
8238 */
8239 removeAllListeners(eventName) {
8240 if (this.events[eventName] !== undefined) {
8241 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
8242 this.events[eventName].length = 0;
8243 }
8244 }
8245 reset() {
8246 this.events = {};
8247 }
8248 }
8249
8250 globalState.eventEmitter = new EventEmitter();
8251
8252 /**
8253 * @param {string} eventName
8254 * @param {EventHandler} eventHandler
8255 */
8256 const on = (eventName, eventHandler) => {
8257 if (globalState.eventEmitter) {
8258 globalState.eventEmitter.on(eventName, eventHandler);
8259 }
8260 };
8261
8262 /**
8263 * @param {string} eventName
8264 * @param {EventHandler} eventHandler
8265 */
8266 const once = (eventName, eventHandler) => {
8267 if (globalState.eventEmitter) {
8268 globalState.eventEmitter.once(eventName, eventHandler);
8269 }
8270 };
8271
8272 /**
8273 * @param {string} [eventName]
8274 * @param {EventHandler} [eventHandler]
8275 */
8276 const off = (eventName, eventHandler) => {
8277 if (!globalState.eventEmitter) {
8278 return;
8279 }
8280
8281 // Remove all handlers for all events
8282 if (!eventName) {
8283 globalState.eventEmitter.reset();
8284 return;
8285 }
8286 if (eventHandler) {
8287 // Remove a specific handler
8288 globalState.eventEmitter.removeListener(eventName, eventHandler);
8289 } else {
8290 // Remove all handlers for a specific event
8291 globalState.eventEmitter.removeAllListeners(eventName);
8292 }
8293 };
8294
8295 var staticMethods = /*#__PURE__*/Object.freeze({
8296 __proto__: null,
8297 argsToParams: argsToParams,
8298 bindClickHandler: bindClickHandler,
8299 clickCancel: clickCancel,
8300 clickConfirm: clickConfirm,
8301 clickDeny: clickDeny,
8302 enableLoading: showLoading,
8303 fire: fire,
8304 getActions: getActions,
8305 getCancelButton: getCancelButton,
8306 getCloseButton: getCloseButton,
8307 getConfirmButton: getConfirmButton,
8308 getContainer: getContainer,
8309 getDenyButton: getDenyButton,
8310 getFocusableElements: getFocusableElements,
8311 getFooter: getFooter,
8312 getHtmlContainer: getHtmlContainer,
8313 getIcon: getIcon,
8314 getIconContent: getIconContent,
8315 getImage: getImage,
8316 getInputLabel: getInputLabel,
8317 getLoader: getLoader,
8318 getPopup: getPopup,
8319 getProgressSteps: getProgressSteps,
8320 getTimerLeft: getTimerLeft,
8321 getTimerProgressBar: getTimerProgressBar,
8322 getTitle: getTitle,
8323 getValidationMessage: getValidationMessage,
8324 increaseTimer: increaseTimer,
8325 isDeprecatedParameter: isDeprecatedParameter,
8326 isLoading: isLoading,
8327 isTimerRunning: isTimerRunning,
8328 isUpdatableParameter: isUpdatableParameter,
8329 isValidParameter: isValidParameter,
8330 isVisible: isVisible,
8331 mixin: mixin,
8332 off: off,
8333 on: on,
8334 once: once,
8335 resumeTimer: resumeTimer,
8336 showLoading: showLoading,
8337 stopTimer: stopTimer,
8338 toggleTimer: toggleTimer
8339 });
8340
8341 class Timer {
8342 /**
8343 * @param {() => void} callback
8344 * @param {number} delay
8345 */
8346 constructor(callback, delay) {
8347 this.callback = callback;
8348 this.remaining = delay;
8349 this.running = false;
8350 this.start();
8351 }
8352
8353 /**
8354 * @returns {number}
8355 */
8356 start() {
8357 if (!this.running) {
8358 this.running = true;
8359 this.started = new Date();
8360 this.id = setTimeout(this.callback, this.remaining);
8361 }
8362 return this.remaining;
8363 }
8364
8365 /**
8366 * @returns {number}
8367 */
8368 stop() {
8369 if (this.started && this.running) {
8370 this.running = false;
8371 clearTimeout(this.id);
8372 this.remaining -= new Date().getTime() - this.started.getTime();
8373 }
8374 return this.remaining;
8375 }
8376
8377 /**
8378 * @param {number} n
8379 * @returns {number}
8380 */
8381 increase(n) {
8382 const running = this.running;
8383 if (running) {
8384 this.stop();
8385 }
8386 this.remaining += n;
8387 if (running) {
8388 this.start();
8389 }
8390 return this.remaining;
8391 }
8392
8393 /**
8394 * @returns {number}
8395 */
8396 getTimerLeft() {
8397 if (this.running) {
8398 this.stop();
8399 this.start();
8400 }
8401 return this.remaining;
8402 }
8403
8404 /**
8405 * @returns {boolean}
8406 */
8407 isRunning() {
8408 return this.running;
8409 }
8410 }
8411
8412 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
8413
8414 /**
8415 * @param {SweetAlertOptions} params
8416 * @returns {SweetAlertOptions}
8417 */
8418 const getTemplateParams = params => {
8419 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
8420 if (!template) {
8421 return {};
8422 }
8423 /** @type {DocumentFragment} */
8424 const templateContent = template.content;
8425 showWarningsForElements(templateContent);
8426 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
8427 return result;
8428 };
8429
8430 /**
8431 * @param {DocumentFragment} templateContent
8432 * @returns {Record<string, string | boolean | number>}
8433 */
8434 const getSwalParams = templateContent => {
8435 /** @type {Record<string, string | boolean | number>} */
8436 const result = {};
8437 /** @type {HTMLElement[]} */
8438 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
8439 swalParams.forEach(param => {
8440 showWarningsForAttributes(param, ['name', 'value']);
8441 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8442 const value = param.getAttribute('value');
8443 if (!paramName || !value) {
8444 return;
8445 }
8446 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
8447 result[paramName] = value !== 'false';
8448 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
8449 result[paramName] = JSON.parse(value);
8450 } else {
8451 result[paramName] = value;
8452 }
8453 });
8454 return result;
8455 };
8456
8457 /**
8458 * @param {DocumentFragment} templateContent
8459 * @returns {Record<string, () => void>}
8460 */
8461 const getSwalFunctionParams = templateContent => {
8462 /** @type {Record<string, () => void>} */
8463 const result = {};
8464 /** @type {HTMLElement[]} */
8465 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
8466 swalFunctions.forEach(param => {
8467 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8468 const value = param.getAttribute('value');
8469 if (!paramName || !value) {
8470 return;
8471 }
8472 result[paramName] = new Function(`return ${value}`)();
8473 });
8474 return result;
8475 };
8476
8477 /**
8478 * @param {DocumentFragment} templateContent
8479 * @returns {Record<string, string | boolean>}
8480 */
8481 const getSwalButtons = templateContent => {
8482 /** @type {Record<string, string | boolean>} */
8483 const result = {};
8484 /** @type {HTMLElement[]} */
8485 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
8486 swalButtons.forEach(button => {
8487 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
8488 const type = button.getAttribute('type');
8489 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
8490 return;
8491 }
8492 result[`${type}ButtonText`] = button.innerHTML;
8493 result[`show${capitalizeFirstLetter(type)}Button`] = true;
8494 const color = button.getAttribute('color');
8495 if (color !== null) {
8496 result[`${type}ButtonColor`] = color;
8497 }
8498 const ariaLabel = button.getAttribute('aria-label');
8499 if (ariaLabel !== null) {
8500 result[`${type}ButtonAriaLabel`] = ariaLabel;
8501 }
8502 });
8503 return result;
8504 };
8505
8506 /**
8507 * @param {DocumentFragment} templateContent
8508 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
8509 */
8510 const getSwalImage = templateContent => {
8511 const result = {};
8512 /** @type {HTMLElement | null} */
8513 const image = templateContent.querySelector('swal-image');
8514 if (image) {
8515 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
8516 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
8517 const src = image.getAttribute('src');
8518 if (src !== null) result.imageUrl = src || undefined;
8519 const width = image.getAttribute('width');
8520 if (width !== null) result.imageWidth = width || undefined;
8521 const height = image.getAttribute('height');
8522 if (height !== null) result.imageHeight = height || undefined;
8523 const alt = image.getAttribute('alt');
8524 if (alt !== null) result.imageAlt = alt || undefined;
8525 }
8526 return result;
8527 };
8528
8529 /**
8530 * @param {DocumentFragment} templateContent
8531 * @returns {object}
8532 */
8533 const getSwalIcon = templateContent => {
8534 const result = {};
8535 /** @type {HTMLElement | null} */
8536 const icon = templateContent.querySelector('swal-icon');
8537 if (icon) {
8538 showWarningsForAttributes(icon, ['type', 'color']);
8539 if (icon.hasAttribute('type')) {
8540 result.icon = icon.getAttribute('type');
8541 }
8542 if (icon.hasAttribute('color')) {
8543 result.iconColor = icon.getAttribute('color');
8544 }
8545 result.iconHtml = icon.innerHTML;
8546 }
8547 return result;
8548 };
8549
8550 /**
8551 * @param {DocumentFragment} templateContent
8552 * @returns {object}
8553 */
8554 const getSwalInput = templateContent => {
8555 /** @type {Record<string, any>} */
8556 const result = {};
8557 /** @type {HTMLElement | null} */
8558 const input = templateContent.querySelector('swal-input');
8559 if (input) {
8560 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
8561 result.input = input.getAttribute('type') || 'text';
8562 if (input.hasAttribute('label')) {
8563 result.inputLabel = input.getAttribute('label');
8564 }
8565 if (input.hasAttribute('placeholder')) {
8566 result.inputPlaceholder = input.getAttribute('placeholder');
8567 }
8568 if (input.hasAttribute('value')) {
8569 result.inputValue = input.getAttribute('value');
8570 }
8571 }
8572 /** @type {HTMLElement[]} */
8573 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
8574 if (inputOptions.length) {
8575 result.inputOptions = {};
8576 inputOptions.forEach(option => {
8577 showWarningsForAttributes(option, ['value']);
8578 const optionValue = option.getAttribute('value');
8579 if (!optionValue) {
8580 return;
8581 }
8582 const optionName = option.innerHTML;
8583 result.inputOptions[optionValue] = optionName;
8584 });
8585 }
8586 return result;
8587 };
8588
8589 /**
8590 * @param {DocumentFragment} templateContent
8591 * @param {string[]} paramNames
8592 * @returns {Record<string, string>}
8593 */
8594 const getSwalStringParams = (templateContent, paramNames) => {
8595 /** @type {Record<string, string>} */
8596 const result = {};
8597 for (const i in paramNames) {
8598 const paramName = paramNames[i];
8599 /** @type {HTMLElement | null} */
8600 const tag = templateContent.querySelector(paramName);
8601 if (tag) {
8602 showWarningsForAttributes(tag, []);
8603 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
8604 }
8605 }
8606 return result;
8607 };
8608
8609 /**
8610 * @param {DocumentFragment} templateContent
8611 */
8612 const showWarningsForElements = templateContent => {
8613 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
8614 Array.from(templateContent.children).forEach(el => {
8615 const tagName = el.tagName.toLowerCase();
8616 if (!allowedElements.includes(tagName)) {
8617 warn(`Unrecognized element <${tagName}>`);
8618 }
8619 });
8620 };
8621
8622 /**
8623 * @param {HTMLElement} el
8624 * @param {string[]} allowedAttributes
8625 */
8626 const showWarningsForAttributes = (el, allowedAttributes) => {
8627 Array.from(el.attributes).forEach(attribute => {
8628 if (allowedAttributes.indexOf(attribute.name) === -1) {
8629 warn([`Unrecognized attribute "${attribute.name}" on <${el.tagName.toLowerCase()}>.`, `${allowedAttributes.length ? `Allowed attributes are: ${allowedAttributes.join(', ')}` : 'To set the value, use HTML within the element.'}`]);
8630 }
8631 });
8632 };
8633
8634 const SHOW_CLASS_TIMEOUT = 10;
8635
8636 /**
8637 * Open popup, add necessary classes and styles, fix scrollbar
8638 *
8639 * @param {SweetAlertOptions} params
8640 */
8641 const openPopup = params => {
8642 var _globalState$eventEmi, _globalState$eventEmi2;
8643 const container = getContainer();
8644 const popup = getPopup();
8645 if (!container || !popup) {
8646 return;
8647 }
8648 if (typeof params.willOpen === 'function') {
8649 params.willOpen(popup);
8650 }
8651 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
8652 const bodyStyles = window.getComputedStyle(document.body);
8653 const initialBodyOverflow = bodyStyles.overflowY;
8654 addClasses(container, popup, params);
8655
8656 // scrolling is 'hidden' until animation is done, after that 'auto'
8657 setTimeout(() => {
8658 setScrollingVisibility(container, popup);
8659 }, SHOW_CLASS_TIMEOUT);
8660 if (isModal()) {
8661 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
8662 setAriaHidden();
8663 }
8664
8665 // https://github.com/sweetalert2/sweetalert2/issues/2923
8666 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
8667 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
8668 container.style.pointerEvents = 'auto';
8669 }
8670 if (!isToast() && !globalState.previousActiveElement) {
8671 globalState.previousActiveElement = document.activeElement;
8672 }
8673 if (typeof params.didOpen === 'function') {
8674 const didOpen = params.didOpen;
8675 setTimeout(() => didOpen(popup));
8676 }
8677 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
8678 };
8679
8680 /**
8681 * @param {Event} event
8682 */
8683 const swalOpenAnimationFinished = event => {
8684 const popup = getPopup();
8685 if (!popup || event.target !== popup) {
8686 return;
8687 }
8688 const container = getContainer();
8689 if (!container) {
8690 return;
8691 }
8692 popup.removeEventListener('animationend', swalOpenAnimationFinished);
8693 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
8694 container.style.overflowY = 'auto';
8695
8696 // no-transition is added in init() in case one swal is opened right after another
8697 removeClass(container, swalClasses['no-transition']);
8698 };
8699
8700 /**
8701 * @param {HTMLElement} container
8702 * @param {HTMLElement} popup
8703 */
8704 const setScrollingVisibility = (container, popup) => {
8705 if (hasCssAnimation(popup)) {
8706 container.style.overflowY = 'hidden';
8707 popup.addEventListener('animationend', swalOpenAnimationFinished);
8708 popup.addEventListener('transitionend', swalOpenAnimationFinished);
8709 } else {
8710 container.style.overflowY = 'auto';
8711 }
8712 };
8713
8714 /**
8715 * @param {HTMLElement} container
8716 * @param {boolean} scrollbarPadding
8717 * @param {string} initialBodyOverflow
8718 */
8719 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
8720 iOSfix();
8721 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
8722 replaceScrollbarWithPadding(initialBodyOverflow);
8723 }
8724
8725 // sweetalert2/issues/1247
8726 setTimeout(() => {
8727 container.scrollTop = 0;
8728 });
8729 };
8730
8731 /**
8732 * @param {HTMLElement} container
8733 * @param {HTMLElement} popup
8734 * @param {SweetAlertOptions} params
8735 */
8736 const addClasses = (container, popup, params) => {
8737 var _params$showClass;
8738 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
8739 addClass(container, params.showClass.backdrop);
8740 }
8741 if (params.animation) {
8742 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
8743 popup.style.setProperty('opacity', '0', 'important');
8744 show(popup, 'grid');
8745 setTimeout(() => {
8746 var _params$showClass2;
8747 // Animate popup right after showing it
8748 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
8749 addClass(popup, params.showClass.popup);
8750 }
8751 // and remove the opacity workaround
8752 popup.style.removeProperty('opacity');
8753 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
8754 } else {
8755 show(popup, 'grid');
8756 }
8757 addClass([document.documentElement, document.body], swalClasses.shown);
8758 if (params.heightAuto && params.backdrop && !params.toast) {
8759 addClass([document.documentElement, document.body], swalClasses['height-auto']);
8760 }
8761 };
8762
8763 var defaultInputValidators = {
8764 /**
8765 * @param {string} string
8766 * @param {string} [validationMessage]
8767 * @returns {Promise<string | void>}
8768 */
8769 email: (string, validationMessage) => {
8770 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
8771 },
8772 /**
8773 * @param {string} string
8774 * @param {string} [validationMessage]
8775 * @returns {Promise<string | void>}
8776 */
8777 url: (string, validationMessage) => {
8778 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
8779 return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid URL');
8780 }
8781 };
8782
8783 /**
8784 * @param {SweetAlertOptions} params
8785 */
8786 function setDefaultInputValidators(params) {
8787 // Use default `inputValidator` for supported input types if not provided
8788 if (params.inputValidator) {
8789 return;
8790 }
8791 if (params.input === 'email') {
8792 params.inputValidator = defaultInputValidators['email'];
8793 }
8794 if (params.input === 'url') {
8795 params.inputValidator = defaultInputValidators['url'];
8796 }
8797 }
8798
8799 /**
8800 * @param {SweetAlertOptions} params
8801 */
8802 function validateCustomTargetElement(params) {
8803 // Determine if the custom target element is valid
8804 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
8805 warn('Target parameter is not valid, defaulting to "body"');
8806 params.target = 'body';
8807 }
8808 }
8809
8810 /**
8811 * Set type, text and actions on popup
8812 *
8813 * @param {SweetAlertOptions} params
8814 */
8815 function setParameters(params) {
8816 setDefaultInputValidators(params);
8817
8818 // showLoaderOnConfirm && preConfirm
8819 if (params.showLoaderOnConfirm && !params.preConfirm) {
8820 warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request');
8821 }
8822 validateCustomTargetElement(params);
8823
8824 // Replace newlines with <br> in title
8825 if (typeof params.title === 'string') {
8826 params.title = params.title.split('\n').join('<br />');
8827 }
8828 init(params);
8829 }
8830
8831 /** @type {SweetAlert} */
8832 let currentInstance;
8833 var _promise = /*#__PURE__*/new WeakMap();
8834 class SweetAlert {
8835 /**
8836 * @param {...(SweetAlertOptions | string)} args
8837 * @this {SweetAlert}
8838 */
8839 constructor(...args) {
8840 /**
8841 * @type {Promise<SweetAlertResult>}
8842 */
8843 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
8844 Promise.resolve({
8845 isConfirmed: false,
8846 isDenied: false,
8847 isDismissed: true
8848 }));
8849 // Prevent run in Node env
8850 if (typeof window === 'undefined') {
8851 return;
8852 }
8853 currentInstance = this;
8854
8855 // @ts-ignore
8856 const outerParams = Object.freeze(this.constructor.argsToParams(args));
8857
8858 /** @type {Readonly<SweetAlertOptions>} */
8859 this.params = outerParams;
8860
8861 /** @type {boolean} */
8862 this.isAwaitingPromise = false;
8863 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
8864 }
8865
8866 /**
8867 * @param {any} userParams
8868 * @param {any} mixinParams
8869 */
8870 _main(userParams, mixinParams = {}) {
8871 showWarningsForParams(Object.assign({}, mixinParams, userParams));
8872 if (globalState.currentInstance) {
8873 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
8874 const {
8875 isAwaitingPromise
8876 } = globalState.currentInstance;
8877 globalState.currentInstance._destroy();
8878 if (!isAwaitingPromise) {
8879 swalPromiseResolve({
8880 isDismissed: true
8881 });
8882 }
8883 if (isModal()) {
8884 unsetAriaHidden();
8885 }
8886 }
8887 globalState.currentInstance = currentInstance;
8888 const innerParams = prepareParams(userParams, mixinParams);
8889 setParameters(innerParams);
8890 Object.freeze(innerParams);
8891
8892 // clear the previous timer
8893 if (globalState.timeout) {
8894 globalState.timeout.stop();
8895 delete globalState.timeout;
8896 }
8897
8898 // clear the restore focus timeout
8899 clearTimeout(globalState.restoreFocusTimeout);
8900 const domCache = populateDomCache(currentInstance);
8901 render(currentInstance, innerParams);
8902 privateProps.innerParams.set(currentInstance, innerParams);
8903 return swalPromise(currentInstance, domCache, innerParams);
8904 }
8905
8906 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
8907 /**
8908 * @param {any} onFulfilled
8909 */
8910 // oxlint-disable-next-line unicorn/no-thenable
8911 then(onFulfilled) {
8912 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
8913 }
8914
8915 /**
8916 * @param {any} onFinally
8917 */
8918 finally(onFinally) {
8919 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
8920 }
8921 }
8922
8923 /**
8924 * @param {SweetAlert} instance
8925 * @param {DomCache} domCache
8926 * @param {SweetAlertOptions} innerParams
8927 * @returns {Promise<SweetAlertResult>}
8928 */
8929 const swalPromise = (instance, domCache, innerParams) => {
8930 return new Promise((resolve, reject) => {
8931 // functions to handle all closings/dismissals
8932 /**
8933 * @param {DismissReason} dismiss
8934 */
8935 const dismissWith = dismiss => {
8936 instance.close({
8937 isDismissed: true,
8938 dismiss,
8939 isConfirmed: false,
8940 isDenied: false
8941 });
8942 };
8943 privateMethods.swalPromiseResolve.set(instance, resolve);
8944 privateMethods.swalPromiseReject.set(instance, reject);
8945 domCache.confirmButton.onclick = () => {
8946 handleConfirmButtonClick(instance);
8947 };
8948 domCache.denyButton.onclick = () => {
8949 handleDenyButtonClick(instance);
8950 };
8951 domCache.cancelButton.onclick = () => {
8952 handleCancelButtonClick(instance, dismissWith);
8953 };
8954 domCache.closeButton.onclick = () => {
8955 dismissWith(DismissReason.close);
8956 };
8957 handlePopupClick(innerParams, domCache, dismissWith);
8958 addKeydownHandler(globalState, innerParams, dismissWith);
8959 handleInputOptionsAndValue(instance, innerParams);
8960 openPopup(innerParams);
8961 setupTimer(globalState, innerParams, dismissWith);
8962 initFocus(domCache, innerParams);
8963
8964 // Scroll container to top on open (#1247, #1946)
8965 setTimeout(() => {
8966 domCache.container.scrollTop = 0;
8967 });
8968 });
8969 };
8970
8971 /**
8972 * @param {SweetAlertOptions} userParams
8973 * @param {SweetAlertOptions} mixinParams
8974 * @returns {SweetAlertOptions}
8975 */
8976 const prepareParams = (userParams, mixinParams) => {
8977 const templateParams = getTemplateParams(userParams);
8978 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
8979 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
8980 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
8981 if (params.animation === false) {
8982 params.showClass = {
8983 backdrop: 'swal2-noanimation'
8984 };
8985 params.hideClass = {};
8986 }
8987 return params;
8988 };
8989
8990 /**
8991 * @param {SweetAlert} instance
8992 * @returns {DomCache}
8993 */
8994 const populateDomCache = instance => {
8995 const domCache = /** @type {DomCache} */{
8996 popup: (/** @type {HTMLElement} */getPopup()),
8997 container: (/** @type {HTMLElement} */getContainer()),
8998 actions: (/** @type {HTMLElement} */getActions()),
8999 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
9000 denyButton: (/** @type {HTMLElement} */getDenyButton()),
9001 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
9002 loader: (/** @type {HTMLElement} */getLoader()),
9003 closeButton: (/** @type {HTMLElement} */getCloseButton()),
9004 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
9005 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
9006 };
9007 privateProps.domCache.set(instance, domCache);
9008 return domCache;
9009 };
9010
9011 /**
9012 * @param {GlobalState} globalState
9013 * @param {SweetAlertOptions} innerParams
9014 * @param {(dismiss: DismissReason) => void} dismissWith
9015 */
9016 const setupTimer = (globalState, innerParams, dismissWith) => {
9017 const timerProgressBar = getTimerProgressBar();
9018 hide(timerProgressBar);
9019 if (innerParams.timer) {
9020 globalState.timeout = new Timer(() => {
9021 dismissWith('timer');
9022 delete globalState.timeout;
9023 }, innerParams.timer);
9024 if (innerParams.timerProgressBar && timerProgressBar) {
9025 show(timerProgressBar);
9026 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
9027 setTimeout(() => {
9028 if (globalState.timeout && globalState.timeout.running) {
9029 // timer can be already stopped or unset at this point
9030 animateTimerProgressBar(/** @type {number} */innerParams.timer);
9031 }
9032 });
9033 }
9034 }
9035 };
9036
9037 /**
9038 * Initialize focus in the popup:
9039 *
9040 * 1. If `toast` is `true`, don't steal focus from the document.
9041 * 2. Else if there is an [autofocus] element, focus it.
9042 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
9043 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
9044 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
9045 * 6. Else focus the first focusable element in a popup (if any).
9046 *
9047 * @param {DomCache} domCache
9048 * @param {SweetAlertOptions} innerParams
9049 */
9050 const initFocus = (domCache, innerParams) => {
9051 if (innerParams.toast) {
9052 return;
9053 }
9054 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
9055 if (!callIfFunction(innerParams.allowEnterKey)) {
9056 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
9057 domCache.popup.focus();
9058 return;
9059 }
9060 if (focusAutofocus(domCache)) {
9061 return;
9062 }
9063 if (focusButton(domCache, innerParams)) {
9064 return;
9065 }
9066 setFocus(-1, 1);
9067 };
9068
9069 /**
9070 * @param {DomCache} domCache
9071 * @returns {boolean}
9072 */
9073 const focusAutofocus = domCache => {
9074 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
9075 for (const autofocusElement of autofocusElements) {
9076 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
9077 autofocusElement.focus();
9078 return true;
9079 }
9080 }
9081 return false;
9082 };
9083
9084 /**
9085 * @param {DomCache} domCache
9086 * @param {SweetAlertOptions} innerParams
9087 * @returns {boolean}
9088 */
9089 const focusButton = (domCache, innerParams) => {
9090 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
9091 domCache.denyButton.focus();
9092 return true;
9093 }
9094 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
9095 domCache.cancelButton.focus();
9096 return true;
9097 }
9098 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
9099 domCache.confirmButton.focus();
9100 return true;
9101 }
9102 return false;
9103 };
9104
9105 // Assign instance methods from src/instanceMethods/*.js to prototype
9106 SweetAlert.prototype.disableButtons = disableButtons;
9107 SweetAlert.prototype.enableButtons = enableButtons;
9108 SweetAlert.prototype.getInput = getInput;
9109 SweetAlert.prototype.disableInput = disableInput;
9110 SweetAlert.prototype.enableInput = enableInput;
9111 SweetAlert.prototype.hideLoading = hideLoading;
9112 SweetAlert.prototype.disableLoading = hideLoading;
9113 SweetAlert.prototype.showValidationMessage = showValidationMessage;
9114 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
9115 SweetAlert.prototype.close = close;
9116 SweetAlert.prototype.closePopup = close;
9117 SweetAlert.prototype.closeModal = close;
9118 SweetAlert.prototype.closeToast = close;
9119 SweetAlert.prototype.rejectPromise = rejectPromise;
9120 SweetAlert.prototype.update = update;
9121 SweetAlert.prototype._destroy = _destroy;
9122
9123 // Assign static methods from src/staticMethods/*.js to constructor
9124 Object.assign(SweetAlert, staticMethods);
9125
9126 // Proxy to instance methods to constructor, for now, for backwards compatibility
9127 Object.keys(instanceMethods).forEach(key => {
9128 /**
9129 * @param {...(SweetAlertOptions | string | undefined)} args
9130 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
9131 */
9132 // @ts-ignore: Dynamic property assignment for backwards compatibility
9133 SweetAlert[key] = function (...args) {
9134 // @ts-ignore
9135 if (currentInstance && currentInstance[key]) {
9136 // @ts-ignore
9137 return currentInstance[key](...args);
9138 }
9139 return undefined;
9140 };
9141 });
9142 SweetAlert.DismissReason = DismissReason;
9143 SweetAlert.version = '11.26.25';
9144
9145 const Swal = SweetAlert;
9146 // @ts-ignore
9147 Swal.default = Swal;
9148
9149 return Swal;
9150
9151 }));
9152 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
9153 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:auto}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:auto}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
9154
9155 /***/ },
9156
9157 /***/ "./node_modules/toastify-js/src/toastify.js"
9158 /*!**************************************************!*\
9159 !*** ./node_modules/toastify-js/src/toastify.js ***!
9160 \**************************************************/
9161 (module) {
9162
9163 /*!
9164 * Toastify js 1.12.0
9165 * https://github.com/apvarun/toastify-js
9166 * @license MIT licensed
9167 *
9168 * Copyright (C) 2018 Varun A P
9169 */
9170 (function(root, factory) {
9171 if ( true && module.exports) {
9172 module.exports = factory();
9173 } else {
9174 root.Toastify = factory();
9175 }
9176 })(this, function(global) {
9177 // Object initialization
9178 var Toastify = function(options) {
9179 // Returning a new init object
9180 return new Toastify.lib.init(options);
9181 },
9182 // Library version
9183 version = "1.12.0";
9184
9185 // Set the default global options
9186 Toastify.defaults = {
9187 oldestFirst: true,
9188 text: "Toastify is awesome!",
9189 node: undefined,
9190 duration: 3000,
9191 selector: undefined,
9192 callback: function () {
9193 },
9194 destination: undefined,
9195 newWindow: false,
9196 close: false,
9197 gravity: "toastify-top",
9198 positionLeft: false,
9199 position: '',
9200 backgroundColor: '',
9201 avatar: "",
9202 className: "",
9203 stopOnFocus: true,
9204 onClick: function () {
9205 },
9206 offset: {x: 0, y: 0},
9207 escapeMarkup: true,
9208 ariaLive: 'polite',
9209 style: {background: ''}
9210 };
9211
9212 // Defining the prototype of the object
9213 Toastify.lib = Toastify.prototype = {
9214 toastify: version,
9215
9216 constructor: Toastify,
9217
9218 // Initializing the object with required parameters
9219 init: function(options) {
9220 // Verifying and validating the input object
9221 if (!options) {
9222 options = {};
9223 }
9224
9225 // Creating the options object
9226 this.options = {};
9227
9228 this.toastElement = null;
9229
9230 // Validating the options
9231 this.options.text = options.text || Toastify.defaults.text; // Display message
9232 this.options.node = options.node || Toastify.defaults.node; // Display content as node
9233 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
9234 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
9235 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
9236 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
9237 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
9238 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
9239 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
9240 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
9241 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
9242 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
9243 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
9244 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
9245 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
9246 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
9247 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
9248 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
9249 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
9250 this.options.style = options.style || Toastify.defaults.style;
9251 if(options.backgroundColor) {
9252 this.options.style.background = options.backgroundColor;
9253 }
9254
9255 // Returning the current object for chaining functions
9256 return this;
9257 },
9258
9259 // Building the DOM element
9260 buildToast: function() {
9261 // Validating if the options are defined
9262 if (!this.options) {
9263 throw "Toastify is not initialized";
9264 }
9265
9266 // Creating the DOM object
9267 var divElement = document.createElement("div");
9268 divElement.className = "toastify on " + this.options.className;
9269
9270 // Positioning toast to left or right or center
9271 if (!!this.options.position) {
9272 divElement.className += " toastify-" + this.options.position;
9273 } else {
9274 // To be depreciated in further versions
9275 if (this.options.positionLeft === true) {
9276 divElement.className += " toastify-left";
9277 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
9278 } else {
9279 // Default position
9280 divElement.className += " toastify-right";
9281 }
9282 }
9283
9284 // Assigning gravity of element
9285 divElement.className += " " + this.options.gravity;
9286
9287 if (this.options.backgroundColor) {
9288 // This is being deprecated in favor of using the style HTML DOM property
9289 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
9290 }
9291
9292 // Loop through our style object and apply styles to divElement
9293 for (var property in this.options.style) {
9294 divElement.style[property] = this.options.style[property];
9295 }
9296
9297 // Announce the toast to screen readers
9298 if (this.options.ariaLive) {
9299 divElement.setAttribute('aria-live', this.options.ariaLive)
9300 }
9301
9302 // Adding the toast message/node
9303 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
9304 // If we have a valid node, we insert it
9305 divElement.appendChild(this.options.node)
9306 } else {
9307 if (this.options.escapeMarkup) {
9308 divElement.innerText = this.options.text;
9309 } else {
9310 divElement.innerHTML = this.options.text;
9311 }
9312
9313 if (this.options.avatar !== "") {
9314 var avatarElement = document.createElement("img");
9315 avatarElement.src = this.options.avatar;
9316
9317 avatarElement.className = "toastify-avatar";
9318
9319 if (this.options.position == "left" || this.options.positionLeft === true) {
9320 // Adding close icon on the left of content
9321 divElement.appendChild(avatarElement);
9322 } else {
9323 // Adding close icon on the right of content
9324 divElement.insertAdjacentElement("afterbegin", avatarElement);
9325 }
9326 }
9327 }
9328
9329 // Adding a close icon to the toast
9330 if (this.options.close === true) {
9331 // Create a span for close element
9332 var closeElement = document.createElement("button");
9333 closeElement.type = "button";
9334 closeElement.setAttribute("aria-label", "Close");
9335 closeElement.className = "toast-close";
9336 closeElement.innerHTML = "&#10006;";
9337
9338 // Triggering the removal of toast from DOM on close click
9339 closeElement.addEventListener(
9340 "click",
9341 function(event) {
9342 event.stopPropagation();
9343 this.removeElement(this.toastElement);
9344 window.clearTimeout(this.toastElement.timeOutValue);
9345 }.bind(this)
9346 );
9347
9348 //Calculating screen width
9349 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9350
9351 // Adding the close icon to the toast element
9352 // Display on the right if screen width is less than or equal to 360px
9353 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
9354 // Adding close icon on the left of content
9355 divElement.insertAdjacentElement("afterbegin", closeElement);
9356 } else {
9357 // Adding close icon on the right of content
9358 divElement.appendChild(closeElement);
9359 }
9360 }
9361
9362 // Clear timeout while toast is focused
9363 if (this.options.stopOnFocus && this.options.duration > 0) {
9364 var self = this;
9365 // stop countdown
9366 divElement.addEventListener(
9367 "mouseover",
9368 function(event) {
9369 window.clearTimeout(divElement.timeOutValue);
9370 }
9371 )
9372 // add back the timeout
9373 divElement.addEventListener(
9374 "mouseleave",
9375 function() {
9376 divElement.timeOutValue = window.setTimeout(
9377 function() {
9378 // Remove the toast from DOM
9379 self.removeElement(divElement);
9380 },
9381 self.options.duration
9382 )
9383 }
9384 )
9385 }
9386
9387 // Adding an on-click destination path
9388 if (typeof this.options.destination !== "undefined") {
9389 divElement.addEventListener(
9390 "click",
9391 function(event) {
9392 event.stopPropagation();
9393 if (this.options.newWindow === true) {
9394 window.open(this.options.destination, "_blank");
9395 } else {
9396 window.location = this.options.destination;
9397 }
9398 }.bind(this)
9399 );
9400 }
9401
9402 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
9403 divElement.addEventListener(
9404 "click",
9405 function(event) {
9406 event.stopPropagation();
9407 this.options.onClick();
9408 }.bind(this)
9409 );
9410 }
9411
9412 // Adding offset
9413 if(typeof this.options.offset === "object") {
9414
9415 var x = getAxisOffsetAValue("x", this.options);
9416 var y = getAxisOffsetAValue("y", this.options);
9417
9418 var xOffset = this.options.position == "left" ? x : "-" + x;
9419 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
9420
9421 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
9422
9423 }
9424
9425 // Returning the generated element
9426 return divElement;
9427 },
9428
9429 // Displaying the toast
9430 showToast: function() {
9431 // Creating the DOM object for the toast
9432 this.toastElement = this.buildToast();
9433
9434 // Getting the root element to with the toast needs to be added
9435 var rootElement;
9436 if (typeof this.options.selector === "string") {
9437 rootElement = document.getElementById(this.options.selector);
9438 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
9439 rootElement = this.options.selector;
9440 } else {
9441 rootElement = document.body;
9442 }
9443
9444 // Validating if root element is present in DOM
9445 if (!rootElement) {
9446 throw "Root element is not defined";
9447 }
9448
9449 // Adding the DOM element
9450 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
9451 rootElement.insertBefore(this.toastElement, elementToInsert);
9452
9453 // Repositioning the toasts in case multiple toasts are present
9454 Toastify.reposition();
9455
9456 if (this.options.duration > 0) {
9457 this.toastElement.timeOutValue = window.setTimeout(
9458 function() {
9459 // Remove the toast from DOM
9460 this.removeElement(this.toastElement);
9461 }.bind(this),
9462 this.options.duration
9463 ); // Binding `this` for function invocation
9464 }
9465
9466 // Supporting function chaining
9467 return this;
9468 },
9469
9470 hideToast: function() {
9471 if (this.toastElement.timeOutValue) {
9472 clearTimeout(this.toastElement.timeOutValue);
9473 }
9474 this.removeElement(this.toastElement);
9475 },
9476
9477 // Removing the element from the DOM
9478 removeElement: function(toastElement) {
9479 // Hiding the element
9480 // toastElement.classList.remove("on");
9481 toastElement.className = toastElement.className.replace(" on", "");
9482
9483 // Removing the element from DOM after transition end
9484 window.setTimeout(
9485 function() {
9486 // remove options node if any
9487 if (this.options.node && this.options.node.parentNode) {
9488 this.options.node.parentNode.removeChild(this.options.node);
9489 }
9490
9491 // Remove the element from the DOM, only when the parent node was not removed before.
9492 if (toastElement.parentNode) {
9493 toastElement.parentNode.removeChild(toastElement);
9494 }
9495
9496 // Calling the callback function
9497 this.options.callback.call(toastElement);
9498
9499 // Repositioning the toasts again
9500 Toastify.reposition();
9501 }.bind(this),
9502 400
9503 ); // Binding `this` for function invocation
9504 },
9505 };
9506
9507 // Positioning the toasts on the DOM
9508 Toastify.reposition = function() {
9509
9510 // Top margins with gravity
9511 var topLeftOffsetSize = {
9512 top: 15,
9513 bottom: 15,
9514 };
9515 var topRightOffsetSize = {
9516 top: 15,
9517 bottom: 15,
9518 };
9519 var offsetSize = {
9520 top: 15,
9521 bottom: 15,
9522 };
9523
9524 // Get all toast messages on the DOM
9525 var allToasts = document.getElementsByClassName("toastify");
9526
9527 var classUsed;
9528
9529 // Modifying the position of each toast element
9530 for (var i = 0; i < allToasts.length; i++) {
9531 // Getting the applied gravity
9532 if (containsClass(allToasts[i], "toastify-top") === true) {
9533 classUsed = "toastify-top";
9534 } else {
9535 classUsed = "toastify-bottom";
9536 }
9537
9538 var height = allToasts[i].offsetHeight;
9539 classUsed = classUsed.substr(9, classUsed.length-1)
9540 // Spacing between toasts
9541 var offset = 15;
9542
9543 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9544
9545 // Show toast in center if screen with less than or equal to 360px
9546 if (width <= 360) {
9547 // Setting the position
9548 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
9549
9550 offsetSize[classUsed] += height + offset;
9551 } else {
9552 if (containsClass(allToasts[i], "toastify-left") === true) {
9553 // Setting the position
9554 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
9555
9556 topLeftOffsetSize[classUsed] += height + offset;
9557 } else {
9558 // Setting the position
9559 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
9560
9561 topRightOffsetSize[classUsed] += height + offset;
9562 }
9563 }
9564 }
9565
9566 // Supporting function chaining
9567 return this;
9568 };
9569
9570 // Helper function to get offset.
9571 function getAxisOffsetAValue(axis, options) {
9572
9573 if(options.offset[axis]) {
9574 if(isNaN(options.offset[axis])) {
9575 return options.offset[axis];
9576 }
9577 else {
9578 return options.offset[axis] + 'px';
9579 }
9580 }
9581
9582 return '0px';
9583
9584 }
9585
9586 function containsClass(elem, yourClass) {
9587 if (!elem || typeof yourClass !== "string") {
9588 return false;
9589 } else if (
9590 elem.className &&
9591 elem.className
9592 .trim()
9593 .split(/\s+/gi)
9594 .indexOf(yourClass) > -1
9595 ) {
9596 return true;
9597 } else {
9598 return false;
9599 }
9600 }
9601
9602 // Setting up the prototype for the init object
9603 Toastify.lib.init.prototype = Toastify.lib;
9604
9605 // Returning the Toastify function to be assigned to the window object/module
9606 return Toastify;
9607 });
9608
9609
9610 /***/ }
9611
9612 /******/ });
9613 /************************************************************************/
9614 /******/ // The module cache
9615 /******/ const __webpack_module_cache__ = {};
9616 /******/
9617 /******/ // The require function
9618 /******/ function __webpack_require__(moduleId) {
9619 /******/ // Check if module is in cache
9620 /******/ const cachedModule = __webpack_module_cache__[moduleId];
9621 /******/ if (cachedModule !== undefined) {
9622 /******/ return cachedModule.exports;
9623 /******/ }
9624 /******/ // Create a new module (and put it into the cache)
9625 /******/ const module = __webpack_module_cache__[moduleId] = {
9626 /******/ id: moduleId,
9627 /******/ // no module.loaded needed
9628 /******/ exports: {}
9629 /******/ };
9630 /******/
9631 /******/ // Execute the module function
9632 /******/ if (!(moduleId in __webpack_modules__)) {
9633 /******/ delete __webpack_module_cache__[moduleId];
9634 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
9635 /******/ e.code = 'MODULE_NOT_FOUND';
9636 /******/ throw e;
9637 /******/ }
9638 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
9639 /******/
9640 /******/ // Return the exports of the module
9641 /******/ return module.exports;
9642 /******/ }
9643 /******/
9644 /************************************************************************/
9645 /******/ /* webpack/runtime/compat get default export */
9646 /******/ (() => {
9647 /******/ // getDefaultExport function for compatibility with non-harmony modules
9648 /******/ __webpack_require__.n = (module) => {
9649 /******/ const getter = module && module.__esModule ?
9650 /******/ () => (module['default']) :
9651 /******/ () => (module);
9652 /******/ __webpack_require__.d(getter, { a: getter });
9653 /******/ return getter;
9654 /******/ };
9655 /******/ })();
9656 /******/
9657 /******/ /* webpack/runtime/define property getters */
9658 /******/ (() => {
9659 /******/ // define getter/value functions for harmony exports
9660 /******/ __webpack_require__.d = (exports, definition) => {
9661 /******/ if(Array.isArray(definition)) {
9662 /******/ var i = 0;
9663 /******/ while(i < definition.length) {
9664 /******/ var key = definition[i++];
9665 /******/ var binding = definition[i++];
9666 /******/ if(!__webpack_require__.o(exports, key)) {
9667 /******/ if(binding === 0) {
9668 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
9669 /******/ } else {
9670 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
9671 /******/ }
9672 /******/ } else if(binding === 0) { i++; }
9673 /******/ }
9674 /******/ } else {
9675 /******/ for(var key in definition) {
9676 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
9677 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
9678 /******/ }
9679 /******/ }
9680 /******/ }
9681 /******/ };
9682 /******/ })();
9683 /******/
9684 /******/ /* webpack/runtime/hasOwnProperty shorthand */
9685 /******/ (() => {
9686 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
9687 /******/ })();
9688 /******/
9689 /******/ /* webpack/runtime/make namespace object */
9690 /******/ (() => {
9691 /******/ // define __esModule on exports
9692 /******/ __webpack_require__.r = (exports) => {
9693 /******/ if(Symbol.toStringTag) {
9694 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
9695 /******/ }
9696 /******/ Object.defineProperty(exports, '__esModule', { value: true });
9697 /******/ };
9698 /******/ })();
9699 /******/
9700 /******/ /* webpack/runtime/nonce */
9701 /******/ (() => {
9702 /******/ __webpack_require__.nc = undefined;
9703 /******/ })();
9704 /******/
9705 /************************************************************************/
9706 let __webpack_exports__ = {};
9707 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
9708 (() => {
9709 "use strict";
9710 /*!**********************************************!*\
9711 !*** ./assets/src/js/admin/edit-question.js ***!
9712 \**********************************************/
9713 __webpack_require__.r(__webpack_exports__);
9714 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9715 /* harmony export */ EditQuestion: () => (/* binding */ EditQuestion)
9716 /* harmony export */ });
9717 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
9718 /* harmony import */ var lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify */ "./assets/src/js/lpToastify.js");
9719 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
9720 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
9721 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
9722 /**
9723 * Edit question JS handler.
9724 *
9725 * @since 4.2.9
9726 * @version 1.0.0
9727 */
9728
9729
9730
9731
9732
9733 const idUrlHandle = 'edit-question';
9734 let fibSelection;
9735 let timeoutAutoUpdateAnswer, timeoutAutoUpdateFib, timeoutAutoUpdateQuestion;
9736
9737 // EditQuestion class
9738 class EditQuestion {
9739 static selectors = {
9740 elEditQuestionWrap: '.lp-edit-question-wrap',
9741 elQuestionEditMain: '.lp-question-edit-main',
9742 elQuestionToggleAll: '.lp-question-toggle-all',
9743 elEditListQuestions: '.lp-edit-list-questions',
9744 elQuestionToggle: '.lp-question-toggle',
9745 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
9746 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
9747 elBtnAddQuestion: '.lp-btn-add-question',
9748 elBtnRemoveQuestion: '.lp-btn-remove-question',
9749 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
9750 elBtnUpdateQuestionDes: '.lp-btn-update-question-des',
9751 elBtnUpdateQuestionHint: '.lp-btn-update-question-hint',
9752 elBtnUpdateQuestionExplain: '.lp-btn-update-question-explanation',
9753 elQuestionTitleNewInput: '.lp-question-title-new-input',
9754 elQuestionTitleInput: '.lp-question-title-input',
9755 elQuestionTypeLabel: '.lp-question-type-label',
9756 elQuestionTypeNew: '.lp-question-type-new',
9757 elAddNewQuestion: 'add-new-question',
9758 elQuestionClone: '.lp-question-item.clone',
9759 elAnswersConfig: '.lp-answers-config',
9760 elBtnAddAnswer: '.lp-btn-add-question-answer',
9761 elQuestionAnswerItemAddNew: '.lp-question-answer-item-add-new',
9762 elQuestionAnswerTitleNewInput: '.lp-question-answer-title-new-input',
9763 elQuestionAnswerTitleInput: '.lp-question-answer-title-input',
9764 elBtnDeleteAnswer: '.lp-btn-delete-question-answer',
9765 elQuestionByType: '.lp-question-by-type',
9766 elInputAnswerSetTrue: '.lp-input-answer-set-true',
9767 elQuestionAnswerItem: '.lp-question-answer-item',
9768 elBtnUpdateQuestionAnswer: '.lp-btn-update-question-answer',
9769 elBtnFibInsertBlank: '.lp-btn-fib-insert-blank',
9770 elBtnFibDeleteAllBlanks: '.lp-btn-fib-delete-all-blanks',
9771 elBtnFibSaveContent: '.lp-btn-fib-save-content',
9772 elBtnFibClearAllContent: '.lp-btn-fib-clear-all-content',
9773 elFibOptionTitleInput: '.lp-question-fib-option-title-input',
9774 elFibBlankOptions: '.lp-question-fib-blank-options',
9775 elFibBlankOptionItem: '.lp-question-fib-blank-option-item',
9776 elFibBlankOptionItemClone: '.lp-question-fib-blank-option-item.clone',
9777 elFibBlankOptionIndex: '.lp-question-fib-option-index',
9778 elBtnFibOptionDelete: '.lp-btn-fib-option-delete',
9779 elFibOptionMatchCaseWrap: '.lp-question-fib-option-match-case-wrap',
9780 elFibOptionMatchCaseInput: '.lp-question-fib-option-match-case-input',
9781 elQuestionFibOptionDetail: '.lp-question-fib-option-detail',
9782 elFibOptionComparisonInput: '.lp-question-fib-option-comparison-input',
9783 elAutoSaveFib: '.lp-auto-save-fib',
9784 LPTarget: '.lp-target',
9785 elCollapse: 'lp-collapse',
9786 elSectionToggle: '.lp-section-toggle',
9787 elTriggerToggle: '.lp-trigger-toggle',
9788 elAutoSaveQuestion: '.lp-auto-save-question',
9789 elAutoSaveAnswer: '.lp-auto-save-question-answer',
9790 elQuestionFibInput: 'lp-question-fib-input',
9791 elBtnQuestionCreateType: '.lp-btn-question-create-type'
9792 };
9793 constructor() {}
9794 init() {
9795 this.events();
9796 this.initTinyMCE().then();
9797 }
9798 events() {
9799 if (EditQuestion._loadedEvents) {
9800 return;
9801 }
9802 EditQuestion._loadedEvents = true;
9803
9804 // Sortable answers's question
9805 const elQuestionEditMains = document.querySelectorAll(`${EditQuestion.selectors.elQuestionEditMain}`);
9806 elQuestionEditMains.forEach(elQuestionEditMain => {
9807 this.sortAbleQuestionAnswer(elQuestionEditMain);
9808 });
9809 // End sortable
9810
9811 // Event click
9812 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
9813 selector: EditQuestion.selectors.elBtnQuestionCreateType,
9814 callBack: this.createQuestionType.name,
9815 class: this
9816 }, {
9817 selector: EditQuestion.selectors.elBtnAddAnswer,
9818 callBack: this.addQuestionAnswer.name,
9819 class: this
9820 }, {
9821 selector: EditQuestion.selectors.elBtnDeleteAnswer,
9822 callBack: this.deleteQuestionAnswer.name,
9823 class: this
9824 }, {
9825 selector: EditQuestion.selectors.elBtnFibInsertBlank,
9826 callBack: this.fibInsertBlank.name,
9827 class: this
9828 }, {
9829 selector: EditQuestion.selectors.elBtnFibDeleteAllBlanks,
9830 callBack: this.fibDeleteAllBlanks.name,
9831 class: this
9832 }, {
9833 selector: EditQuestion.selectors.elBtnFibSaveContent,
9834 callBack: this.fibSaveContent.name,
9835 class: this
9836 }, {
9837 selector: EditQuestion.selectors.elBtnFibClearAllContent,
9838 callBack: this.fibClearContent.name,
9839 class: this
9840 }, {
9841 selector: EditQuestion.selectors.elBtnFibOptionDelete,
9842 callBack: this.fibDeleteBlank.name,
9843 class: this
9844 }, {
9845 selector: EditQuestion.selectors.elFibOptionMatchCaseInput,
9846 callBack: this.fibShowHideMatchCaseOption.name,
9847 class: this
9848 }, {
9849 selector: EditQuestion.selectors.elFibOptionComparisonInput,
9850 callBack: args => {
9851 const {
9852 e,
9853 target
9854 } = args;
9855 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
9856 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
9857 elBtnFibSaveContent.click();
9858 }
9859 }]);
9860
9861 // Toggle collapse
9862 document.addEventListener('click', e => {
9863 const target = e.target;
9864 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuestion.selectors.elTriggerToggle);
9865 });
9866
9867 // Event keyup
9868 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
9869 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
9870 callBack: this.checkCanAddAnswer.name,
9871 class: this
9872 }, {
9873 selector: EditQuestion.selectors.elFibOptionTitleInput,
9874 callBack: this.fibOptionTitleInputChange.name,
9875 class: this
9876 }, {
9877 selector: EditQuestion.selectors.elAutoSaveQuestion,
9878 callBack: this.autoUpdateQuestion.name,
9879 class: this
9880 }]);
9881
9882 // Event keydown
9883 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
9884 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
9885 callBack: this.addQuestionAnswer.name,
9886 class: this,
9887 checkIsEventEnter: true
9888 }]);
9889
9890 // Event change
9891 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
9892 selector: EditQuestion.selectors.elAutoSaveAnswer,
9893 callBack: this.autoUpdateAnswer.name,
9894 class: this
9895 }]);
9896
9897 // TinyMCE events
9898 this.eventEditorTinymce();
9899 }
9900
9901 // Run async to re-init all TinyMCE editors, because it slow if have many editors
9902 async initTinyMCE() {
9903 const elTextareas = document.querySelectorAll('.lp-editor-tinymce');
9904 elTextareas.forEach(elTextarea => {
9905 const idTextarea = elTextarea.id;
9906 this.reInitTinymce(idTextarea);
9907 });
9908 }
9909 reInitTinymce(id) {
9910 window.tinymce.execCommand('mceRemoveEditor', true, id);
9911 window.tinymce.execCommand('mceAddEditor', true, id);
9912 }
9913 reInitQuickTags(id) {
9914 const toolbar = document.getElementById(`qt_${id}_toolbar`);
9915 if (!toolbar || toolbar.children.length || !window.quicktags) {
9916 return;
9917 }
9918 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
9919 id
9920 };
9921 window.quicktags(settings);
9922 if (window.QTags?._buttonsInit) {
9923 window.QTags._buttonsInit();
9924 }
9925 }
9926 setDefaultEditorTab(id) {
9927 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
9928 if (!wrapEditor) {
9929 return;
9930 }
9931 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
9932 window.switchEditors.go(id, 'tmce');
9933 const elTextarea = document.getElementById(id);
9934 if (elTextarea) {
9935 elTextarea.style.visibility = '';
9936 }
9937 }
9938 wrapEditor.classList.add('tmce-active');
9939 wrapEditor.classList.remove('html-active');
9940 const visualTab = document.getElementById(`${id}-tmce`);
9941 const codeTab = document.getElementById(`${id}-html`);
9942 visualTab?.setAttribute('aria-pressed', 'true');
9943 codeTab?.setAttribute('aria-pressed', 'false');
9944 }
9945
9946 // Events for TinyMCE editor
9947 eventEditorTinymce() {
9948 window.tinymce.on('AddEditor', eEditor => {
9949 const id = eEditor.editor.id;
9950 const editor = window.tinymce.get(id);
9951 if (!editor) {
9952 return;
9953 }
9954 if (id === 'content') {
9955 return;
9956 }
9957 const elTextarea = document.getElementById(id);
9958 if (!elTextarea) {
9959 return;
9960 }
9961 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
9962
9963 // Skip if not in question edit context
9964 if (!elQuestionEditMain) {
9965 return;
9966 }
9967 const questionId = elQuestionEditMain.dataset.questionId;
9968 editor.settings.force_p_newlines = false;
9969 editor.settings.forced_root_block = '';
9970 editor.settings.force_br_newlines = true;
9971
9972 // Config use absolute url
9973 editor.settings.relative_urls = false;
9974 editor.settings.remove_script_host = false;
9975 editor.settings.convert_urls = true;
9976 editor.settings.document_base_url = lpData.site_url;
9977 // End config use absolute url
9978
9979 // Add quick tags
9980 this.reInitQuickTags(id);
9981
9982 // Events focus in TinyMCE editor
9983 editor.on('change keyup', e => {
9984 // Auto save if it has class lp-auto-save
9985 elTextarea.value = editor.getContent();
9986 this.autoUpdateQuestion({
9987 e,
9988 target: elTextarea
9989 });
9990 });
9991 editor.on('blur', e => {
9992 //console.log( 'Editor blurred:', e.target.id );
9993 });
9994 editor.on('focusin', e => {});
9995 editor.on('init', () => {
9996 // Add style
9997 editor.dom.addStyle(`
9998 body {
9999 line-height: 2.2 !important;
10000 }
10001 .${EditQuestion.selectors.elQuestionFibInput} {
10002 border: 1px dashed rebeccapurple;
10003 padding: 5px;
10004 }
10005 `);
10006
10007 // Set default tab visual
10008 this.setDefaultEditorTab(id);
10009 });
10010 editor.on('setcontent', e => {
10011 const uniquid = this.randomString();
10012 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
10013 if (elementg[0]) {
10014 elementg[0].focus();
10015 }
10016 editor.dom.bind(elementg[0], 'input', e => {
10017 //console.log( 'Input changed:', e.target.value );
10018 });
10019 });
10020 editor.on('selectionchange', e => {
10021 fibSelection = editor.selection;
10022
10023 // Check selection is blank, check empty blank content
10024 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10025 const blankId = fibSelection.getNode().dataset.id;
10026 const textBlank = fibSelection.getNode().textContent.trim();
10027 if (textBlank.length === 0) {
10028 const editorId = editor.id;
10029 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
10030 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
10031 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10032 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10033 if (elFibBlankOptionItem) {
10034 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
10035 }
10036 } else {
10037 const elTextarea = document.getElementById(id);
10038 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
10039 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10040 if (elFibBlankOptionItem) {
10041 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10042 if (elFibOptionTitleInput) {
10043 elFibOptionTitleInput.value = textBlank;
10044 }
10045 }
10046 }
10047 }
10048 });
10049 editor.on('Undo', e => {
10050 const contentUndo = editor.getContent();
10051 const selection = editor.selection;
10052 const nodeUndo = selection.getNode();
10053 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10054 const blankId = nodeUndo.dataset.id;
10055 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10056 if (elFibBlankOptionItem) {
10057 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
10058 }
10059 }
10060 });
10061 editor.on('Redo', e => {});
10062 });
10063 }
10064 autoUpdateQuestion(args) {
10065 let {
10066 e,
10067 target,
10068 key,
10069 value
10070 } = args;
10071 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
10072 if (!elAutoSave) {
10073 return;
10074 }
10075 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10076 const questionId = elQuestionEditMain.dataset.questionId;
10077 clearTimeout(timeoutAutoUpdateQuestion);
10078 timeoutAutoUpdateQuestion = setTimeout(() => {
10079 // Call ajax to update question description
10080 const callBack = {
10081 success: response => {
10082 const {
10083 message,
10084 status
10085 } = response;
10086 if (status === 'success') {
10087 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10088 } else {
10089 throw `Error: ${message}`;
10090 }
10091 },
10092 error: error => {
10093 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10094 },
10095 completed: () => {}
10096 };
10097 const dataSend = {
10098 action: 'update_question',
10099 question_id: questionId,
10100 args: {
10101 id_url: idUrlHandle
10102 }
10103 };
10104 if (undefined === key) {
10105 key = elAutoSave.dataset.keyAutoSave;
10106 if (!key) {
10107 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
10108 return;
10109 }
10110 const textAreaId = elAutoSave.id;
10111 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
10112 if (!key) {
10113 return;
10114 }
10115 }
10116 value = elAutoSave.value;
10117 }
10118 dataSend[key] = value;
10119 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10120 }, 700);
10121 }
10122 // Create question type
10123 createQuestionType(args) {
10124 const {
10125 e,
10126 target
10127 } = args;
10128 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
10129 if (!elBtnQuestionCreateType) {
10130 return;
10131 }
10132 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10133 if (!elQuestionEditMain) {
10134 return;
10135 }
10136 const questionId = elQuestionEditMain.dataset.questionId;
10137 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
10138 if (!elQuestionTypeNew) {
10139 return;
10140 }
10141 const questionType = elQuestionTypeNew.value.trim();
10142 if (!questionType) {
10143 const message = elQuestionTypeNew.dataset.messEmptyType;
10144 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10145 return;
10146 }
10147
10148 // Call ajax to create new question type
10149 const callBack = {
10150 success: response => {
10151 const {
10152 message,
10153 status,
10154 data
10155 } = response;
10156 if (status === 'success') {
10157 const {
10158 html_option_answers
10159 } = data;
10160 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10161 elAnswersConfig.outerHTML = html_option_answers;
10162 this.initTinyMCE();
10163 this.sortAbleQuestionAnswer(elQuestionEditMain);
10164 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10165 } else {
10166 throw `Error: ${message}`;
10167 }
10168 },
10169 error: error => {
10170 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10171 },
10172 completed: () => {}
10173 };
10174 const dataSend = {
10175 action: 'update_question',
10176 question_id: questionId,
10177 question_type: questionType,
10178 args: {
10179 id_url: idUrlHandle
10180 }
10181 };
10182 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10183 }
10184 addQuestionAnswer(args) {
10185 const {
10186 e,
10187 target
10188 } = args;
10189 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10190 if (!elQuestionAnswerItemAddNew) {
10191 return;
10192 }
10193 e.preventDefault();
10194 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
10195 if (!elQuestionAnswerTitleNewInput.value.trim()) {
10196 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
10197 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10198 return;
10199 }
10200 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10201 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
10202 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
10203 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10204 elQuestionAnswerNew.classList.remove('clone');
10205 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
10206 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
10207 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
10208 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
10209 elQuestionAnswerTitleInputNew.value = answerTitle;
10210 elQuestionAnswerTitleNewInput.value = '';
10211 const questionId = elQuestionEditMain.dataset.questionId;
10212
10213 // Call ajax to add new question answer
10214 const callBack = {
10215 success: response => {
10216 const {
10217 message,
10218 status,
10219 data
10220 } = response;
10221 if (status === 'success') {
10222 const {
10223 question_answer
10224 } = data;
10225 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
10226 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
10227
10228 // Set data lp-answers-config
10229 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10230 dataAnswers.push(question_answer);
10231 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10232 } else {
10233 throw `Error: ${message}`;
10234 }
10235 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10236 },
10237 error: error => {
10238 elQuestionAnswerNew.remove();
10239 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10240 },
10241 completed: () => {}
10242 };
10243 const dataSend = {
10244 action: 'add_question_answer',
10245 question_id: questionId,
10246 answer_title: answerTitle,
10247 args: {
10248 id_url: idUrlHandle
10249 }
10250 };
10251 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10252 }
10253
10254 // Check to enable or disable add new question button
10255 checkCanAddAnswer(args) {
10256 const {
10257 e,
10258 target
10259 } = args;
10260 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
10261 if (!elTrigger) {
10262 return;
10263 }
10264 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10265 if (!elQuestionAnswerItemAddNew) {
10266 return;
10267 }
10268 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
10269 if (!elBtnAddAnswer) {
10270 return;
10271 }
10272 const titleValue = elTrigger.value.trim();
10273 if (titleValue) {
10274 elBtnAddAnswer.classList.add('active');
10275 } else {
10276 elBtnAddAnswer.classList.remove('active');
10277 }
10278 }
10279
10280 // Auto update question answer
10281 autoUpdateAnswer(args) {
10282 const {
10283 e,
10284 target
10285 } = args;
10286 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10287 if (!elAutoSaveAnswer) {
10288 return;
10289 }
10290 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10291 clearTimeout(timeoutAutoUpdateAnswer);
10292 timeoutAutoUpdateAnswer = setTimeout(() => {
10293 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10294 const questionId = elQuestionEditMain.dataset.questionId;
10295 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10296 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10297
10298 // For both radio and checkbox.
10299 const dataAnswersOld = structuredClone(dataAnswers);
10300
10301 // Get position of answers
10302 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
10303 const answersPosition = {};
10304 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
10305 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
10306 });
10307
10308 //console.log( 'answersPosition', answersPosition );
10309
10310 dataAnswers.map((answer, k) => {
10311 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10312 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10313 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10314
10315 // Set title
10316 if (elInputAnswerTitle) {
10317 answer.title = elInputAnswerTitle.value.trim();
10318 }
10319
10320 // Set true answer
10321 if (elInputAnswerSetTrue) {
10322 if (elInputAnswerSetTrue.checked) {
10323 answer.is_true = 'yes';
10324 } else {
10325 answer.is_true = '';
10326 }
10327 }
10328
10329 // Set position
10330 if (answersPosition[answer.question_answer_id]) {
10331 answer.order = answersPosition[answer.question_answer_id];
10332 }
10333 return answer;
10334 });
10335
10336 //console.log( dataAnswers );
10337
10338 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10339
10340 // Call ajax to update answers config
10341 const callBack = {
10342 success: response => {
10343 const {
10344 message,
10345 status
10346 } = response;
10347 if (status === 'success') {} else {
10348 throw `Error: ${message}`;
10349 }
10350 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10351 },
10352 error: error => {
10353 // rollback changes to old data
10354 dataAnswersOld.forEach(answer => {
10355 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10356 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10357 if (answer.is_true === 'yes') {
10358 inputAnswerSetTrue.checked = true;
10359 }
10360 return answer;
10361 });
10362 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10363 },
10364 completed: () => {
10365 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10366 }
10367 };
10368 const dataSend = {
10369 action: 'update_question_answers_config',
10370 question_id: questionId,
10371 answers: dataAnswers,
10372 args: {
10373 id_url: idUrlHandle
10374 }
10375 };
10376 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10377 }, 700);
10378 }
10379
10380 // Sortable answers's question
10381 sortAbleQuestionAnswer(elQuestionEditMain) {
10382 let isUpdateSectionPosition = 0;
10383 let timeout;
10384 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
10385 elQuestionAnswers.forEach(elAnswersConfig => {
10386 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
10387 handle: '.drag',
10388 animation: 150,
10389 onEnd: evt => {
10390 const elQuestionAnswerItem = evt.item;
10391 if (!isUpdateSectionPosition) {
10392 // No change in section position, do nothing
10393 return;
10394 }
10395 clearTimeout(timeout);
10396 timeout = setTimeout(() => {
10397 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10398 this.autoUpdateAnswer({
10399 e: null,
10400 target: elAutoSaveAnswer
10401 });
10402 }, 1000);
10403 },
10404 onMove: evt => {
10405 clearTimeout(timeout);
10406 },
10407 onUpdate: evt => {
10408 isUpdateSectionPosition = 1;
10409 }
10410 });
10411 });
10412 }
10413
10414 // Delete question answer
10415 deleteQuestionAnswer(args) {
10416 const {
10417 e,
10418 target
10419 } = args;
10420 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
10421 if (!elBtnDeleteAnswer) {
10422 return;
10423 }
10424 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10425 if (!elQuestionAnswerItem) {
10426 return;
10427 }
10428 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10429 const questionId = elQuestionEditMain.dataset.questionId;
10430 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
10431 if (!questionId || !questionAnswerId) {
10432 return;
10433 }
10434 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10435 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
10436 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
10437 icon: 'warning',
10438 showCloseButton: true,
10439 showCancelButton: true,
10440 cancelButtonText: lpData.i18n.cancel,
10441 confirmButtonText: lpData.i18n.yes,
10442 reverseButtons: true
10443 }).then(result => {
10444 if (result.isConfirmed) {
10445 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10446
10447 // Call ajax to delete item from section
10448 const callBack = {
10449 success: response => {
10450 const {
10451 message,
10452 status
10453 } = response;
10454 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10455 if (status === 'success') {
10456 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
10457 elQuestionAnswerItem.remove();
10458 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10459 if (dataAnswers) {
10460 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
10461 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
10462 }
10463 }
10464 },
10465 error: error => {
10466 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10467 },
10468 completed: () => {
10469 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10470 }
10471 };
10472 const dataSend = {
10473 action: 'delete_question_answer',
10474 question_id: questionId,
10475 question_answer_id: questionAnswerId,
10476 args: {
10477 id_url: idUrlHandle
10478 }
10479 };
10480 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10481 }
10482 });
10483 }
10484
10485 // Get data answers config
10486 getDataAnswersConfig(elQuestionEditMain) {
10487 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10488 if (!elAnswersConfig) {
10489 return null;
10490 }
10491 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
10492 try {
10493 dataAnswers = JSON.parse(dataAnswers);
10494 } catch (e) {
10495 dataAnswers = [];
10496 }
10497 if (!dataAnswers.meta_data) {
10498 dataAnswers.meta_data = {};
10499 }
10500 return dataAnswers;
10501 }
10502
10503 // Set data answers config
10504 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
10505 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10506 if (!elAnswersConfig) {
10507 return;
10508 }
10509 if (!dataAnswers || typeof dataAnswers !== 'object') {
10510 dataAnswers = {};
10511 }
10512 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
10513 }
10514
10515 /***** Fill in the blank question type *****/
10516 // For FIB question type
10517 fibInsertBlank = args => {
10518 const {
10519 e,
10520 target
10521 } = args;
10522 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
10523 if (!elBtnFibInsertBlank) {
10524 return;
10525 }
10526 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
10527 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
10528 const questionId = elQuestionEditMain.dataset.questionId;
10529 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
10530 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
10531 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
10532 const uniquid = this.randomString();
10533 let selectedText;
10534 if (fibSelection) {
10535 const elNode = fibSelection.getNode();
10536 if (!elNode) {
10537 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
10538 return;
10539 }
10540 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
10541 if (!findParent) {
10542 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10543 return;
10544 }
10545 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10546 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
10547 return;
10548 }
10549 selectedText = fibSelection.getContent();
10550 if (selectedText.length === 0) {
10551 selectedText = textPlaceholder;
10552 }
10553 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
10554 fibSelection.setContent(elInputNew);
10555 } else {
10556 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10557 return;
10558 }
10559 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10560 dataAnswers.meta_data = dataAnswers.meta_data || {};
10561 // Convert array to object
10562 if (Object.keys(dataAnswers.meta_data).length === 0) {
10563 dataAnswers.meta_data = {};
10564 }
10565 dataAnswers.meta_data[uniquid] = {
10566 id: uniquid,
10567 match_case: 0,
10568 comparison: 'equal',
10569 fill: selectedText,
10570 index: 1,
10571 open: false
10572 };
10573 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10574
10575 // Clone blank options
10576 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10577 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
10578 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
10579 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
10580 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
10581 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10582 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10583 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
10584 elFibBlankOptionItemNew.dataset.id = uniquid;
10585 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
10586 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
10587 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
10588 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
10589 elFibOptionComparisonInput.forEach(elInput => {
10590 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
10591 if (elInput.value === 'equal') {
10592 elInput.checked = true;
10593 }
10594 });
10595 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
10596 elFibBlankOptionItemNew.classList.remove('clone');
10597 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
10598 // End clone blank options
10599
10600 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10601 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
10602 this.fibSaveContent({
10603 e: null,
10604 target: elBtnFibSaveContent,
10605 callBackCompleted: () => {
10606 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
10607 }
10608 });
10609 };
10610
10611 // Delete all blanks
10612 fibDeleteAllBlanks(args) {
10613 const {
10614 e,
10615 target
10616 } = args;
10617 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
10618 if (!elBtnFibDeleteAllBlanks) {
10619 return;
10620 }
10621 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10622 if (!elQuestionEditMain) {
10623 return;
10624 }
10625 const questionId = elQuestionEditMain.dataset.questionId;
10626 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10627 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10628 title: elBtnFibDeleteAllBlanks.dataset.title,
10629 text: elBtnFibDeleteAllBlanks.dataset.content,
10630 icon: 'warning',
10631 showCloseButton: true,
10632 showCancelButton: true,
10633 cancelButtonText: lpData.i18n.cancel,
10634 confirmButtonText: lpData.i18n.yes,
10635 reverseButtons: true
10636 }).then(result => {
10637 if (result.isConfirmed) {
10638 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10639 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
10640 elBlanks.forEach(elBlank => {
10641 editor.dom.remove(elBlank, true);
10642 });
10643 dataAnswers.meta_data = {};
10644 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10645 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10646 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10647 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10648 elFibBlankOptionItem.remove();
10649 });
10650 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10651 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
10652 this.fibSaveContent({
10653 e: null,
10654 target: elBtnFibSaveContent,
10655 callBackCompleted: () => {
10656 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
10657 }
10658 });
10659 }
10660 });
10661 }
10662 // Clear content FIB question
10663 fibClearContent(args) {
10664 const {
10665 e,
10666 target
10667 } = args;
10668 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
10669 if (!elBtnFibClearAllContent) {
10670 return;
10671 }
10672 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10673 if (!elQuestionEditMain) {
10674 return;
10675 }
10676 const questionId = elQuestionEditMain.dataset.questionId;
10677 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10678 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10679 title: elBtnFibClearAllContent.dataset.title,
10680 text: elBtnFibClearAllContent.dataset.content,
10681 icon: 'warning',
10682 showCloseButton: true,
10683 showCancelButton: true,
10684 cancelButtonText: lpData.i18n.cancel,
10685 confirmButtonText: lpData.i18n.yes,
10686 reverseButtons: true
10687 }).then(result => {
10688 if (result.isConfirmed) {
10689 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10690 editor.setContent('');
10691 dataAnswers.meta_data = {};
10692 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10693 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10694 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10695 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10696 elFibBlankOptionItem.remove();
10697 });
10698 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10699 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
10700 this.fibSaveContent({
10701 e: null,
10702 target: elBtnFibSaveContent,
10703 callBackCompleted: () => {
10704 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
10705 }
10706 });
10707 }
10708 });
10709 }
10710
10711 // Remove blank
10712 fibDeleteBlank(args) {
10713 const {
10714 e,
10715 target
10716 } = args;
10717 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
10718 if (!elBtnFibOptionDelete) {
10719 return;
10720 }
10721 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10722 if (!elQuestionEditMain) {
10723 return;
10724 }
10725 const questionId = elQuestionEditMain.dataset.questionId;
10726 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10727 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10728 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10729 const blankId = elFibBlankOptionItem.dataset.id;
10730 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10731 title: elBtnFibOptionDelete.dataset.title,
10732 text: elBtnFibOptionDelete.dataset.content,
10733 icon: 'warning',
10734 showCloseButton: true,
10735 showCancelButton: true,
10736 cancelButtonText: lpData.i18n.cancel,
10737 confirmButtonText: lpData.i18n.yes,
10738 reverseButtons: true
10739 }).then(result => {
10740 if (result.isConfirmed) {
10741 // Find span with id on editor and remove it
10742 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10743 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
10744 if (elBlank[0]) {
10745 // Remove tag html but keep content
10746 editor.dom.remove(elBlank[0], true);
10747 }
10748 elFibBlankOptionItem.remove();
10749 dataAnswers.meta_data = dataAnswers.meta_data || {};
10750 if (dataAnswers.meta_data[blankId]) {
10751 delete dataAnswers.meta_data[blankId];
10752 }
10753 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10754 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10755 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
10756 this.fibSaveContent({
10757 e: null,
10758 target: elBtnFibSaveContent,
10759 callBackCompleted: () => {
10760 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
10761 }
10762 });
10763 }
10764 });
10765 }
10766
10767 // Change title of blank option
10768 fibOptionTitleInputChange(args) {
10769 const {
10770 e,
10771 target
10772 } = args;
10773 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10774 if (!elFibOptionTitleInput) {
10775 return;
10776 }
10777 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10778 if (!elQuestionFibOptionItem) {
10779 return;
10780 }
10781 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10782 if (!elQuestionEditMain) {
10783 return;
10784 }
10785 const value = elFibOptionTitleInput.value.trim();
10786 const blankId = elQuestionFibOptionItem.dataset.id;
10787 const questionId = elQuestionEditMain.dataset.questionId;
10788 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10789 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
10790 if (elBlank[0]) {
10791 // Update content of blank
10792 elBlank[0].textContent = value;
10793 }
10794 clearTimeout(timeoutAutoUpdateFib);
10795 timeoutAutoUpdateFib = setTimeout(() => {
10796 // Call ajax to update question description
10797 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10798 this.fibSaveContent({
10799 e: null,
10800 target: elBtnFibSaveContent
10801 });
10802 }, 700);
10803 }
10804
10805 // Save content FIB question
10806 fibSaveContent(args) {
10807 const {
10808 e,
10809 target,
10810 callBackCompleted = null
10811 } = args;
10812 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10813 if (!elBtnFibSaveContent) {
10814 return;
10815 }
10816 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10817 const questionId = elQuestionEditMain.dataset.questionId;
10818 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10819 if (!dataAnswers) {
10820 return;
10821 }
10822 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10823 dataAnswers.title = editor.getContent();
10824 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10825 if (elFibBlankOptionItems) {
10826 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10827 const blankId = elFibBlankOptionItem.dataset.id;
10828 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10829 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
10830 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
10831 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
10832 });
10833 }
10834
10835 //console.log( 'dataAnswers', dataAnswers );
10836
10837 if (!callBackCompleted) {
10838 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
10839 }
10840
10841 // Call ajax to update answers config
10842 const callBack = {
10843 success: response => {
10844 const {
10845 message,
10846 status
10847 } = response;
10848 if (status === 'success') {
10849 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10850 } else {
10851 throw `Error: ${message}`;
10852 }
10853 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10854 },
10855 error: error => {
10856 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10857 },
10858 completed: () => {
10859 if (callBackCompleted && typeof callBackCompleted === 'function') {
10860 callBackCompleted();
10861 } else {
10862 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
10863 }
10864 }
10865 };
10866
10867 //console.log( 'dataAnswers', dataAnswers );
10868
10869 const dataSend = {
10870 action: 'update_question_answers_config',
10871 question_id: questionId,
10872 answers: dataAnswers,
10873 args: {
10874 id_url: idUrlHandle
10875 }
10876 };
10877 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10878 }
10879 // Show/hide match case option
10880 fibShowHideMatchCaseOption(args) {
10881 const {
10882 e,
10883 target
10884 } = args;
10885 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10886 if (!elFibOptionMatchCaseInput) {
10887 return;
10888 }
10889 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
10890 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
10891 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
10892 return;
10893 }
10894 if (elFibOptionMatchCaseInput.checked) {
10895 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
10896 } else {
10897 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
10898 }
10899 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10900 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10901 elBtnFibSaveContent.click();
10902 }
10903 /***** End Fill in the blank question type *****/
10904
10905 // Generate a random string of specified length, for set unique id
10906 randomString(length = 10) {
10907 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
10908 let result = '';
10909 for (let i = 0; i < length; i++) {
10910 result += chars.charAt(Math.floor(Math.random() * chars.length));
10911 }
10912 return result;
10913 }
10914 // Decode HTML entities
10915 decodeHtml(html) {
10916 const txt = document.createElement('textarea');
10917 txt.innerHTML = html;
10918 return txt.value;
10919 }
10920 }
10921 const editQuestion = new EditQuestion();
10922 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
10923 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
10924 if (!elEditQuestionWrap.classList.contains(findClass)) {
10925 return;
10926 }
10927 editQuestion.init();
10928 });
10929 })();
10930
10931 /******/ })()
10932 ;
10933 //# sourceMappingURL=edit-question.js.map