PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
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-curriculum.js

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

11,156 lines 395.7 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/admin/edit-curriculum/edit-section-item.js":
5 /*!******************************************************************!*\
6 !*** ./assets/src/js/admin/edit-curriculum/edit-section-item.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 */ addItemToSection: () => (/* binding */ addItemToSection),
14 /* harmony export */ addItemType: () => (/* binding */ addItemType),
15 /* harmony export */ addItemsSelectedToSection: () => (/* binding */ addItemsSelectedToSection),
16 /* harmony export */ backToSelectItems: () => (/* binding */ backToSelectItems),
17 /* harmony export */ cancelAddItemType: () => (/* binding */ cancelAddItemType),
18 /* harmony export */ cancelUpdateTitle: () => (/* binding */ cancelUpdateTitle),
19 /* harmony export */ changeTitle: () => (/* binding */ changeTitle),
20 /* harmony export */ changeTitleAddNew: () => (/* binding */ changeTitleAddNew),
21 /* harmony export */ chooseTabItemsType: () => (/* binding */ chooseTabItemsType),
22 /* harmony export */ deleteItem: () => (/* binding */ deleteItem),
23 /* harmony export */ focusTitleInput: () => (/* binding */ focusTitleInput),
24 /* harmony export */ init: () => (/* binding */ init),
25 /* harmony export */ removeItemSelected: () => (/* binding */ removeItemSelected),
26 /* harmony export */ searchTitleItemToSelect: () => (/* binding */ searchTitleItemToSelect),
27 /* harmony export */ selectItemsFromList: () => (/* binding */ selectItemsFromList),
28 /* harmony export */ showItemsSelected: () => (/* binding */ showItemsSelected),
29 /* harmony export */ showPopupItemsToSelect: () => (/* binding */ showPopupItemsToSelect),
30 /* harmony export */ sortAbleItem: () => (/* binding */ sortAbleItem),
31 /* harmony export */ updatePreviewItem: () => (/* binding */ updatePreviewItem),
32 /* harmony export */ updateTitle: () => (/* binding */ updateTitle)
33 /* harmony export */ });
34 /* harmony import */ var _share_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./share.js */ "./assets/src/js/admin/edit-curriculum/share.js");
35 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
36 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
37 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
38 /**
39 * Edit Section item Script on Curriculum
40 *
41 * @version 1.0.2
42 * @since 4.2.8.6
43 */
44
45
46
47 const className = {
48 ..._share_js__WEBPACK_IMPORTED_MODULE_0__.className,
49 elSectionListItems: '.section-list-items',
50 elItemClone: '.section-item.clone',
51 elSectionItem: '.section-item',
52 elBtnSelectItemType: '.lp-btn-select-item-type',
53 elAddItemTypeClone: '.lp-add-item-type.clone',
54 elSectionActions: '.section-actions',
55 elAddItemType: '.lp-add-item-type',
56 elAddItemTypeTitleInput: '.lp-add-item-type-title-input',
57 elBtnAddItemCancel: '.lp-btn-add-item-cancel',
58 elBtnAddItem: '.lp-btn-add-item',
59 elItemTitleInput: '.lp-item-title-input',
60 elBtnUpdateItemTitle: '.lp-btn-update-item-title',
61 elBtnCancelUpdateTitle: '.lp-btn-cancel-update-item-title',
62 elBtnDeleteItem: '.lp-btn-delete-item',
63 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
64 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
65 elPopupItemsToSelect: '.lp-popup-items-to-select',
66 elSelectItem: '.lp-select-item',
67 elListItemsWrap: '.list-items-wrap',
68 elListItems: '.list-items',
69 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
70 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
71 elBtnBackListItems: '.lp-btn-back-to-select-items',
72 elHeaderCountItemSelected: '.header-count-items-selected',
73 elListItemsSelected: '.list-items-selected',
74 elItemSelectedClone: '.li-item-selected.clone',
75 elItemSelected: '.li-item-selected',
76 elBtnSetPreviewItem: '.lp-btn-set-preview-item'
77 };
78 let {
79 courseId,
80 elCurriculumSections,
81 showToast,
82 lpUtils,
83 updateCountItems
84 } = _share_js__WEBPACK_IMPORTED_MODULE_0__;
85 const idUrlHandle = 'edit-course-curriculum';
86 const init = () => {
87 ({
88 courseId,
89 elCurriculumSections,
90 showToast,
91 lpUtils,
92 updateCountItems
93 } = _share_js__WEBPACK_IMPORTED_MODULE_0__);
94 };
95
96 // Add item type
97 const addItemType = (e, target) => {
98 const elBtnSelectItemType = target.closest(`${className.elBtnSelectItemType}`);
99 if (!elBtnSelectItemType) {
100 return;
101 }
102 const itemType = elBtnSelectItemType.dataset.itemType;
103 const itemPlaceholder = elBtnSelectItemType.dataset.placeholder;
104 const itemBtnAddText = elBtnSelectItemType.dataset.buttonAddText;
105 const elSection = elBtnSelectItemType.closest(`${className.elSection}`);
106 const elSectionActions = elSection.querySelector(`${className.elSectionActions}`);
107
108 // Insert input item type to add
109 const elAddItemTypeClone = elSectionActions.querySelector(`${className.elAddItemTypeClone}`);
110 const elNewItemByType = elAddItemTypeClone.cloneNode(true);
111 const elAddItemTypeInput = elNewItemByType.querySelector(`${className.elAddItemTypeTitleInput}`);
112 const elBtnAddItem = elNewItemByType.querySelector(`${className.elBtnAddItem}`);
113 elNewItemByType.classList.remove('clone');
114 elNewItemByType.classList.add(itemType);
115 lpUtils.lpShowHideEl(elNewItemByType, 1);
116 elAddItemTypeInput.setAttribute('placeholder', itemPlaceholder);
117 elAddItemTypeInput.dataset.itemType = itemType;
118 elBtnAddItem.textContent = itemBtnAddText;
119 elSectionActions.insertAdjacentElement('beforebegin', elNewItemByType);
120 elAddItemTypeInput.focus();
121 };
122
123 // Cancel add item type
124 const cancelAddItemType = (e, target) => {
125 const elBtnAddItemCancel = target.closest(`${className.elBtnAddItemCancel}`);
126 if (!elBtnAddItemCancel) {
127 return;
128 }
129 const elAddItemType = target.closest(`${className.elAddItemType}`);
130 if (elAddItemType) {
131 elAddItemType.remove();
132 }
133 };
134
135 // Add item to section
136 const addItemToSection = (e, target) => {
137 let canHandle = false;
138 if (target.closest(`${className.elBtnAddItem}`)) {
139 canHandle = true;
140 } else if (target.closest(`${className.elAddItemTypeTitleInput}`) && e.key === 'Enter') {
141 canHandle = true;
142 }
143 if (!canHandle) {
144 return;
145 }
146 e.preventDefault();
147 const elAddItemType = target.closest(`${className.elAddItemType}`);
148 const elSection = elAddItemType.closest(`${className.elSection}`);
149 const sectionId = elSection.dataset.sectionId;
150 const elAddItemTypeTitleInput = elAddItemType.querySelector(`${className.elAddItemTypeTitleInput}`);
151 const titleValue = elAddItemTypeTitleInput.value.trim();
152 const typeValue = elAddItemTypeTitleInput.dataset.itemType;
153 const message = elAddItemTypeTitleInput.dataset.messEmptyTitle;
154 if (titleValue.length === 0) {
155 showToast(message, 'error');
156 return;
157 }
158
159 // Clone new section item
160 const elItemClone = elSection.querySelector(`${className.elItemClone}`);
161 const elItemNew = elItemClone.cloneNode(true);
162 const elItemTitleInput = elItemNew.querySelector(`${className.elItemTitleInput}`);
163 elItemNew.classList.remove('clone');
164 elItemNew.classList.add(typeValue);
165 elItemNew.dataset.itemType = typeValue;
166 lpUtils.lpShowHideEl(elItemNew, 1);
167 lpUtils.lpSetLoadingEl(elItemNew, 1);
168 elItemTitleInput.value = titleValue;
169 elItemTitleInput.dataset.old = titleValue;
170 elItemClone.insertAdjacentElement('beforebegin', elItemNew);
171 elAddItemType.remove();
172
173 // Call ajax to add item to section
174 const callBack = {
175 success: response => {
176 const {
177 message,
178 status,
179 data
180 } = response;
181 showToast(message, status);
182 if (status === 'error') {
183 elItemNew.remove();
184 } else if (status === 'success') {
185 const {
186 section_item,
187 item_link
188 } = data || {};
189 elItemNew.dataset.itemId = section_item.item_id || 0;
190 elItemNew.querySelector('.edit-link').setAttribute('href', item_link || '');
191 }
192 },
193 error: error => {
194 showToast(error, 'error');
195 elItemNew.remove();
196 },
197 completed: () => {
198 lpUtils.lpSetLoadingEl(elItemNew, 0);
199 updateCountItems(elSection);
200 }
201 };
202 const dataSend = {
203 course_id: courseId,
204 action: 'create_item_add_to_section',
205 section_id: sectionId,
206 item_title: titleValue,
207 item_type: typeValue,
208 args: {
209 id_url: idUrlHandle
210 }
211 };
212 window.lpAJAXG.fetchAJAX(dataSend, callBack);
213 };
214
215 // Typing in title input
216 const changeTitle = (e, target) => {
217 const elItemTitleInput = target.closest(`${className.elItemTitleInput}`);
218 if (!elItemTitleInput) {
219 return;
220 }
221 const elSectionItem = elItemTitleInput.closest(`${className.elSectionItem}`);
222 if (!elSectionItem) {
223 return;
224 }
225 const titleValue = elItemTitleInput.value.trim();
226 const titleValueOld = elItemTitleInput.dataset.old || '';
227 if (titleValue === titleValueOld) {
228 elSectionItem.classList.remove('editing');
229 } else {
230 elSectionItem.classList.add('editing');
231 }
232 };
233
234 // Focus in item title input
235 const focusTitleInput = (e, target, isFocus = true) => {
236 const elItemTitleInput = target.closest(`${className.elItemTitleInput}`);
237 if (!elItemTitleInput) {
238 return;
239 }
240 const elSectionItem = elItemTitleInput.closest(`${className.elSectionItem}`);
241 if (!elSectionItem) {
242 return;
243 }
244 if (isFocus) {
245 elSectionItem.classList.add('focus');
246 } else {
247 elSectionItem.classList.remove('focus');
248 }
249 };
250 const changeTitleAddNew = (e, target) => {
251 const elAddItemTypeTitleInput = target.closest(`${className.elAddItemTypeTitleInput}`);
252 if (!elAddItemTypeTitleInput) {
253 return;
254 }
255 const elAddItemType = elAddItemTypeTitleInput.closest(`${className.elAddItemType}`);
256 if (!elAddItemType) {
257 return;
258 }
259 const elBtnAddItem = elAddItemType.querySelector(`${className.elBtnAddItem}`);
260 if (!elBtnAddItem) {
261 return;
262 }
263 const titleValue = elAddItemTypeTitleInput.value.trim();
264 if (titleValue.length === 0) {
265 elBtnAddItem.classList.remove('active');
266 } else {
267 elBtnAddItem.classList.add('active');
268 }
269 };
270
271 // Update item title
272 const updateTitle = (e, target) => {
273 let canHandle = false;
274 if (target.closest(`${className.elBtnUpdateItemTitle}`)) {
275 canHandle = true;
276 } else if (target.closest(`${className.elItemTitleInput}`) && e.key === 'Enter') {
277 canHandle = true;
278 }
279 if (!canHandle) {
280 return;
281 }
282 e.preventDefault();
283 const elSectionItem = target.closest(`${className.elSectionItem}`);
284 if (!elSectionItem) {
285 return;
286 }
287 const elSection = elSectionItem.closest(`${className.elSection}`);
288 if (!elSection) {
289 return;
290 }
291 const elItemTitleInput = elSectionItem.querySelector(`${className.elItemTitleInput}`);
292 if (!elItemTitleInput) {
293 return;
294 }
295 const itemId = elSectionItem.dataset.itemId;
296 const itemType = elSectionItem.dataset.itemType;
297 const itemTitleValue = elItemTitleInput.value.trim();
298 const titleOld = elItemTitleInput.dataset.old;
299 const message = elItemTitleInput.dataset.messEmptyTitle;
300 if (itemTitleValue.length === 0) {
301 showToast(message, 'error');
302 return;
303 }
304 if (itemTitleValue === titleOld) {
305 return;
306 }
307
308 // Un-focus input item title
309 elItemTitleInput.blur();
310 // show loading
311 lpUtils.lpSetLoadingEl(elSectionItem, 1);
312 // Call ajax to update item title
313 const callBack = {
314 success: response => {
315 const {
316 message,
317 status
318 } = response;
319 if (status === 'success') {
320 elItemTitleInput.dataset.old = itemTitleValue; // Update value input
321 } else {
322 elItemTitleInput.value = titleOld;
323 }
324 showToast(message, status);
325 },
326 error: error => {
327 showToast(error, 'error');
328 },
329 completed: () => {
330 lpUtils.lpSetLoadingEl(elSectionItem, 0);
331 elSectionItem.classList.remove('editing'); // Remove editing class
332 }
333 };
334 const dataSend = {
335 course_id: courseId,
336 action: 'update_item_of_section',
337 section_id: elSection.dataset.sectionId,
338 item_id: itemId,
339 item_type: itemType,
340 item_title: itemTitleValue,
341 args: {
342 id_url: idUrlHandle
343 }
344 };
345 window.lpAJAXG.fetchAJAX(dataSend, callBack);
346 };
347
348 // Cancel update item title
349 const cancelUpdateTitle = (e, target) => {
350 const elBtnCancelUpdateTitle = target.closest(`${className.elBtnCancelUpdateTitle}`);
351 if (!elBtnCancelUpdateTitle) {
352 return;
353 }
354 const elSectionItem = elBtnCancelUpdateTitle.closest(`${className.elSectionItem}`);
355 const elItemTitleInput = elSectionItem.querySelector(`${className.elItemTitleInput}`);
356 elItemTitleInput.value = elItemTitleInput.dataset.old || ''; // Reset to old value
357 elSectionItem.classList.remove('editing'); // Remove editing class
358 };
359
360 // Delete item from section
361 const deleteItem = (e, target) => {
362 const elBtnDeleteItem = target.closest(`${className.elBtnDeleteItem}`);
363 if (!elBtnDeleteItem) {
364 return;
365 }
366 const elSectionItem = elBtnDeleteItem.closest(`${className.elSectionItem}`);
367 if (!elSectionItem) {
368 return;
369 }
370 const itemId = elSectionItem.dataset.itemId;
371 const elSection = elSectionItem.closest(`${className.elSection}`);
372 const sectionId = elSection.dataset.sectionId;
373 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
374 title: elBtnDeleteItem.dataset.title,
375 text: elBtnDeleteItem.dataset.content,
376 icon: 'warning',
377 showCloseButton: true,
378 showCancelButton: true,
379 cancelButtonText: lpDataAdmin.i18n.cancel,
380 confirmButtonText: lpDataAdmin.i18n.yes,
381 reverseButtons: true
382 }).then(result => {
383 if (result.isConfirmed) {
384 lpUtils.lpSetLoadingEl(elSectionItem, 1);
385
386 // Call ajax to delete item from section
387 const callBack = {
388 success: response => {
389 const {
390 message,
391 status
392 } = response;
393 showToast(message, status);
394 if (status === 'success') {
395 elSectionItem.remove();
396 }
397 },
398 error: error => {
399 showToast(error, 'error');
400 },
401 completed: () => {
402 lpUtils.lpSetLoadingEl(elSectionItem, 0);
403 updateCountItems(elSection);
404 }
405 };
406 const dataSend = {
407 course_id: courseId,
408 action: 'delete_item_from_section',
409 section_id: sectionId,
410 item_id: itemId,
411 args: {
412 id_url: idUrlHandle
413 }
414 };
415 window.lpAJAXG.fetchAJAX(dataSend, callBack);
416 }
417 });
418 };
419
420 // Sortable items, can drop on multiple sections
421 const sortAbleItem = () => {
422 const elSectionListItems = elCurriculumSections.querySelectorAll(`${className.elSectionListItems}`);
423 let itemIdChoose = 0;
424 let elSectionChoose;
425 let sectionIdChoose = 0;
426 let sectionIdEnd = 0;
427 let timeout;
428 elSectionListItems.forEach(elItem => {
429 new sortablejs__WEBPACK_IMPORTED_MODULE_2__["default"](elItem, {
430 handle: '.drag',
431 animation: 150,
432 group: {
433 name: 'shared'
434 },
435 onEnd: evt => {
436 const dataSectionsItems = [];
437 const elItemDragged = evt.item;
438 sectionIdEnd = elItemDragged.closest(`${className.elSection}`).dataset.sectionId;
439 const dataSend = {
440 course_id: courseId,
441 args: {
442 id_url: idUrlHandle
443 }
444 };
445 if (sectionIdChoose === sectionIdEnd) {
446 // Update items position in the same section
447 dataSend.action = 'update_items_position';
448 dataSend.section_id = sectionIdEnd;
449 } else {
450 // Update section id of item changed
451 dataSend.action = 'update_item_section_and_position';
452 dataSend.item_id_change = itemIdChoose;
453 dataSend.section_id_new_of_item = sectionIdEnd;
454 dataSend.section_id_old_of_item = sectionIdChoose;
455 }
456
457 // Send list items position
458 const section = elCurriculumSections.querySelector(`.section[data-section-id="${sectionIdEnd}"]`);
459 const items = section.querySelectorAll(`${className.elSectionItem}`);
460 items.forEach(elItem => {
461 const itemId = parseInt(elItem.dataset.itemId || 0);
462 if (itemId === 0) {
463 return;
464 }
465 dataSectionsItems.push(itemId);
466 });
467 dataSend.items_position = dataSectionsItems;
468
469 // Call ajax to update items position
470 const callBack = {
471 success: response => {
472 const {
473 message,
474 status
475 } = response;
476 showToast(message, status);
477 },
478 error: error => {
479 showToast(error, 'error');
480 },
481 completed: () => {
482 lpUtils.lpSetLoadingEl(elItemDragged, 0);
483 updateCountItems(section);
484 if (sectionIdChoose !== sectionIdEnd) {
485 updateCountItems(elSectionChoose);
486 }
487 }
488 };
489
490 /*clearTimeout( timeout );
491 timeout = setTimeout( () => {
492 lpUtils.lpSetLoadingEl( elItemDragged, 1 );
493 window.lpAJAXG.fetchAJAX( dataSend, callBack );
494 }, 1000 );*/
495
496 lpUtils.lpSetLoadingEl(elItemDragged, 1);
497 window.lpAJAXG.fetchAJAX(dataSend, callBack);
498 },
499 onMove: evt => {
500 //clearTimeout( timeout );
501 },
502 onChoose: evt => {
503 const elChooseItem = evt.item;
504 itemIdChoose = elChooseItem.dataset.itemId;
505 elSectionChoose = elChooseItem.closest(`${className.elSection}`);
506 sectionIdChoose = elSectionChoose.dataset.sectionId;
507 },
508 onUpdate: evt => {}
509 });
510 });
511 };
512 let sectionIdSelected;
513 let elPopupSelectItems;
514 // Show popup items to select
515 const showPopupItemsToSelect = (e, target) => {
516 const elBtnShowPopupItemsToSelect = target.closest(`${className.elBtnShowPopupItemsToSelect}`);
517 if (!elBtnShowPopupItemsToSelect) {
518 return;
519 }
520 const elSection = elBtnShowPopupItemsToSelect.closest(`${className.elSection}`);
521 sectionIdSelected = elSection.dataset.sectionId;
522 const elPopupItemsToSelectClone = document.querySelector(`${className.elPopupItemsToSelectClone}`);
523 elPopupSelectItems = elPopupItemsToSelectClone.cloneNode(true);
524 elPopupSelectItems.classList.remove('clone');
525 lpUtils.lpShowHideEl(elPopupSelectItems, 1);
526 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
527 html: elPopupSelectItems,
528 showConfirmButton: false,
529 showCloseButton: true,
530 width: '60%',
531 customClass: {
532 popup: 'lp-select-items-popup',
533 htmlContainer: 'lp-select-items-html-container',
534 container: 'lp-select-items-container'
535 },
536 willOpen: () => {
537 // Trigger tab lesson to be active and call AJAX load items
538 const tabLesson = elPopupSelectItems.querySelector('li[data-type="lp_lesson"]');
539 tabLesson.click();
540 }
541 }).then(result => {
542 if (result.isDismissed) {}
543 });
544 };
545
546 // Choose tab items type
547 const chooseTabItemsType = (e, target) => {
548 const elTabType = target.closest('.tab');
549 if (!elTabType) {
550 return;
551 }
552 e.preventDefault();
553 const elTabs = elTabType.closest('.tabs');
554 if (!elTabs) {
555 return;
556 }
557 const elSelectItemsToAdd = elTabs.closest(`${className.elPopupItemsToSelect}`);
558 const elInputSearch = elSelectItemsToAdd.querySelector('.lp-search-title-item');
559 const itemType = elTabType.dataset.type;
560 const elTabLis = elTabs.querySelectorAll('.tab');
561 elTabLis.forEach(elTabLi => {
562 if (elTabLi.classList.contains('active')) {
563 elTabLi.classList.remove('active');
564 }
565 });
566 elTabType.classList.add('active');
567 // Reset search input
568 elInputSearch.value = '';
569 const elLPTarget = elSelectItemsToAdd.querySelector(`${className.LPTarget}`);
570 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
571 dataSend.args.item_type = itemType;
572 dataSend.args.paged = 1;
573 dataSend.args.item_selecting = itemsSelectedData || [];
574 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
575
576 // Show loading
577 window.lpAJAXG.showHideLoading(elLPTarget, 1);
578 // End
579
580 window.lpAJAXG.fetchAJAX(dataSend, {
581 success: response => {
582 const {
583 data
584 } = response;
585 elLPTarget.innerHTML = data.content || '';
586 },
587 error: error => {
588 showToast(error, 'error');
589 },
590 completed: () => {
591 window.lpAJAXG.showHideLoading(elLPTarget, 0);
592 // Show button add if there are items selected
593 watchItemsSelectedDataChange();
594 }
595 });
596 };
597 let itemsSelectedData = [];
598 // Choice items to add list items selected before adding to section
599 const selectItemsFromList = (e, target) => {
600 const elItemAttend = target.closest(`${className.elSelectItem}`);
601 if (!elItemAttend) {
602 return;
603 }
604 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
605 if (target.tagName !== 'INPUT') {
606 elInput.click();
607 return;
608 }
609 const elUl = elItemAttend.closest(`${className.elListItems}`);
610 if (!elUl) {
611 return;
612 }
613 const itemSelected = {
614 item_id: elInput.value,
615 item_type: elInput.dataset.type || '',
616 item_title: elInput.dataset.title || '',
617 item_edit_link: elInput.dataset.editLink || ''
618 };
619 if (elInput.checked) {
620 const exists = itemsSelectedData.some(item => item.item_id === itemSelected.item_id);
621 if (!exists) {
622 itemsSelectedData.push(itemSelected);
623 }
624 } else {
625 const index = itemsSelectedData.findIndex(item => item.item_id === itemSelected.item_id);
626 if (index !== -1) {
627 itemsSelectedData.splice(index, 1);
628 }
629 }
630 watchItemsSelectedDataChange();
631 };
632
633 // Search title item
634 let timeSearchTitleItem;
635 const searchTitleItemToSelect = (e, target) => {
636 const elInputSearch = target.closest('.lp-search-title-item');
637 if (!elInputSearch) {
638 return;
639 }
640 const elPopupItemsToSelect = elInputSearch.closest(`${className.elPopupItemsToSelect}`);
641 if (!elPopupItemsToSelect) {
642 return;
643 }
644 const elLPTarget = elPopupItemsToSelect.querySelector(`${className.LPTarget}`);
645 clearTimeout(timeSearchTitleItem);
646 timeSearchTitleItem = setTimeout(() => {
647 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
648 dataSet.args.search_title = elInputSearch.value.trim();
649 dataSet.args.item_selecting = itemsSelectedData;
650
651 // Show loading
652 window.lpAJAXG.showHideLoading(elLPTarget, 1);
653 window.lpAJAXG.fetchAJAX(dataSet, {
654 success: response => {
655 const {
656 data
657 } = response;
658 elLPTarget.innerHTML = data.content || '';
659 },
660 error: error => {
661 showToast(error, 'error');
662 },
663 completed: () => {
664 window.lpAJAXG.showHideLoading(elLPTarget, 0);
665 }
666 });
667 }, 1000);
668 };
669
670 // Show list of items, to choose items to add to section
671 const showItemsSelected = (e, target) => {
672 const elBtnCountItemsSelected = target.closest(`${className.elBtnCountItemsSelected}`);
673 if (!elBtnCountItemsSelected) {
674 return;
675 }
676 const elParent = elBtnCountItemsSelected.closest(`${className.elPopupItemsToSelect}`);
677 if (!elParent) {
678 return;
679 }
680 const elBtnBack = elParent.querySelector(`${className.elBtnBackListItems}`);
681 const elTabs = elParent.querySelector('.tabs');
682 const elListItemsWrap = elParent.querySelector(`${className.elListItemsWrap}`);
683 const elHeaderItemsSelected = elParent.querySelector(`${className.elHeaderCountItemSelected}`);
684 const elListItemsSelected = elParent.querySelector(`${className.elListItemsSelected}`);
685 const elItemClone = elListItemsSelected.querySelector(`${className.elItemSelectedClone}`);
686 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
687 lpUtils.lpShowHideEl(elListItemsWrap, 0);
688 lpUtils.lpShowHideEl(elBtnCountItemsSelected, 0);
689 lpUtils.lpShowHideEl(elTabs, 0);
690 lpUtils.lpShowHideEl(elBtnBack, 1);
691 lpUtils.lpShowHideEl(elHeaderItemsSelected, 1);
692 lpUtils.lpShowHideEl(elListItemsSelected, 1);
693 elListItemsSelected.querySelectorAll(`${className.elItemSelected}:not(.clone)`).forEach(elItem => {
694 elItem.remove();
695 });
696 itemsSelectedData.forEach(item => {
697 const elItemSelected = elItemClone.cloneNode(true);
698 elItemSelected.classList.remove('clone');
699 elItemSelected.dataset.id = item.item_id;
700 elItemSelected.dataset.type = item.item_type || '';
701 elItemSelected.querySelector('.item-title').textContent = item.item_title || '';
702 elItemSelected.querySelector('.item-id').textContent = item.item_id || '';
703 elItemSelected.querySelector('.item-type').textContent = item.item_type || '';
704 lpUtils.lpShowHideEl(elItemSelected, 1);
705 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
706 });
707 };
708
709 // Back to list of items
710 const backToSelectItems = (e, target) => {
711 const elBtnBack = target.closest(`${className.elBtnBackListItems}`);
712 if (!elBtnBack) {
713 return;
714 }
715 const elParent = elBtnBack.closest(`${className.elPopupItemsToSelect}`);
716 const elBtnCountItemsSelected = elParent.querySelector(`${className.elBtnCountItemsSelected}`);
717 const elTabs = elParent.querySelector('.tabs');
718 const elListItemsWrap = elParent.querySelector(`${className.elListItemsWrap}`);
719 const elHeaderCountItemSelected = elParent.querySelector(`${className.elHeaderCountItemSelected}`);
720 const elListItemsSelected = elParent.querySelector(`${className.elListItemsSelected}`);
721 lpUtils.lpShowHideEl(elBtnCountItemsSelected, 1);
722 lpUtils.lpShowHideEl(elListItemsWrap, 1);
723 lpUtils.lpShowHideEl(elTabs, 1);
724 lpUtils.lpShowHideEl(elBtnBack, 0);
725 lpUtils.lpShowHideEl(elHeaderCountItemSelected, 0);
726 lpUtils.lpShowHideEl(elListItemsSelected, 0);
727 };
728
729 // Remove item selected from list items selected
730 const removeItemSelected = (e, target) => {
731 const elRemoveItemSelected = target.closest(`${className.elItemSelected}`);
732 if (!elRemoveItemSelected) {
733 return;
734 }
735 const itemRemove = {
736 item_id: elRemoveItemSelected.dataset.id,
737 item_type: elRemoveItemSelected.dataset.type
738 };
739 const index = itemsSelectedData.findIndex(item => item.item_id === itemRemove.item_id);
740 if (index !== -1) {
741 itemsSelectedData.splice(index, 1);
742 }
743 elRemoveItemSelected.remove();
744 watchItemsSelectedDataChange();
745 };
746
747 // Watch items selected when data change
748 const watchItemsSelectedDataChange = () => {
749 if (!elPopupSelectItems) {
750 return;
751 }
752
753 // Update count items selected, disable/enable buttons
754 const elBtnAddItemsSelected = elPopupSelectItems.querySelector(`${className.elBtnAddItemsSelected}`);
755 const elBtnCountItemsSelected = elPopupSelectItems.querySelector(`${className.elBtnCountItemsSelected}`);
756 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
757 const elHeaderCount = elPopupSelectItems.querySelector(`${className.elHeaderCountItemSelected}`);
758 if (itemsSelectedData.length !== 0) {
759 elBtnCountItemsSelected.disabled = false;
760 elBtnAddItemsSelected.disabled = false;
761 elSpanCount.textContent = `(${itemsSelectedData.length})`;
762 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
763 } else {
764 elBtnCountItemsSelected.disabled = true;
765 elBtnAddItemsSelected.disabled = true;
766 elSpanCount.textContent = '';
767 elHeaderCount.textContent = '';
768 }
769 const elListItems = elPopupSelectItems.querySelector(`${className.elListItems}`);
770 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
771 elInputs.forEach(elInputItem => {
772 const itemSelected = {
773 item_id: elInputItem.value,
774 item_type: elInputItem.dataset.type || '',
775 item_title: elInputItem.dataset.title || ''
776 };
777 const exists = itemsSelectedData.some(item => item.item_id === itemSelected.item_id);
778 elInputItem.checked = exists;
779 });
780 };
781
782 // Add items selected to section
783 const addItemsSelectedToSection = (e, target) => {
784 const elBtnAddItems = target.closest(`${className.elBtnAddItemsSelected}`);
785 if (!elBtnAddItems) {
786 return;
787 }
788 const elPopupItemsToSelect = elBtnAddItems.closest(`${className.elPopupItemsToSelect}`);
789 if (!elPopupItemsToSelect) {
790 return;
791 }
792 const elSection = document.querySelector(`.section[data-section-id="${sectionIdSelected}"]`);
793 const elItemClone = elSection.querySelector(`${className.elItemClone}`);
794 itemsSelectedData.forEach(item => {
795 const elItemNew = elItemClone.cloneNode(true);
796 const elInputTitleNew = elItemNew.querySelector(`${className.elItemTitleInput}`);
797 elItemNew.dataset.itemId = item.item_id;
798 elItemNew.classList.add(item.item_type);
799 elItemNew.classList.remove('clone');
800 elItemNew.dataset.itemType = item.item_type;
801 elItemNew.querySelector('.edit-link').setAttribute('href', item.item_edit_link || '');
802 elInputTitleNew.value = item.item_title || '';
803 lpUtils.lpSetLoadingEl(elItemNew, 1);
804 lpUtils.lpShowHideEl(elItemNew, 1);
805 elItemClone.insertAdjacentElement('beforebegin', elItemNew);
806 });
807 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
808 const dataSend = {
809 course_id: courseId,
810 action: 'add_items_to_section',
811 section_id: sectionIdSelected,
812 items: itemsSelectedData,
813 args: {
814 id_url: idUrlHandle
815 }
816 };
817 window.lpAJAXG.fetchAJAX(dataSend, {
818 success: response => {
819 const {
820 message,
821 status
822 } = response;
823 showToast(message, status);
824 if (status === 'error') {
825 itemsSelectedData.forEach(item => {
826 const elItemAdded = elSection.querySelector(`${className.elSectionItem}[data-item-id="${item.item_id}"]`);
827 if (elItemAdded) {
828 elItemAdded.remove();
829 }
830 });
831 }
832 },
833 error: error => {
834 showToast(error, 'error');
835 },
836 completed: () => {
837 itemsSelectedData.forEach(item => {
838 const elItemAdded = elSection.querySelector(`${className.elSectionItem}[data-item-id="${item.item_id}"]`);
839 lpUtils.lpSetLoadingEl(elItemAdded, 0);
840 });
841 itemsSelectedData = []; // Clear selected items data
842 updateCountItems(elSection);
843 }
844 });
845 };
846
847 // Enable/disable preview item
848 const updatePreviewItem = (e, target) => {
849 const elBtnSetPreviewItem = target.closest(`${className.elBtnSetPreviewItem}`);
850 if (!elBtnSetPreviewItem) {
851 return;
852 }
853 const elSectionItem = elBtnSetPreviewItem.closest(`${className.elSectionItem}`);
854 if (!elSectionItem) {
855 return;
856 }
857 const icon = elBtnSetPreviewItem.querySelector('a');
858 icon.classList.toggle('lp-icon-eye');
859 icon.classList.toggle('lp-icon-eye-slash');
860 const enablePreview = !icon.classList.contains('lp-icon-eye-slash');
861 const itemId = elSectionItem.dataset.itemId;
862 const itemType = elSectionItem.dataset.itemType;
863 lpUtils.lpSetLoadingEl(elSectionItem, 1);
864
865 // Call ajax to update item preview
866 const callBack = {
867 success: response => {
868 const {
869 message,
870 status
871 } = response;
872 showToast(message, status);
873 if (status === 'error') {
874 icon.classList.toggle('lp-icon-eye');
875 icon.classList.toggle('lp-icon-eye-slash');
876 }
877 },
878 error: error => {
879 showToast(error, 'error');
880 icon.classList.toggle('lp-icon-eye');
881 icon.classList.toggle('lp-icon-eye-slash');
882 },
883 completed: () => {
884 lpUtils.lpSetLoadingEl(elSectionItem, 0);
885 }
886 };
887 const dataSend = {
888 course_id: courseId,
889 action: 'update_item_preview',
890 item_id: itemId,
891 item_type: itemType,
892 enable_preview: enablePreview ? 1 : 0,
893 args: {
894 id_url: idUrlHandle
895 }
896 };
897 window.lpAJAXG.fetchAJAX(dataSend, callBack);
898 };
899
900
901 /***/ }),
902
903 /***/ "./assets/src/js/admin/edit-curriculum/edit-section.js":
904 /*!*************************************************************!*\
905 !*** ./assets/src/js/admin/edit-curriculum/edit-section.js ***!
906 \*************************************************************/
907 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
908
909 "use strict";
910 __webpack_require__.r(__webpack_exports__);
911 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
912 /* harmony export */ addSection: () => (/* binding */ addSection),
913 /* harmony export */ cancelSectionDescription: () => (/* binding */ cancelSectionDescription),
914 /* harmony export */ cancelSectionTitle: () => (/* binding */ cancelSectionTitle),
915 /* harmony export */ changeDescription: () => (/* binding */ changeDescription),
916 /* harmony export */ changeTitle: () => (/* binding */ changeTitle),
917 /* harmony export */ changeTitleBeforeAdd: () => (/* binding */ changeTitleBeforeAdd),
918 /* harmony export */ deleteSection: () => (/* binding */ deleteSection),
919 /* harmony export */ focusTitleInput: () => (/* binding */ focusTitleInput),
920 /* harmony export */ focusTitleNewInput: () => (/* binding */ focusTitleNewInput),
921 /* harmony export */ init: () => (/* binding */ init),
922 /* harmony export */ setFocusTitleInput: () => (/* binding */ setFocusTitleInput),
923 /* harmony export */ sortAbleSection: () => (/* binding */ sortAbleSection),
924 /* harmony export */ toggleSection: () => (/* binding */ toggleSection),
925 /* harmony export */ updateSectionDescription: () => (/* binding */ updateSectionDescription),
926 /* harmony export */ updateSectionTitle: () => (/* binding */ updateSectionTitle)
927 /* harmony export */ });
928 /* harmony import */ var _share_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./share.js */ "./assets/src/js/admin/edit-curriculum/share.js");
929 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
930 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
931 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
932 /**
933 * Edit Section Script on Curriculum
934 *
935 * @since 4.2.8.6
936 * @version 1.0.2
937 */
938
939
940
941 const className = {
942 ..._share_js__WEBPACK_IMPORTED_MODULE_0__.className,
943 elDivAddNewSection: '.add-new-section',
944 elSectionClone: '.section.clone',
945 elSectionTitleNewInput: '.lp-section-title-new-input',
946 elSectionTitleInput: '.lp-section-title-input',
947 etBtnEditTitle: '.lp-btn-edit-section-title',
948 elSectionDesInput: '.lp-section-description-input',
949 elBtnAddSection: '.lp-btn-add-section',
950 elBtnUpdateTitle: '.lp-btn-update-section-title',
951 elBtnUpdateDes: '.lp-btn-update-section-description',
952 elBtnCancelUpdateTitle: '.lp-btn-cancel-update-section-title',
953 elBtnCancelUpdateDes: '.lp-btn-cancel-update-section-description',
954 elBtnDeleteSection: '.lp-btn-delete-section',
955 elSectionDesc: '.section-description',
956 elSectionToggle: '.section-toggle',
957 elCountSections: '.count-sections'
958 };
959 let {
960 courseId,
961 elEditCurriculum,
962 elCurriculumSections,
963 showToast,
964 lpUtils,
965 updateCountItems
966 } = _share_js__WEBPACK_IMPORTED_MODULE_0__;
967 const idUrlHandle = 'edit-course-curriculum';
968 const init = () => {
969 ({
970 courseId,
971 elEditCurriculum,
972 elCurriculumSections,
973 showToast,
974 lpUtils,
975 updateCountItems
976 } = _share_js__WEBPACK_IMPORTED_MODULE_0__);
977 };
978
979 // Typing in new section title input
980 const changeTitleBeforeAdd = (e, target) => {
981 const elSectionTitleNewInput = target.closest(`${className.elSectionTitleNewInput}`);
982 if (!elSectionTitleNewInput) {
983 return;
984 }
985 const elAddNewSection = elSectionTitleNewInput.closest(`${className.elDivAddNewSection}`);
986 if (!elAddNewSection) {
987 return;
988 }
989 const elBtnAddSection = elAddNewSection.querySelector(`${className.elBtnAddSection}`);
990 const titleValue = elSectionTitleNewInput.value.trim();
991 if (titleValue.length === 0) {
992 elBtnAddSection.classList.remove('active');
993 delete _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.titleNew;
994 } else {
995 elBtnAddSection.classList.add('active');
996 _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.titleNew = 1;
997 }
998 };
999
1000 // Focus on new section title input
1001 const focusTitleNewInput = (e, target, focusIn = true) => {
1002 const elSectionTitleNewInput = target.closest(`${className.elSectionTitleNewInput}`);
1003 if (!elSectionTitleNewInput) {
1004 return;
1005 }
1006 const elAddNewSection = elSectionTitleNewInput.closest(`${className.elDivAddNewSection}`);
1007 if (!elAddNewSection) {
1008 return;
1009 }
1010 if (focusIn) {
1011 elAddNewSection.classList.add('focus');
1012 } else {
1013 elAddNewSection.classList.remove('focus');
1014 }
1015 };
1016
1017 // Add new section
1018 const addSection = (e, target) => {
1019 let canHandle = false;
1020 if (target.closest(`${className.elBtnAddSection}`)) {
1021 canHandle = true;
1022 } else if (target.closest(`${className.elSectionTitleNewInput}`) && e.key === 'Enter') {
1023 canHandle = true;
1024 }
1025 if (!canHandle) {
1026 return;
1027 }
1028 const elAddNewSection = target.closest(`${className.elDivAddNewSection}`);
1029 if (!elAddNewSection) {
1030 return;
1031 }
1032 e.preventDefault();
1033 const elSectionTitleNewInput = elAddNewSection.querySelector(`${className.elSectionTitleNewInput}`);
1034 const titleValue = elSectionTitleNewInput.value.trim();
1035 const message = elSectionTitleNewInput.dataset.messEmptyTitle;
1036 if (titleValue.length === 0) {
1037 showToast(message, 'error');
1038 return;
1039 }
1040
1041 // Clear input after add
1042 elSectionTitleNewInput.value = '';
1043 elSectionTitleNewInput.blur();
1044
1045 // Add and set data for new section
1046 const elSectionClone = elCurriculumSections.querySelector(`${className.elSectionClone}`);
1047 const newSection = elSectionClone.cloneNode(true);
1048 newSection.classList.remove('clone');
1049 lpUtils.lpShowHideEl(newSection, 1);
1050 lpUtils.lpSetLoadingEl(newSection, 1);
1051 const elSectionTitleInput = newSection.querySelector(`${className.elSectionTitleInput}`);
1052 elSectionTitleInput.value = titleValue;
1053 elCurriculumSections.insertAdjacentElement('beforeend', newSection);
1054 // End
1055
1056 // Call ajax to add new section
1057 const callBack = {
1058 success: response => {
1059 const {
1060 message,
1061 status,
1062 data
1063 } = response;
1064 if (status === 'error') {
1065 newSection.remove();
1066 } else if (status === 'success') {
1067 const {
1068 section
1069 } = data;
1070 newSection.dataset.sectionId = section.section_id || '';
1071 if (_share_js__WEBPACK_IMPORTED_MODULE_0__.sortAbleItem) {
1072 _share_js__WEBPACK_IMPORTED_MODULE_0__.sortAbleItem();
1073 }
1074 }
1075 showToast(message, status);
1076 },
1077 error: error => {
1078 newSection.remove();
1079 showToast(error, 'error');
1080 },
1081 completed: () => {
1082 lpUtils.lpSetLoadingEl(newSection, 0);
1083 newSection.classList.remove(`${className.elCollapse}`);
1084 const elSectionDesInput = newSection.querySelector(`${className.elSectionDesInput}`);
1085 elSectionDesInput.focus();
1086 updateCountSections();
1087 delete _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.titleNew;
1088 }
1089 };
1090 const dataSend = {
1091 action: 'add_section',
1092 course_id: courseId,
1093 section_name: titleValue,
1094 args: {
1095 id_url: idUrlHandle
1096 }
1097 };
1098 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1099 };
1100
1101 // Delete section
1102 const deleteSection = (e, target) => {
1103 const elBtnDeleteSection = target.closest(`${className.elBtnDeleteSection}`);
1104 if (!elBtnDeleteSection) {
1105 return;
1106 }
1107 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
1108 title: elBtnDeleteSection.dataset.title,
1109 text: elBtnDeleteSection.dataset.content,
1110 icon: 'warning',
1111 showCloseButton: true,
1112 showCancelButton: true,
1113 cancelButtonText: lpDataAdmin.i18n.cancel,
1114 confirmButtonText: lpDataAdmin.i18n.yes,
1115 reverseButtons: true
1116 }).then(result => {
1117 if (result.isConfirmed) {
1118 const elSection = elBtnDeleteSection.closest('.section');
1119 const sectionId = elSection.dataset.sectionId;
1120 lpUtils.lpSetLoadingEl(elSection, 1);
1121
1122 // Call ajax to delete section
1123 const callBack = {
1124 success: response => {
1125 const {
1126 message,
1127 status
1128 } = response;
1129 const {
1130 content
1131 } = response.data;
1132 showToast(message, status);
1133 },
1134 error: error => {
1135 showToast(error, 'error');
1136 },
1137 completed: () => {
1138 lpUtils.lpSetLoadingEl(elSection, 0);
1139 elSection.remove();
1140 updateCountItems(elSection);
1141 updateCountSections();
1142 }
1143 };
1144 const dataSend = {
1145 action: 'delete_section',
1146 course_id: courseId,
1147 section_id: sectionId,
1148 args: {
1149 id_url: idUrlHandle
1150 }
1151 };
1152 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1153 }
1154 });
1155 };
1156
1157 // Focus on new section title input
1158 const focusTitleInput = (e, target, focusIn = true) => {
1159 const elSectionTitleInput = target.closest(`${className.elSectionTitleInput}`);
1160 if (!elSectionTitleInput) {
1161 return;
1162 }
1163 const elSection = elSectionTitleInput.closest(`${className.elSection}`);
1164 if (!elSection) {
1165 return;
1166 }
1167 if (focusIn) {
1168 elSection.classList.add('focus');
1169 } else {
1170 elSection.classList.remove('focus');
1171 }
1172 };
1173
1174 // Set focus on section title input
1175 const setFocusTitleInput = (e, target) => {
1176 const etBtnEditTitle = target.closest(`${className.etBtnEditTitle}`);
1177 if (!etBtnEditTitle) {
1178 return;
1179 }
1180 const elSection = etBtnEditTitle.closest(`${className.elSection}`);
1181 if (!elSection) {
1182 return;
1183 }
1184 const elSectionTitleInput = elSection.querySelector(`${className.elSectionTitleInput}`);
1185 elSectionTitleInput.setSelectionRange(elSectionTitleInput.value.length, elSectionTitleInput.value.length);
1186 elSectionTitleInput.focus();
1187 };
1188
1189 // Typing in description input
1190 const changeTitle = (e, target) => {
1191 const elSectionTitleInput = target.closest(`${className.elSectionTitleInput}`);
1192 if (!elSectionTitleInput) {
1193 return;
1194 }
1195 const elSection = elSectionTitleInput.closest(`${className.elSection}`);
1196 const titleValue = elSectionTitleInput.value.trim();
1197 const titleValueOld = elSectionTitleInput.dataset.old || '';
1198 if (titleValue === titleValueOld) {
1199 elSection.classList.remove('editing');
1200 delete _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.title;
1201 } else {
1202 elSection.classList.add('editing');
1203 _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.title = 1;
1204 }
1205 };
1206
1207 // Update section title to server
1208 const updateSectionTitle = (e, target) => {
1209 let canHandle = false;
1210 if (target.closest(`${className.elBtnUpdateTitle}`)) {
1211 canHandle = true;
1212 } else if (target.closest(`${className.elSectionTitleInput}`) && e.key === 'Enter') {
1213 canHandle = true;
1214 }
1215 if (!canHandle) {
1216 return;
1217 }
1218 e.preventDefault();
1219 const elSection = target.closest(`${className.elSection}`);
1220 if (!elSection) {
1221 return;
1222 }
1223 const elSectionTitleInput = elSection.querySelector(`${className.elSectionTitleInput}`);
1224 if (!elSectionTitleInput) {
1225 return;
1226 }
1227 const sectionId = elSection.dataset.sectionId;
1228 const titleValue = elSectionTitleInput.value.trim();
1229 const titleValueOld = elSectionTitleInput.dataset.old || '';
1230 const message = elSectionTitleInput.dataset.messEmptyTitle;
1231 if (titleValue.length === 0) {
1232 showToast(message, 'error');
1233 return;
1234 }
1235 if (titleValue === titleValueOld) {
1236 return;
1237 }
1238 elSectionTitleInput.blur();
1239 lpUtils.lpSetLoadingEl(elSection, 1);
1240
1241 // Call ajax to update section title
1242 const callBack = {
1243 success: response => {
1244 const {
1245 message,
1246 status
1247 } = response;
1248 showToast(message, status);
1249 if (status === 'success') {
1250 elSectionTitleInput.dataset.old = titleValue;
1251 }
1252 },
1253 error: error => {
1254 showToast(error, 'error');
1255 },
1256 completed: () => {
1257 lpUtils.lpSetLoadingEl(elSection, 0);
1258 elSection.classList.remove('editing');
1259 delete _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.title;
1260 }
1261 };
1262 const dataSend = {
1263 action: 'update_section',
1264 course_id: courseId,
1265 section_id: sectionId,
1266 section_name: titleValue,
1267 args: {
1268 id_url: idUrlHandle
1269 }
1270 };
1271 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1272 };
1273
1274 // Cancel updating section description
1275 const cancelSectionTitle = (e, target) => {
1276 const elBtnCancelUpdateTitle = target.closest(`${className.elBtnCancelUpdateTitle}`);
1277 if (!elBtnCancelUpdateTitle) {
1278 return;
1279 }
1280 const elSection = elBtnCancelUpdateTitle.closest(`${className.elSection}`);
1281 const elSectionTitleInput = elSection.querySelector(`${className.elSectionTitleInput}`);
1282 elSectionTitleInput.value = elSectionTitleInput.dataset.old || ''; // Reset to old value
1283 elSection.classList.remove('editing'); // Remove editing class
1284 delete _share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange.title;
1285 };
1286
1287 // Update section description to server
1288 const updateSectionDescription = (e, target) => {
1289 let canHandle = false;
1290 if (target.closest(`${className.elBtnUpdateDes}`)) {
1291 canHandle = true;
1292 } else if (target.closest(`${className.elSectionDesInput}`) && e.key === 'Enter') {
1293 canHandle = true;
1294 }
1295 if (!canHandle) {
1296 return;
1297 }
1298 e.preventDefault();
1299 const elSectionDesc = target.closest(`${className.elSectionDesc}`);
1300 if (!elSectionDesc) {
1301 return;
1302 }
1303 const elSectionDesInput = elSectionDesc.querySelector(`${className.elSectionDesInput}`);
1304 if (!elSectionDesInput) {
1305 return;
1306 }
1307 const elSection = elSectionDesInput.closest(`${className.elSection}`);
1308 const sectionId = elSection.dataset.sectionId;
1309 const descValue = elSectionDesInput.value.trim();
1310 const descValueOld = elSectionDesInput.dataset.old || '';
1311 if (descValue === descValueOld) {
1312 return;
1313 }
1314 lpUtils.lpSetLoadingEl(elSection, 1);
1315
1316 // Call ajax to update section description
1317 const callBack = {
1318 success: response => {
1319 const {
1320 message,
1321 status
1322 } = response;
1323 showToast(message, status);
1324 },
1325 error: error => {
1326 showToast(error, 'error');
1327 },
1328 completed: () => {
1329 lpUtils.lpSetLoadingEl(elSection, 0);
1330 const elSectionDesc = elSectionDesInput.closest(`${className.elSectionDesc}`);
1331 elSectionDesc.classList.remove('editing');
1332 elSectionDesInput.dataset.old = descValue; // Update old value
1333 }
1334 };
1335 const dataSend = {
1336 action: 'update_section',
1337 course_id: courseId,
1338 section_id: sectionId,
1339 section_description: descValue,
1340 args: {
1341 id_url: idUrlHandle
1342 }
1343 };
1344 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1345 };
1346
1347 // Cancel updating section description
1348 const cancelSectionDescription = (e, target) => {
1349 const elBtnCancelUpdateDes = target.closest(`${className.elBtnCancelUpdateDes}`);
1350 if (!elBtnCancelUpdateDes) {
1351 return;
1352 }
1353 const elSectionDesc = elBtnCancelUpdateDes.closest(`${className.elSectionDesc}`);
1354 const elSectionDesInput = elSectionDesc.querySelector(`${className.elSectionDesInput}`);
1355 elSectionDesInput.value = elSectionDesInput.dataset.old || ''; // Reset to old value
1356 elSectionDesc.classList.remove('editing'); // Remove editing class
1357 };
1358
1359 // Typing in description input
1360 const changeDescription = (e, target) => {
1361 const elSectionDesInput = target.closest(`${className.elSectionDesInput}`);
1362 if (!elSectionDesInput) {
1363 return;
1364 }
1365 const elSectionDesc = elSectionDesInput.closest(`${className.elSectionDesc}`);
1366 const descValue = elSectionDesInput.value.trim();
1367 const descValueOld = elSectionDesInput.dataset.old || '';
1368 if (descValue === descValueOld) {
1369 elSectionDesc.classList.remove('editing');
1370 } else {
1371 elSectionDesc.classList.add('editing');
1372 }
1373 };
1374
1375 // Toggle section
1376 const toggleSection = (e, target) => {
1377 const elSectionToggle = target.closest(`${className.elSectionToggle}`);
1378 if (!elSectionToggle) {
1379 return;
1380 }
1381 const elSection = elSectionToggle.closest(`${className.elSection}`);
1382 const elCurriculumSections = elSection.closest(`${className.elCurriculumSections}`);
1383 if (!elCurriculumSections) {
1384 return;
1385 }
1386
1387 // Toggle section
1388 elSection.classList.toggle(`${className.elCollapse}`);
1389
1390 // Check all sections collapsed
1391 checkAllSectionsCollapsed();
1392 };
1393
1394 // Check if all sections are collapsed
1395 const checkAllSectionsCollapsed = () => {
1396 const elSections = elEditCurriculum.querySelectorAll(`${className.elSection}:not(.clone)`);
1397 const elToggleAllSections = elEditCurriculum.querySelector(`${className.elToggleAllSections}`);
1398 let isAllExpand = true;
1399 elSections.forEach(el => {
1400 if (el.classList.contains(`${className.elCollapse}`)) {
1401 isAllExpand = false;
1402 return false; // Break the loop
1403 }
1404 });
1405 if (isAllExpand) {
1406 elToggleAllSections.classList.remove(`${className.elCollapse}`);
1407 } else {
1408 elToggleAllSections.classList.add(`${className.elCollapse}`);
1409 }
1410 };
1411
1412 // Sortable sections, drag and drop to change section position
1413 const sortAbleSection = () => {
1414 let isUpdateSectionPosition = 0;
1415 let timeout;
1416 new sortablejs__WEBPACK_IMPORTED_MODULE_2__["default"](elCurriculumSections, {
1417 handle: '.drag',
1418 animation: 150,
1419 onEnd: evt => {
1420 const target = evt.item;
1421 if (!isUpdateSectionPosition) {
1422 // No change in section position, do nothing
1423 return;
1424 }
1425 const elSection = target.closest(`${className.elSection}`);
1426 const elSections = elCurriculumSections.querySelectorAll(`${className.elSection}`);
1427 const sectionIds = [];
1428 elSections.forEach((elSection, index) => {
1429 const sectionId = elSection.dataset.sectionId;
1430 sectionIds.push(sectionId);
1431 });
1432
1433 // Call ajax to update section position
1434 const callBack = {
1435 success: response => {
1436 const {
1437 message,
1438 status
1439 } = response;
1440 showToast(message, status);
1441 },
1442 error: error => {
1443 showToast(error, 'error');
1444 },
1445 completed: () => {
1446 lpUtils.lpSetLoadingEl(elSection, 0);
1447 isUpdateSectionPosition = 0;
1448 }
1449 };
1450 const dataSend = {
1451 action: 'update_section_position',
1452 course_id: courseId,
1453 new_position: sectionIds,
1454 args: {
1455 id_url: idUrlHandle
1456 }
1457 };
1458 clearTimeout(timeout);
1459 timeout = setTimeout(() => {
1460 lpUtils.lpSetLoadingEl(elSection, 1);
1461 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1462 }, 1000);
1463 },
1464 onMove: evt => {
1465 clearTimeout(timeout);
1466 },
1467 onUpdate: evt => {
1468 isUpdateSectionPosition = 1;
1469 }
1470 });
1471 };
1472
1473 // Update count sections, when add or delete section
1474 const updateCountSections = () => {
1475 const elCountSections = elEditCurriculum.querySelector(`${className.elCountSections}`);
1476 const elSections = elCurriculumSections.querySelectorAll(`${className.elSection}:not(.clone)`);
1477 const sectionsCount = elSections.length;
1478 elCountSections.dataset.count = sectionsCount;
1479 elCountSections.querySelector('.count').textContent = sectionsCount;
1480 };
1481
1482
1483 /***/ }),
1484
1485 /***/ "./assets/src/js/admin/edit-curriculum/share.js":
1486 /*!******************************************************!*\
1487 !*** ./assets/src/js/admin/edit-curriculum/share.js ***!
1488 \******************************************************/
1489 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1490
1491 "use strict";
1492 __webpack_require__.r(__webpack_exports__);
1493 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1494 /* harmony export */ className: () => (/* binding */ className),
1495 /* harmony export */ courseId: () => (/* binding */ courseId),
1496 /* harmony export */ elCurriculumSections: () => (/* binding */ elCurriculumSections),
1497 /* harmony export */ elEditCurriculum: () => (/* binding */ elEditCurriculum),
1498 /* harmony export */ hasChange: () => (/* binding */ hasChange),
1499 /* harmony export */ lpUtils: () => (/* reexport module object */ _utils_js__WEBPACK_IMPORTED_MODULE_0__),
1500 /* harmony export */ setVariable: () => (/* binding */ setVariable),
1501 /* harmony export */ setVariables: () => (/* binding */ setVariables),
1502 /* harmony export */ showToast: () => (/* binding */ showToast),
1503 /* harmony export */ sortAbleItem: () => (/* binding */ sortAbleItem),
1504 /* harmony export */ updateCountItems: () => (/* binding */ updateCountItems)
1505 /* harmony export */ });
1506 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
1507 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1508 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_1__);
1509 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
1510 /**
1511 * Share variables and functions for the edit curriculum page.
1512 *
1513 * @since 4.2.8.6
1514 * @version 1.0.1
1515 */
1516
1517
1518
1519 let courseId;
1520 let elEditCurriculum;
1521 let elCurriculumSections;
1522 let updateCountItems;
1523 let sortAbleItem;
1524 let hasChange;
1525 const className = {
1526 idElEditCurriculum: '#lp-course-edit-curriculum',
1527 elCurriculumSections: '.curriculum-sections',
1528 elSection: '.section',
1529 elToggleAllSections: '.course-toggle-all-sections',
1530 elSectionItem: '.section-item',
1531 LPTarget: '.lp-target',
1532 elCollapse: 'lp-collapse'
1533 };
1534 const argsToastify = {
1535 text: '',
1536 gravity: lpDataAdmin.toast.gravity,
1537 // `top` or `bottom`
1538 position: lpDataAdmin.toast.position,
1539 // `left`, `center` or `right`
1540 className: `${lpDataAdmin.toast.classPrefix}`,
1541 close: lpDataAdmin.toast.close == 1,
1542 stopOnFocus: lpDataAdmin.toast.stopOnFocus == 1,
1543 duration: lpDataAdmin.toast.duration
1544 };
1545 const showToast = (message, status = 'success') => {
1546 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_1___default())({
1547 ...argsToastify,
1548 text: message,
1549 className: `${lpDataAdmin.toast.classPrefix} ${status}`
1550 });
1551 toastify.showToast();
1552 };
1553 const setVariables = variables => {
1554 ({
1555 courseId,
1556 elEditCurriculum,
1557 elCurriculumSections,
1558 updateCountItems,
1559 hasChange
1560 } = variables);
1561 };
1562 const setVariable = (variable, value) => {
1563 if (variable && value !== undefined) {
1564 switch (variable) {
1565 case 'sortAbleItem':
1566 sortAbleItem = value;
1567 break;
1568 }
1569 }
1570 };
1571
1572
1573 /***/ }),
1574
1575 /***/ "./assets/src/js/utils.js":
1576 /*!********************************!*\
1577 !*** ./assets/src/js/utils.js ***!
1578 \********************************/
1579 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1580
1581 "use strict";
1582 __webpack_require__.r(__webpack_exports__);
1583 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1584 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1585 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1586 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1587 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1588 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1589 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1590 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1591 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1592 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1593 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1594 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1595 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1596 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1597 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
1598 /* harmony export */ });
1599 /**
1600 * Utils functions
1601 *
1602 * @param url
1603 * @param data
1604 * @param functions
1605 * @since 4.2.5.1
1606 * @version 1.0.4
1607 */
1608 const lpClassName = {
1609 hidden: 'lp-hidden',
1610 loading: 'loading',
1611 elCollapse: 'lp-collapse',
1612 elSectionToggle: '.lp-section-toggle',
1613 elTriggerToggle: '.lp-trigger-toggle'
1614 };
1615 const lpFetchAPI = (url, data = {}, functions = {}) => {
1616 if ('function' === typeof functions.before) {
1617 functions.before();
1618 }
1619 fetch(url, {
1620 method: 'GET',
1621 ...data
1622 }).then(response => response.json()).then(response => {
1623 if ('function' === typeof functions.success) {
1624 functions.success(response);
1625 }
1626 }).catch(err => {
1627 if ('function' === typeof functions.error) {
1628 functions.error(err);
1629 }
1630 }).finally(() => {
1631 if ('function' === typeof functions.completed) {
1632 functions.completed();
1633 }
1634 });
1635 };
1636
1637 /**
1638 * Get current URL without params.
1639 *
1640 * @since 4.2.5.1
1641 */
1642 const lpGetCurrentURLNoParam = () => {
1643 let currentUrl = window.location.href;
1644 const hasParams = currentUrl.includes('?');
1645 if (hasParams) {
1646 currentUrl = currentUrl.split('?')[0];
1647 }
1648 return currentUrl;
1649 };
1650 const lpAddQueryArgs = (endpoint, args) => {
1651 const url = new URL(endpoint);
1652 Object.keys(args).forEach(arg => {
1653 url.searchParams.set(arg, args[arg]);
1654 });
1655 return url;
1656 };
1657
1658 /**
1659 * Listen element viewed.
1660 *
1661 * @param el
1662 * @param callback
1663 * @since 4.2.5.8
1664 */
1665 const listenElementViewed = (el, callback) => {
1666 const observerSeeItem = new IntersectionObserver(function (entries) {
1667 for (const entry of entries) {
1668 if (entry.isIntersecting) {
1669 callback(entry);
1670 }
1671 }
1672 });
1673 observerSeeItem.observe(el);
1674 };
1675
1676 /**
1677 * Listen element created.
1678 *
1679 * @param callback
1680 * @since 4.2.5.8
1681 */
1682 const listenElementCreated = callback => {
1683 const observerCreateItem = new MutationObserver(function (mutations) {
1684 mutations.forEach(function (mutation) {
1685 if (mutation.addedNodes) {
1686 mutation.addedNodes.forEach(function (node) {
1687 if (node.nodeType === 1) {
1688 callback(node);
1689 }
1690 });
1691 }
1692 });
1693 });
1694 observerCreateItem.observe(document, {
1695 childList: true,
1696 subtree: true
1697 });
1698 // End.
1699 };
1700
1701 /**
1702 * Listen element created.
1703 *
1704 * @param selector
1705 * @param callback
1706 * @since 4.2.7.1
1707 */
1708 const lpOnElementReady = (selector, callback) => {
1709 const element = document.querySelector(selector);
1710 if (element) {
1711 callback(element);
1712 return;
1713 }
1714 const observer = new MutationObserver((mutations, obs) => {
1715 const element = document.querySelector(selector);
1716 if (element) {
1717 obs.disconnect();
1718 callback(element);
1719 }
1720 });
1721 observer.observe(document.documentElement, {
1722 childList: true,
1723 subtree: true
1724 });
1725 };
1726
1727 // Parse JSON from string with content include LP_AJAX_START.
1728 const lpAjaxParseJsonOld = data => {
1729 if (typeof data !== 'string') {
1730 return data;
1731 }
1732 const m = String.raw({
1733 raw: data
1734 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1735 try {
1736 if (m) {
1737 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1738 } else {
1739 data = JSON.parse(data);
1740 }
1741 } catch (e) {
1742 data = {};
1743 }
1744 return data;
1745 };
1746
1747 // status 0: hide, 1: show
1748 const lpShowHideEl = (el, status = 0) => {
1749 if (!el) {
1750 return;
1751 }
1752 if (!status) {
1753 el.classList.add(lpClassName.hidden);
1754 } else {
1755 el.classList.remove(lpClassName.hidden);
1756 }
1757 };
1758
1759 // status 0: hide, 1: show
1760 const lpSetLoadingEl = (el, status) => {
1761 if (!el) {
1762 return;
1763 }
1764 if (!status) {
1765 el.classList.remove(lpClassName.loading);
1766 } else {
1767 el.classList.add(lpClassName.loading);
1768 }
1769 };
1770
1771 // Toggle collapse section
1772 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1773 if (!elTriggerClassName) {
1774 elTriggerClassName = lpClassName.elTriggerToggle;
1775 }
1776
1777 // Exclude elements, which should not trigger the collapse toggle
1778 if (elsExclude && elsExclude.length > 0) {
1779 for (const elExclude of elsExclude) {
1780 if (target.closest(elExclude)) {
1781 return;
1782 }
1783 }
1784 }
1785 const elTrigger = target.closest(elTriggerClassName);
1786 if (!elTrigger) {
1787 return;
1788 }
1789
1790 //console.log( 'elTrigger', elTrigger );
1791
1792 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1793 if (!elSectionToggle) {
1794 return;
1795 }
1796 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1797 if ('function' === typeof callback) {
1798 callback(elSectionToggle);
1799 }
1800 };
1801
1802 // Get data of form
1803 const getDataOfForm = form => {
1804 const dataSend = {};
1805 const formData = new FormData(form);
1806 for (const pair of formData.entries()) {
1807 const key = pair[0];
1808 const value = formData.getAll(key);
1809 if (!dataSend.hasOwnProperty(key)) {
1810 dataSend[key] = value;
1811 }
1812 }
1813 return dataSend;
1814 };
1815
1816 // Get field keys of form
1817 const getFieldKeysOfForm = form => {
1818 const keys = [];
1819 const elements = form.elements;
1820 for (let i = 0; i < elements.length; i++) {
1821 const name = elements[i].name;
1822 if (name && !keys.includes(name)) {
1823 keys.push(name);
1824 }
1825 }
1826 return keys;
1827 };
1828
1829 // Merge data handle with data form.
1830 const mergeDataWithDatForm = (elForm, dataHandle) => {
1831 const dataForm = getDataOfForm(elForm);
1832 const keys = getFieldKeysOfForm(elForm);
1833 keys.forEach(key => {
1834 if (!dataForm.hasOwnProperty(key)) {
1835 delete dataHandle[key];
1836 } else if (dataForm[key][0] === '') {
1837 delete dataForm[key];
1838 delete dataHandle[key];
1839 }
1840 });
1841 dataHandle = {
1842 ...dataHandle,
1843 ...dataForm
1844 };
1845 return dataHandle;
1846 };
1847
1848 /***/ }),
1849
1850 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css":
1851 /*!*****************************************************************************************!*\
1852 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
1853 \*****************************************************************************************/
1854 /***/ ((module, __webpack_exports__, __webpack_require__) => {
1855
1856 "use strict";
1857 __webpack_require__.r(__webpack_exports__);
1858 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1859 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1860 /* harmony export */ });
1861 /* 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");
1862 /* 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__);
1863 /* 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");
1864 /* 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__);
1865 // Imports
1866
1867
1868 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()));
1869 // Module
1870 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
1871 * Toastify js 1.12.0
1872 * https://github.com/apvarun/toastify-js
1873 * @license MIT licensed
1874 *
1875 * Copyright (C) 2018 Varun A P
1876 */
1877
1878 .toastify {
1879 padding: 12px 20px;
1880 color: #ffffff;
1881 display: inline-block;
1882 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
1883 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
1884 background: linear-gradient(135deg, #73a5ff, #5477f5);
1885 position: fixed;
1886 opacity: 0;
1887 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
1888 border-radius: 2px;
1889 cursor: pointer;
1890 text-decoration: none;
1891 max-width: calc(50% - 20px);
1892 z-index: 2147483647;
1893 }
1894
1895 .toastify.on {
1896 opacity: 1;
1897 }
1898
1899 .toast-close {
1900 background: transparent;
1901 border: 0;
1902 color: white;
1903 cursor: pointer;
1904 font-family: inherit;
1905 font-size: 1em;
1906 opacity: 0.4;
1907 padding: 0 5px;
1908 }
1909
1910 .toastify-right {
1911 right: 15px;
1912 }
1913
1914 .toastify-left {
1915 left: 15px;
1916 }
1917
1918 .toastify-top {
1919 top: -150px;
1920 }
1921
1922 .toastify-bottom {
1923 bottom: -150px;
1924 }
1925
1926 .toastify-rounded {
1927 border-radius: 25px;
1928 }
1929
1930 .toastify-avatar {
1931 width: 1.5em;
1932 height: 1.5em;
1933 margin: -7px 5px;
1934 border-radius: 2px;
1935 }
1936
1937 .toastify-center {
1938 margin-left: auto;
1939 margin-right: auto;
1940 left: 0;
1941 right: 0;
1942 max-width: fit-content;
1943 max-width: -moz-fit-content;
1944 }
1945
1946 @media only screen and (max-width: 360px) {
1947 .toastify-right, .toastify-left {
1948 margin-left: auto;
1949 margin-right: auto;
1950 left: 0;
1951 right: 0;
1952 max-width: fit-content;
1953 }
1954 }
1955 `, "",{"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":""}]);
1956 // Exports
1957 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
1958
1959
1960 /***/ }),
1961
1962 /***/ "./node_modules/css-loader/dist/runtime/api.js":
1963 /*!*****************************************************!*\
1964 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
1965 \*****************************************************/
1966 /***/ ((module) => {
1967
1968 "use strict";
1969
1970
1971 /*
1972 MIT License http://www.opensource.org/licenses/mit-license.php
1973 Author Tobias Koppers @sokra
1974 */
1975 module.exports = function (cssWithMappingToString) {
1976 var list = [];
1977
1978 // return the list of modules as css string
1979 list.toString = function toString() {
1980 return this.map(function (item) {
1981 var content = "";
1982 var needLayer = typeof item[5] !== "undefined";
1983 if (item[4]) {
1984 content += "@supports (".concat(item[4], ") {");
1985 }
1986 if (item[2]) {
1987 content += "@media ".concat(item[2], " {");
1988 }
1989 if (needLayer) {
1990 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
1991 }
1992 content += cssWithMappingToString(item);
1993 if (needLayer) {
1994 content += "}";
1995 }
1996 if (item[2]) {
1997 content += "}";
1998 }
1999 if (item[4]) {
2000 content += "}";
2001 }
2002 return content;
2003 }).join("");
2004 };
2005
2006 // import a list of modules into the list
2007 list.i = function i(modules, media, dedupe, supports, layer) {
2008 if (typeof modules === "string") {
2009 modules = [[null, modules, undefined]];
2010 }
2011 var alreadyImportedModules = {};
2012 if (dedupe) {
2013 for (var k = 0; k < this.length; k++) {
2014 var id = this[k][0];
2015 if (id != null) {
2016 alreadyImportedModules[id] = true;
2017 }
2018 }
2019 }
2020 for (var _k = 0; _k < modules.length; _k++) {
2021 var item = [].concat(modules[_k]);
2022 if (dedupe && alreadyImportedModules[item[0]]) {
2023 continue;
2024 }
2025 if (typeof layer !== "undefined") {
2026 if (typeof item[5] === "undefined") {
2027 item[5] = layer;
2028 } else {
2029 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
2030 item[5] = layer;
2031 }
2032 }
2033 if (media) {
2034 if (!item[2]) {
2035 item[2] = media;
2036 } else {
2037 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
2038 item[2] = media;
2039 }
2040 }
2041 if (supports) {
2042 if (!item[4]) {
2043 item[4] = "".concat(supports);
2044 } else {
2045 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
2046 item[4] = supports;
2047 }
2048 }
2049 list.push(item);
2050 }
2051 };
2052 return list;
2053 };
2054
2055 /***/ }),
2056
2057 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js":
2058 /*!************************************************************!*\
2059 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
2060 \************************************************************/
2061 /***/ ((module) => {
2062
2063 "use strict";
2064
2065
2066 module.exports = function (item) {
2067 var content = item[1];
2068 var cssMapping = item[3];
2069 if (!cssMapping) {
2070 return content;
2071 }
2072 if (typeof btoa === "function") {
2073 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
2074 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
2075 var sourceMapping = "/*# ".concat(data, " */");
2076 return [content].concat([sourceMapping]).join("\n");
2077 }
2078 return [content].join("\n");
2079 };
2080
2081 /***/ }),
2082
2083 /***/ "./node_modules/sortablejs/modular/sortable.esm.js":
2084 /*!*********************************************************!*\
2085 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
2086 \*********************************************************/
2087 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2088
2089 "use strict";
2090 __webpack_require__.r(__webpack_exports__);
2091 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2092 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
2093 /* harmony export */ Sortable: () => (/* binding */ Sortable),
2094 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
2095 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2096 /* harmony export */ });
2097 /**!
2098 * Sortable 1.15.6
2099 * @author RubaXa <[email protected]>
2100 * @author owenm <[email protected]>
2101 * @license MIT
2102 */
2103 function ownKeys(object, enumerableOnly) {
2104 var keys = Object.keys(object);
2105 if (Object.getOwnPropertySymbols) {
2106 var symbols = Object.getOwnPropertySymbols(object);
2107 if (enumerableOnly) {
2108 symbols = symbols.filter(function (sym) {
2109 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
2110 });
2111 }
2112 keys.push.apply(keys, symbols);
2113 }
2114 return keys;
2115 }
2116 function _objectSpread2(target) {
2117 for (var i = 1; i < arguments.length; i++) {
2118 var source = arguments[i] != null ? arguments[i] : {};
2119 if (i % 2) {
2120 ownKeys(Object(source), true).forEach(function (key) {
2121 _defineProperty(target, key, source[key]);
2122 });
2123 } else if (Object.getOwnPropertyDescriptors) {
2124 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
2125 } else {
2126 ownKeys(Object(source)).forEach(function (key) {
2127 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
2128 });
2129 }
2130 }
2131 return target;
2132 }
2133 function _typeof(obj) {
2134 "@babel/helpers - typeof";
2135
2136 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
2137 _typeof = function (obj) {
2138 return typeof obj;
2139 };
2140 } else {
2141 _typeof = function (obj) {
2142 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
2143 };
2144 }
2145 return _typeof(obj);
2146 }
2147 function _defineProperty(obj, key, value) {
2148 if (key in obj) {
2149 Object.defineProperty(obj, key, {
2150 value: value,
2151 enumerable: true,
2152 configurable: true,
2153 writable: true
2154 });
2155 } else {
2156 obj[key] = value;
2157 }
2158 return obj;
2159 }
2160 function _extends() {
2161 _extends = Object.assign || function (target) {
2162 for (var i = 1; i < arguments.length; i++) {
2163 var source = arguments[i];
2164 for (var key in source) {
2165 if (Object.prototype.hasOwnProperty.call(source, key)) {
2166 target[key] = source[key];
2167 }
2168 }
2169 }
2170 return target;
2171 };
2172 return _extends.apply(this, arguments);
2173 }
2174 function _objectWithoutPropertiesLoose(source, excluded) {
2175 if (source == null) return {};
2176 var target = {};
2177 var sourceKeys = Object.keys(source);
2178 var key, i;
2179 for (i = 0; i < sourceKeys.length; i++) {
2180 key = sourceKeys[i];
2181 if (excluded.indexOf(key) >= 0) continue;
2182 target[key] = source[key];
2183 }
2184 return target;
2185 }
2186 function _objectWithoutProperties(source, excluded) {
2187 if (source == null) return {};
2188 var target = _objectWithoutPropertiesLoose(source, excluded);
2189 var key, i;
2190 if (Object.getOwnPropertySymbols) {
2191 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
2192 for (i = 0; i < sourceSymbolKeys.length; i++) {
2193 key = sourceSymbolKeys[i];
2194 if (excluded.indexOf(key) >= 0) continue;
2195 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
2196 target[key] = source[key];
2197 }
2198 }
2199 return target;
2200 }
2201 function _toConsumableArray(arr) {
2202 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
2203 }
2204 function _arrayWithoutHoles(arr) {
2205 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
2206 }
2207 function _iterableToArray(iter) {
2208 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
2209 }
2210 function _unsupportedIterableToArray(o, minLen) {
2211 if (!o) return;
2212 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
2213 var n = Object.prototype.toString.call(o).slice(8, -1);
2214 if (n === "Object" && o.constructor) n = o.constructor.name;
2215 if (n === "Map" || n === "Set") return Array.from(o);
2216 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
2217 }
2218 function _arrayLikeToArray(arr, len) {
2219 if (len == null || len > arr.length) len = arr.length;
2220 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
2221 return arr2;
2222 }
2223 function _nonIterableSpread() {
2224 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2225 }
2226
2227 var version = "1.15.6";
2228
2229 function userAgent(pattern) {
2230 if (typeof window !== 'undefined' && window.navigator) {
2231 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
2232 }
2233 }
2234 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
2235 var Edge = userAgent(/Edge/i);
2236 var FireFox = userAgent(/firefox/i);
2237 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
2238 var IOS = userAgent(/iP(ad|od|hone)/i);
2239 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
2240
2241 var captureMode = {
2242 capture: false,
2243 passive: false
2244 };
2245 function on(el, event, fn) {
2246 el.addEventListener(event, fn, !IE11OrLess && captureMode);
2247 }
2248 function off(el, event, fn) {
2249 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
2250 }
2251 function matches( /**HTMLElement*/el, /**String*/selector) {
2252 if (!selector) return;
2253 selector[0] === '>' && (selector = selector.substring(1));
2254 if (el) {
2255 try {
2256 if (el.matches) {
2257 return el.matches(selector);
2258 } else if (el.msMatchesSelector) {
2259 return el.msMatchesSelector(selector);
2260 } else if (el.webkitMatchesSelector) {
2261 return el.webkitMatchesSelector(selector);
2262 }
2263 } catch (_) {
2264 return false;
2265 }
2266 }
2267 return false;
2268 }
2269 function getParentOrHost(el) {
2270 return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
2271 }
2272 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
2273 if (el) {
2274 ctx = ctx || document;
2275 do {
2276 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
2277 return el;
2278 }
2279 if (el === ctx) break;
2280 /* jshint boss:true */
2281 } while (el = getParentOrHost(el));
2282 }
2283 return null;
2284 }
2285 var R_SPACE = /\s+/g;
2286 function toggleClass(el, name, state) {
2287 if (el && name) {
2288 if (el.classList) {
2289 el.classList[state ? 'add' : 'remove'](name);
2290 } else {
2291 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
2292 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
2293 }
2294 }
2295 }
2296 function css(el, prop, val) {
2297 var style = el && el.style;
2298 if (style) {
2299 if (val === void 0) {
2300 if (document.defaultView && document.defaultView.getComputedStyle) {
2301 val = document.defaultView.getComputedStyle(el, '');
2302 } else if (el.currentStyle) {
2303 val = el.currentStyle;
2304 }
2305 return prop === void 0 ? val : val[prop];
2306 } else {
2307 if (!(prop in style) && prop.indexOf('webkit') === -1) {
2308 prop = '-webkit-' + prop;
2309 }
2310 style[prop] = val + (typeof val === 'string' ? '' : 'px');
2311 }
2312 }
2313 }
2314 function matrix(el, selfOnly) {
2315 var appliedTransforms = '';
2316 if (typeof el === 'string') {
2317 appliedTransforms = el;
2318 } else {
2319 do {
2320 var transform = css(el, 'transform');
2321 if (transform && transform !== 'none') {
2322 appliedTransforms = transform + ' ' + appliedTransforms;
2323 }
2324 /* jshint boss:true */
2325 } while (!selfOnly && (el = el.parentNode));
2326 }
2327 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
2328 /*jshint -W056 */
2329 return matrixFn && new matrixFn(appliedTransforms);
2330 }
2331 function find(ctx, tagName, iterator) {
2332 if (ctx) {
2333 var list = ctx.getElementsByTagName(tagName),
2334 i = 0,
2335 n = list.length;
2336 if (iterator) {
2337 for (; i < n; i++) {
2338 iterator(list[i], i);
2339 }
2340 }
2341 return list;
2342 }
2343 return [];
2344 }
2345 function getWindowScrollingElement() {
2346 var scrollingElement = document.scrollingElement;
2347 if (scrollingElement) {
2348 return scrollingElement;
2349 } else {
2350 return document.documentElement;
2351 }
2352 }
2353
2354 /**
2355 * Returns the "bounding client rect" of given element
2356 * @param {HTMLElement} el The element whose boundingClientRect is wanted
2357 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
2358 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
2359 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
2360 * @param {[HTMLElement]} container The parent the element will be placed in
2361 * @return {Object} The boundingClientRect of el, with specified adjustments
2362 */
2363 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
2364 if (!el.getBoundingClientRect && el !== window) return;
2365 var elRect, top, left, bottom, right, height, width;
2366 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
2367 elRect = el.getBoundingClientRect();
2368 top = elRect.top;
2369 left = elRect.left;
2370 bottom = elRect.bottom;
2371 right = elRect.right;
2372 height = elRect.height;
2373 width = elRect.width;
2374 } else {
2375 top = 0;
2376 left = 0;
2377 bottom = window.innerHeight;
2378 right = window.innerWidth;
2379 height = window.innerHeight;
2380 width = window.innerWidth;
2381 }
2382 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
2383 // Adjust for translate()
2384 container = container || el.parentNode;
2385
2386 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
2387 // Not needed on <= IE11
2388 if (!IE11OrLess) {
2389 do {
2390 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
2391 var containerRect = container.getBoundingClientRect();
2392
2393 // Set relative to edges of padding box of container
2394 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
2395 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
2396 bottom = top + elRect.height;
2397 right = left + elRect.width;
2398 break;
2399 }
2400 /* jshint boss:true */
2401 } while (container = container.parentNode);
2402 }
2403 }
2404 if (undoScale && el !== window) {
2405 // Adjust for scale()
2406 var elMatrix = matrix(container || el),
2407 scaleX = elMatrix && elMatrix.a,
2408 scaleY = elMatrix && elMatrix.d;
2409 if (elMatrix) {
2410 top /= scaleY;
2411 left /= scaleX;
2412 width /= scaleX;
2413 height /= scaleY;
2414 bottom = top + height;
2415 right = left + width;
2416 }
2417 }
2418 return {
2419 top: top,
2420 left: left,
2421 bottom: bottom,
2422 right: right,
2423 width: width,
2424 height: height
2425 };
2426 }
2427
2428 /**
2429 * Checks if a side of an element is scrolled past a side of its parents
2430 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
2431 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
2432 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
2433 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
2434 */
2435 function isScrolledPast(el, elSide, parentSide) {
2436 var parent = getParentAutoScrollElement(el, true),
2437 elSideVal = getRect(el)[elSide];
2438
2439 /* jshint boss:true */
2440 while (parent) {
2441 var parentSideVal = getRect(parent)[parentSide],
2442 visible = void 0;
2443 if (parentSide === 'top' || parentSide === 'left') {
2444 visible = elSideVal >= parentSideVal;
2445 } else {
2446 visible = elSideVal <= parentSideVal;
2447 }
2448 if (!visible) return parent;
2449 if (parent === getWindowScrollingElement()) break;
2450 parent = getParentAutoScrollElement(parent, false);
2451 }
2452 return false;
2453 }
2454
2455 /**
2456 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
2457 * and non-draggable elements
2458 * @param {HTMLElement} el The parent element
2459 * @param {Number} childNum The index of the child
2460 * @param {Object} options Parent Sortable's options
2461 * @return {HTMLElement} The child at index childNum, or null if not found
2462 */
2463 function getChild(el, childNum, options, includeDragEl) {
2464 var currentChild = 0,
2465 i = 0,
2466 children = el.children;
2467 while (i < children.length) {
2468 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
2469 if (currentChild === childNum) {
2470 return children[i];
2471 }
2472 currentChild++;
2473 }
2474 i++;
2475 }
2476 return null;
2477 }
2478
2479 /**
2480 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
2481 * @param {HTMLElement} el Parent element
2482 * @param {selector} selector Any other elements that should be ignored
2483 * @return {HTMLElement} The last child, ignoring ghostEl
2484 */
2485 function lastChild(el, selector) {
2486 var last = el.lastElementChild;
2487 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
2488 last = last.previousElementSibling;
2489 }
2490 return last || null;
2491 }
2492
2493 /**
2494 * Returns the index of an element within its parent for a selected set of
2495 * elements
2496 * @param {HTMLElement} el
2497 * @param {selector} selector
2498 * @return {number}
2499 */
2500 function index(el, selector) {
2501 var index = 0;
2502 if (!el || !el.parentNode) {
2503 return -1;
2504 }
2505
2506 /* jshint boss:true */
2507 while (el = el.previousElementSibling) {
2508 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
2509 index++;
2510 }
2511 }
2512 return index;
2513 }
2514
2515 /**
2516 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
2517 * The value is returned in real pixels.
2518 * @param {HTMLElement} el
2519 * @return {Array} Offsets in the format of [left, top]
2520 */
2521 function getRelativeScrollOffset(el) {
2522 var offsetLeft = 0,
2523 offsetTop = 0,
2524 winScroller = getWindowScrollingElement();
2525 if (el) {
2526 do {
2527 var elMatrix = matrix(el),
2528 scaleX = elMatrix.a,
2529 scaleY = elMatrix.d;
2530 offsetLeft += el.scrollLeft * scaleX;
2531 offsetTop += el.scrollTop * scaleY;
2532 } while (el !== winScroller && (el = el.parentNode));
2533 }
2534 return [offsetLeft, offsetTop];
2535 }
2536
2537 /**
2538 * Returns the index of the object within the given array
2539 * @param {Array} arr Array that may or may not hold the object
2540 * @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
2541 * @return {Number} The index of the object in the array, or -1
2542 */
2543 function indexOfObject(arr, obj) {
2544 for (var i in arr) {
2545 if (!arr.hasOwnProperty(i)) continue;
2546 for (var key in obj) {
2547 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
2548 }
2549 }
2550 return -1;
2551 }
2552 function getParentAutoScrollElement(el, includeSelf) {
2553 // skip to window
2554 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
2555 var elem = el;
2556 var gotSelf = false;
2557 do {
2558 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
2559 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
2560 var elemCSS = css(elem);
2561 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
2562 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
2563 if (gotSelf || includeSelf) return elem;
2564 gotSelf = true;
2565 }
2566 }
2567 /* jshint boss:true */
2568 } while (elem = elem.parentNode);
2569 return getWindowScrollingElement();
2570 }
2571 function extend(dst, src) {
2572 if (dst && src) {
2573 for (var key in src) {
2574 if (src.hasOwnProperty(key)) {
2575 dst[key] = src[key];
2576 }
2577 }
2578 }
2579 return dst;
2580 }
2581 function isRectEqual(rect1, rect2) {
2582 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);
2583 }
2584 var _throttleTimeout;
2585 function throttle(callback, ms) {
2586 return function () {
2587 if (!_throttleTimeout) {
2588 var args = arguments,
2589 _this = this;
2590 if (args.length === 1) {
2591 callback.call(_this, args[0]);
2592 } else {
2593 callback.apply(_this, args);
2594 }
2595 _throttleTimeout = setTimeout(function () {
2596 _throttleTimeout = void 0;
2597 }, ms);
2598 }
2599 };
2600 }
2601 function cancelThrottle() {
2602 clearTimeout(_throttleTimeout);
2603 _throttleTimeout = void 0;
2604 }
2605 function scrollBy(el, x, y) {
2606 el.scrollLeft += x;
2607 el.scrollTop += y;
2608 }
2609 function clone(el) {
2610 var Polymer = window.Polymer;
2611 var $ = window.jQuery || window.Zepto;
2612 if (Polymer && Polymer.dom) {
2613 return Polymer.dom(el).cloneNode(true);
2614 } else if ($) {
2615 return $(el).clone(true)[0];
2616 } else {
2617 return el.cloneNode(true);
2618 }
2619 }
2620 function setRect(el, rect) {
2621 css(el, 'position', 'absolute');
2622 css(el, 'top', rect.top);
2623 css(el, 'left', rect.left);
2624 css(el, 'width', rect.width);
2625 css(el, 'height', rect.height);
2626 }
2627 function unsetRect(el) {
2628 css(el, 'position', '');
2629 css(el, 'top', '');
2630 css(el, 'left', '');
2631 css(el, 'width', '');
2632 css(el, 'height', '');
2633 }
2634 function getChildContainingRectFromElement(container, options, ghostEl) {
2635 var rect = {};
2636 Array.from(container.children).forEach(function (child) {
2637 var _rect$left, _rect$top, _rect$right, _rect$bottom;
2638 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
2639 var childRect = getRect(child);
2640 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
2641 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
2642 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
2643 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
2644 });
2645 rect.width = rect.right - rect.left;
2646 rect.height = rect.bottom - rect.top;
2647 rect.x = rect.left;
2648 rect.y = rect.top;
2649 return rect;
2650 }
2651 var expando = 'Sortable' + new Date().getTime();
2652
2653 function AnimationStateManager() {
2654 var animationStates = [],
2655 animationCallbackId;
2656 return {
2657 captureAnimationState: function captureAnimationState() {
2658 animationStates = [];
2659 if (!this.options.animation) return;
2660 var children = [].slice.call(this.el.children);
2661 children.forEach(function (child) {
2662 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
2663 animationStates.push({
2664 target: child,
2665 rect: getRect(child)
2666 });
2667 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
2668
2669 // If animating: compensate for current animation
2670 if (child.thisAnimationDuration) {
2671 var childMatrix = matrix(child, true);
2672 if (childMatrix) {
2673 fromRect.top -= childMatrix.f;
2674 fromRect.left -= childMatrix.e;
2675 }
2676 }
2677 child.fromRect = fromRect;
2678 });
2679 },
2680 addAnimationState: function addAnimationState(state) {
2681 animationStates.push(state);
2682 },
2683 removeAnimationState: function removeAnimationState(target) {
2684 animationStates.splice(indexOfObject(animationStates, {
2685 target: target
2686 }), 1);
2687 },
2688 animateAll: function animateAll(callback) {
2689 var _this = this;
2690 if (!this.options.animation) {
2691 clearTimeout(animationCallbackId);
2692 if (typeof callback === 'function') callback();
2693 return;
2694 }
2695 var animating = false,
2696 animationTime = 0;
2697 animationStates.forEach(function (state) {
2698 var time = 0,
2699 target = state.target,
2700 fromRect = target.fromRect,
2701 toRect = getRect(target),
2702 prevFromRect = target.prevFromRect,
2703 prevToRect = target.prevToRect,
2704 animatingRect = state.rect,
2705 targetMatrix = matrix(target, true);
2706 if (targetMatrix) {
2707 // Compensate for current animation
2708 toRect.top -= targetMatrix.f;
2709 toRect.left -= targetMatrix.e;
2710 }
2711 target.toRect = toRect;
2712 if (target.thisAnimationDuration) {
2713 // Could also check if animatingRect is between fromRect and toRect
2714 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
2715 // Make sure animatingRect is on line between toRect & fromRect
2716 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
2717 // If returning to same place as started from animation and on same axis
2718 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
2719 }
2720 }
2721
2722 // if fromRect != toRect: animate
2723 if (!isRectEqual(toRect, fromRect)) {
2724 target.prevFromRect = fromRect;
2725 target.prevToRect = toRect;
2726 if (!time) {
2727 time = _this.options.animation;
2728 }
2729 _this.animate(target, animatingRect, toRect, time);
2730 }
2731 if (time) {
2732 animating = true;
2733 animationTime = Math.max(animationTime, time);
2734 clearTimeout(target.animationResetTimer);
2735 target.animationResetTimer = setTimeout(function () {
2736 target.animationTime = 0;
2737 target.prevFromRect = null;
2738 target.fromRect = null;
2739 target.prevToRect = null;
2740 target.thisAnimationDuration = null;
2741 }, time);
2742 target.thisAnimationDuration = time;
2743 }
2744 });
2745 clearTimeout(animationCallbackId);
2746 if (!animating) {
2747 if (typeof callback === 'function') callback();
2748 } else {
2749 animationCallbackId = setTimeout(function () {
2750 if (typeof callback === 'function') callback();
2751 }, animationTime);
2752 }
2753 animationStates = [];
2754 },
2755 animate: function animate(target, currentRect, toRect, duration) {
2756 if (duration) {
2757 css(target, 'transition', '');
2758 css(target, 'transform', '');
2759 var elMatrix = matrix(this.el),
2760 scaleX = elMatrix && elMatrix.a,
2761 scaleY = elMatrix && elMatrix.d,
2762 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
2763 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
2764 target.animatingX = !!translateX;
2765 target.animatingY = !!translateY;
2766 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
2767 this.forRepaintDummy = repaint(target); // repaint
2768
2769 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
2770 css(target, 'transform', 'translate3d(0,0,0)');
2771 typeof target.animated === 'number' && clearTimeout(target.animated);
2772 target.animated = setTimeout(function () {
2773 css(target, 'transition', '');
2774 css(target, 'transform', '');
2775 target.animated = false;
2776 target.animatingX = false;
2777 target.animatingY = false;
2778 }, duration);
2779 }
2780 }
2781 };
2782 }
2783 function repaint(target) {
2784 return target.offsetWidth;
2785 }
2786 function calculateRealTime(animatingRect, fromRect, toRect, options) {
2787 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;
2788 }
2789
2790 var plugins = [];
2791 var defaults = {
2792 initializeByDefault: true
2793 };
2794 var PluginManager = {
2795 mount: function mount(plugin) {
2796 // Set default static properties
2797 for (var option in defaults) {
2798 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
2799 plugin[option] = defaults[option];
2800 }
2801 }
2802 plugins.forEach(function (p) {
2803 if (p.pluginName === plugin.pluginName) {
2804 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
2805 }
2806 });
2807 plugins.push(plugin);
2808 },
2809 pluginEvent: function pluginEvent(eventName, sortable, evt) {
2810 var _this = this;
2811 this.eventCanceled = false;
2812 evt.cancel = function () {
2813 _this.eventCanceled = true;
2814 };
2815 var eventNameGlobal = eventName + 'Global';
2816 plugins.forEach(function (plugin) {
2817 if (!sortable[plugin.pluginName]) return;
2818 // Fire global events if it exists in this sortable
2819 if (sortable[plugin.pluginName][eventNameGlobal]) {
2820 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
2821 sortable: sortable
2822 }, evt));
2823 }
2824
2825 // Only fire plugin event if plugin is enabled in this sortable,
2826 // and plugin has event defined
2827 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
2828 sortable[plugin.pluginName][eventName](_objectSpread2({
2829 sortable: sortable
2830 }, evt));
2831 }
2832 });
2833 },
2834 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
2835 plugins.forEach(function (plugin) {
2836 var pluginName = plugin.pluginName;
2837 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
2838 var initialized = new plugin(sortable, el, sortable.options);
2839 initialized.sortable = sortable;
2840 initialized.options = sortable.options;
2841 sortable[pluginName] = initialized;
2842
2843 // Add default options from plugin
2844 _extends(defaults, initialized.defaults);
2845 });
2846 for (var option in sortable.options) {
2847 if (!sortable.options.hasOwnProperty(option)) continue;
2848 var modified = this.modifyOption(sortable, option, sortable.options[option]);
2849 if (typeof modified !== 'undefined') {
2850 sortable.options[option] = modified;
2851 }
2852 }
2853 },
2854 getEventProperties: function getEventProperties(name, sortable) {
2855 var eventProperties = {};
2856 plugins.forEach(function (plugin) {
2857 if (typeof plugin.eventProperties !== 'function') return;
2858 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
2859 });
2860 return eventProperties;
2861 },
2862 modifyOption: function modifyOption(sortable, name, value) {
2863 var modifiedValue;
2864 plugins.forEach(function (plugin) {
2865 // Plugin must exist on the Sortable
2866 if (!sortable[plugin.pluginName]) return;
2867
2868 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
2869 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
2870 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
2871 }
2872 });
2873 return modifiedValue;
2874 }
2875 };
2876
2877 function dispatchEvent(_ref) {
2878 var sortable = _ref.sortable,
2879 rootEl = _ref.rootEl,
2880 name = _ref.name,
2881 targetEl = _ref.targetEl,
2882 cloneEl = _ref.cloneEl,
2883 toEl = _ref.toEl,
2884 fromEl = _ref.fromEl,
2885 oldIndex = _ref.oldIndex,
2886 newIndex = _ref.newIndex,
2887 oldDraggableIndex = _ref.oldDraggableIndex,
2888 newDraggableIndex = _ref.newDraggableIndex,
2889 originalEvent = _ref.originalEvent,
2890 putSortable = _ref.putSortable,
2891 extraEventProperties = _ref.extraEventProperties;
2892 sortable = sortable || rootEl && rootEl[expando];
2893 if (!sortable) return;
2894 var evt,
2895 options = sortable.options,
2896 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
2897 // Support for new CustomEvent feature
2898 if (window.CustomEvent && !IE11OrLess && !Edge) {
2899 evt = new CustomEvent(name, {
2900 bubbles: true,
2901 cancelable: true
2902 });
2903 } else {
2904 evt = document.createEvent('Event');
2905 evt.initEvent(name, true, true);
2906 }
2907 evt.to = toEl || rootEl;
2908 evt.from = fromEl || rootEl;
2909 evt.item = targetEl || rootEl;
2910 evt.clone = cloneEl;
2911 evt.oldIndex = oldIndex;
2912 evt.newIndex = newIndex;
2913 evt.oldDraggableIndex = oldDraggableIndex;
2914 evt.newDraggableIndex = newDraggableIndex;
2915 evt.originalEvent = originalEvent;
2916 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
2917 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
2918 for (var option in allEventProperties) {
2919 evt[option] = allEventProperties[option];
2920 }
2921 if (rootEl) {
2922 rootEl.dispatchEvent(evt);
2923 }
2924 if (options[onName]) {
2925 options[onName].call(sortable, evt);
2926 }
2927 }
2928
2929 var _excluded = ["evt"];
2930 var pluginEvent = function pluginEvent(eventName, sortable) {
2931 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
2932 originalEvent = _ref.evt,
2933 data = _objectWithoutProperties(_ref, _excluded);
2934 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
2935 dragEl: dragEl,
2936 parentEl: parentEl,
2937 ghostEl: ghostEl,
2938 rootEl: rootEl,
2939 nextEl: nextEl,
2940 lastDownEl: lastDownEl,
2941 cloneEl: cloneEl,
2942 cloneHidden: cloneHidden,
2943 dragStarted: moved,
2944 putSortable: putSortable,
2945 activeSortable: Sortable.active,
2946 originalEvent: originalEvent,
2947 oldIndex: oldIndex,
2948 oldDraggableIndex: oldDraggableIndex,
2949 newIndex: newIndex,
2950 newDraggableIndex: newDraggableIndex,
2951 hideGhostForTarget: _hideGhostForTarget,
2952 unhideGhostForTarget: _unhideGhostForTarget,
2953 cloneNowHidden: function cloneNowHidden() {
2954 cloneHidden = true;
2955 },
2956 cloneNowShown: function cloneNowShown() {
2957 cloneHidden = false;
2958 },
2959 dispatchSortableEvent: function dispatchSortableEvent(name) {
2960 _dispatchEvent({
2961 sortable: sortable,
2962 name: name,
2963 originalEvent: originalEvent
2964 });
2965 }
2966 }, data));
2967 };
2968 function _dispatchEvent(info) {
2969 dispatchEvent(_objectSpread2({
2970 putSortable: putSortable,
2971 cloneEl: cloneEl,
2972 targetEl: dragEl,
2973 rootEl: rootEl,
2974 oldIndex: oldIndex,
2975 oldDraggableIndex: oldDraggableIndex,
2976 newIndex: newIndex,
2977 newDraggableIndex: newDraggableIndex
2978 }, info));
2979 }
2980 var dragEl,
2981 parentEl,
2982 ghostEl,
2983 rootEl,
2984 nextEl,
2985 lastDownEl,
2986 cloneEl,
2987 cloneHidden,
2988 oldIndex,
2989 newIndex,
2990 oldDraggableIndex,
2991 newDraggableIndex,
2992 activeGroup,
2993 putSortable,
2994 awaitingDragStarted = false,
2995 ignoreNextClick = false,
2996 sortables = [],
2997 tapEvt,
2998 touchEvt,
2999 lastDx,
3000 lastDy,
3001 tapDistanceLeft,
3002 tapDistanceTop,
3003 moved,
3004 lastTarget,
3005 lastDirection,
3006 pastFirstInvertThresh = false,
3007 isCircumstantialInvert = false,
3008 targetMoveDistance,
3009 // For positioning ghost absolutely
3010 ghostRelativeParent,
3011 ghostRelativeParentInitialScroll = [],
3012 // (left, top)
3013
3014 _silent = false,
3015 savedInputChecked = [];
3016
3017 /** @const */
3018 var documentExists = typeof document !== 'undefined',
3019 PositionGhostAbsolutely = IOS,
3020 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
3021 // This will not pass for IE9, because IE9 DnD only works on anchors
3022 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
3023 supportCssPointerEvents = function () {
3024 if (!documentExists) return;
3025 // false when <= IE11
3026 if (IE11OrLess) {
3027 return false;
3028 }
3029 var el = document.createElement('x');
3030 el.style.cssText = 'pointer-events:auto';
3031 return el.style.pointerEvents === 'auto';
3032 }(),
3033 _detectDirection = function _detectDirection(el, options) {
3034 var elCSS = css(el),
3035 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
3036 child1 = getChild(el, 0, options),
3037 child2 = getChild(el, 1, options),
3038 firstChildCSS = child1 && css(child1),
3039 secondChildCSS = child2 && css(child2),
3040 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
3041 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
3042 if (elCSS.display === 'flex') {
3043 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
3044 }
3045 if (elCSS.display === 'grid') {
3046 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
3047 }
3048 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
3049 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
3050 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
3051 }
3052 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';
3053 },
3054 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
3055 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
3056 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
3057 dragElOppLength = vertical ? dragRect.width : dragRect.height,
3058 targetS1Opp = vertical ? targetRect.left : targetRect.top,
3059 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
3060 targetOppLength = vertical ? targetRect.width : targetRect.height;
3061 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
3062 },
3063 /**
3064 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
3065 * @param {Number} x X position
3066 * @param {Number} y Y position
3067 * @return {HTMLElement} Element of the first found nearest Sortable
3068 */
3069 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
3070 var ret;
3071 sortables.some(function (sortable) {
3072 var threshold = sortable[expando].options.emptyInsertThreshold;
3073 if (!threshold || lastChild(sortable)) return;
3074 var rect = getRect(sortable),
3075 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
3076 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
3077 if (insideHorizontally && insideVertically) {
3078 return ret = sortable;
3079 }
3080 });
3081 return ret;
3082 },
3083 _prepareGroup = function _prepareGroup(options) {
3084 function toFn(value, pull) {
3085 return function (to, from, dragEl, evt) {
3086 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
3087 if (value == null && (pull || sameGroup)) {
3088 // Default pull value
3089 // Default pull and put value if same group
3090 return true;
3091 } else if (value == null || value === false) {
3092 return false;
3093 } else if (pull && value === 'clone') {
3094 return value;
3095 } else if (typeof value === 'function') {
3096 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
3097 } else {
3098 var otherGroup = (pull ? to : from).options.group.name;
3099 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
3100 }
3101 };
3102 }
3103 var group = {};
3104 var originalGroup = options.group;
3105 if (!originalGroup || _typeof(originalGroup) != 'object') {
3106 originalGroup = {
3107 name: originalGroup
3108 };
3109 }
3110 group.name = originalGroup.name;
3111 group.checkPull = toFn(originalGroup.pull, true);
3112 group.checkPut = toFn(originalGroup.put);
3113 group.revertClone = originalGroup.revertClone;
3114 options.group = group;
3115 },
3116 _hideGhostForTarget = function _hideGhostForTarget() {
3117 if (!supportCssPointerEvents && ghostEl) {
3118 css(ghostEl, 'display', 'none');
3119 }
3120 },
3121 _unhideGhostForTarget = function _unhideGhostForTarget() {
3122 if (!supportCssPointerEvents && ghostEl) {
3123 css(ghostEl, 'display', '');
3124 }
3125 };
3126
3127 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
3128 if (documentExists && !ChromeForAndroid) {
3129 document.addEventListener('click', function (evt) {
3130 if (ignoreNextClick) {
3131 evt.preventDefault();
3132 evt.stopPropagation && evt.stopPropagation();
3133 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
3134 ignoreNextClick = false;
3135 return false;
3136 }
3137 }, true);
3138 }
3139 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
3140 if (dragEl) {
3141 evt = evt.touches ? evt.touches[0] : evt;
3142 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
3143 if (nearest) {
3144 // Create imitation event
3145 var event = {};
3146 for (var i in evt) {
3147 if (evt.hasOwnProperty(i)) {
3148 event[i] = evt[i];
3149 }
3150 }
3151 event.target = event.rootEl = nearest;
3152 event.preventDefault = void 0;
3153 event.stopPropagation = void 0;
3154 nearest[expando]._onDragOver(event);
3155 }
3156 }
3157 };
3158 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
3159 if (dragEl) {
3160 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
3161 }
3162 };
3163
3164 /**
3165 * @class Sortable
3166 * @param {HTMLElement} el
3167 * @param {Object} [options]
3168 */
3169 function Sortable(el, options) {
3170 if (!(el && el.nodeType && el.nodeType === 1)) {
3171 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
3172 }
3173 this.el = el; // root element
3174 this.options = options = _extends({}, options);
3175
3176 // Export instance
3177 el[expando] = this;
3178 var defaults = {
3179 group: null,
3180 sort: true,
3181 disabled: false,
3182 store: null,
3183 handle: null,
3184 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
3185 swapThreshold: 1,
3186 // percentage; 0 <= x <= 1
3187 invertSwap: false,
3188 // invert always
3189 invertedSwapThreshold: null,
3190 // will be set to same as swapThreshold if default
3191 removeCloneOnHide: true,
3192 direction: function direction() {
3193 return _detectDirection(el, this.options);
3194 },
3195 ghostClass: 'sortable-ghost',
3196 chosenClass: 'sortable-chosen',
3197 dragClass: 'sortable-drag',
3198 ignore: 'a, img',
3199 filter: null,
3200 preventOnFilter: true,
3201 animation: 0,
3202 easing: null,
3203 setData: function setData(dataTransfer, dragEl) {
3204 dataTransfer.setData('Text', dragEl.textContent);
3205 },
3206 dropBubble: false,
3207 dragoverBubble: false,
3208 dataIdAttr: 'data-id',
3209 delay: 0,
3210 delayOnTouchOnly: false,
3211 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
3212 forceFallback: false,
3213 fallbackClass: 'sortable-fallback',
3214 fallbackOnBody: false,
3215 fallbackTolerance: 0,
3216 fallbackOffset: {
3217 x: 0,
3218 y: 0
3219 },
3220 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
3221 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
3222 emptyInsertThreshold: 5
3223 };
3224 PluginManager.initializePlugins(this, el, defaults);
3225
3226 // Set default options
3227 for (var name in defaults) {
3228 !(name in options) && (options[name] = defaults[name]);
3229 }
3230 _prepareGroup(options);
3231
3232 // Bind all private methods
3233 for (var fn in this) {
3234 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3235 this[fn] = this[fn].bind(this);
3236 }
3237 }
3238
3239 // Setup drag mode
3240 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
3241 if (this.nativeDraggable) {
3242 // Touch start threshold cannot be greater than the native dragstart threshold
3243 this.options.touchStartThreshold = 1;
3244 }
3245
3246 // Bind events
3247 if (options.supportPointer) {
3248 on(el, 'pointerdown', this._onTapStart);
3249 } else {
3250 on(el, 'mousedown', this._onTapStart);
3251 on(el, 'touchstart', this._onTapStart);
3252 }
3253 if (this.nativeDraggable) {
3254 on(el, 'dragover', this);
3255 on(el, 'dragenter', this);
3256 }
3257 sortables.push(this.el);
3258
3259 // Restore sorting
3260 options.store && options.store.get && this.sort(options.store.get(this) || []);
3261
3262 // Add animation state manager
3263 _extends(this, AnimationStateManager());
3264 }
3265 Sortable.prototype = /** @lends Sortable.prototype */{
3266 constructor: Sortable,
3267 _isOutsideThisEl: function _isOutsideThisEl(target) {
3268 if (!this.el.contains(target) && target !== this.el) {
3269 lastTarget = null;
3270 }
3271 },
3272 _getDirection: function _getDirection(evt, target) {
3273 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
3274 },
3275 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
3276 if (!evt.cancelable) return;
3277 var _this = this,
3278 el = this.el,
3279 options = this.options,
3280 preventOnFilter = options.preventOnFilter,
3281 type = evt.type,
3282 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
3283 target = (touch || evt).target,
3284 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
3285 filter = options.filter;
3286 _saveInputCheckedState(el);
3287
3288 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
3289 if (dragEl) {
3290 return;
3291 }
3292 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
3293 return; // only left button and enabled
3294 }
3295
3296 // cancel dnd if original target is content editable
3297 if (originalTarget.isContentEditable) {
3298 return;
3299 }
3300
3301 // Safari ignores further event handling after mousedown
3302 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
3303 return;
3304 }
3305 target = closest(target, options.draggable, el, false);
3306 if (target && target.animated) {
3307 return;
3308 }
3309 if (lastDownEl === target) {
3310 // Ignoring duplicate `down`
3311 return;
3312 }
3313
3314 // Get the index of the dragged element within its parent
3315 oldIndex = index(target);
3316 oldDraggableIndex = index(target, options.draggable);
3317
3318 // Check filter
3319 if (typeof filter === 'function') {
3320 if (filter.call(this, evt, target, this)) {
3321 _dispatchEvent({
3322 sortable: _this,
3323 rootEl: originalTarget,
3324 name: 'filter',
3325 targetEl: target,
3326 toEl: el,
3327 fromEl: el
3328 });
3329 pluginEvent('filter', _this, {
3330 evt: evt
3331 });
3332 preventOnFilter && evt.preventDefault();
3333 return; // cancel dnd
3334 }
3335 } else if (filter) {
3336 filter = filter.split(',').some(function (criteria) {
3337 criteria = closest(originalTarget, criteria.trim(), el, false);
3338 if (criteria) {
3339 _dispatchEvent({
3340 sortable: _this,
3341 rootEl: criteria,
3342 name: 'filter',
3343 targetEl: target,
3344 fromEl: el,
3345 toEl: el
3346 });
3347 pluginEvent('filter', _this, {
3348 evt: evt
3349 });
3350 return true;
3351 }
3352 });
3353 if (filter) {
3354 preventOnFilter && evt.preventDefault();
3355 return; // cancel dnd
3356 }
3357 }
3358 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
3359 return;
3360 }
3361
3362 // Prepare `dragstart`
3363 this._prepareDragStart(evt, touch, target);
3364 },
3365 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
3366 var _this = this,
3367 el = _this.el,
3368 options = _this.options,
3369 ownerDocument = el.ownerDocument,
3370 dragStartFn;
3371 if (target && !dragEl && target.parentNode === el) {
3372 var dragRect = getRect(target);
3373 rootEl = el;
3374 dragEl = target;
3375 parentEl = dragEl.parentNode;
3376 nextEl = dragEl.nextSibling;
3377 lastDownEl = target;
3378 activeGroup = options.group;
3379 Sortable.dragged = dragEl;
3380 tapEvt = {
3381 target: dragEl,
3382 clientX: (touch || evt).clientX,
3383 clientY: (touch || evt).clientY
3384 };
3385 tapDistanceLeft = tapEvt.clientX - dragRect.left;
3386 tapDistanceTop = tapEvt.clientY - dragRect.top;
3387 this._lastX = (touch || evt).clientX;
3388 this._lastY = (touch || evt).clientY;
3389 dragEl.style['will-change'] = 'all';
3390 dragStartFn = function dragStartFn() {
3391 pluginEvent('delayEnded', _this, {
3392 evt: evt
3393 });
3394 if (Sortable.eventCanceled) {
3395 _this._onDrop();
3396 return;
3397 }
3398 // Delayed drag has been triggered
3399 // we can re-enable the events: touchmove/mousemove
3400 _this._disableDelayedDragEvents();
3401 if (!FireFox && _this.nativeDraggable) {
3402 dragEl.draggable = true;
3403 }
3404
3405 // Bind the events: dragstart/dragend
3406 _this._triggerDragStart(evt, touch);
3407
3408 // Drag start event
3409 _dispatchEvent({
3410 sortable: _this,
3411 name: 'choose',
3412 originalEvent: evt
3413 });
3414
3415 // Chosen item
3416 toggleClass(dragEl, options.chosenClass, true);
3417 };
3418
3419 // Disable "draggable"
3420 options.ignore.split(',').forEach(function (criteria) {
3421 find(dragEl, criteria.trim(), _disableDraggable);
3422 });
3423 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
3424 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
3425 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
3426 if (options.supportPointer) {
3427 on(ownerDocument, 'pointerup', _this._onDrop);
3428 // Native D&D triggers pointercancel
3429 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
3430 } else {
3431 on(ownerDocument, 'mouseup', _this._onDrop);
3432 on(ownerDocument, 'touchend', _this._onDrop);
3433 on(ownerDocument, 'touchcancel', _this._onDrop);
3434 }
3435
3436 // Make dragEl draggable (must be before delay for FireFox)
3437 if (FireFox && this.nativeDraggable) {
3438 this.options.touchStartThreshold = 4;
3439 dragEl.draggable = true;
3440 }
3441 pluginEvent('delayStart', this, {
3442 evt: evt
3443 });
3444
3445 // Delay is impossible for native DnD in Edge or IE
3446 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
3447 if (Sortable.eventCanceled) {
3448 this._onDrop();
3449 return;
3450 }
3451 // If the user moves the pointer or let go the click or touch
3452 // before the delay has been reached:
3453 // disable the delayed drag
3454 if (options.supportPointer) {
3455 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
3456 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
3457 } else {
3458 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
3459 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
3460 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
3461 }
3462 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
3463 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
3464 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
3465 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
3466 } else {
3467 dragStartFn();
3468 }
3469 }
3470 },
3471 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
3472 var touch = e.touches ? e.touches[0] : e;
3473 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))) {
3474 this._disableDelayedDrag();
3475 }
3476 },
3477 _disableDelayedDrag: function _disableDelayedDrag() {
3478 dragEl && _disableDraggable(dragEl);
3479 clearTimeout(this._dragStartTimer);
3480 this._disableDelayedDragEvents();
3481 },
3482 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
3483 var ownerDocument = this.el.ownerDocument;
3484 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
3485 off(ownerDocument, 'touchend', this._disableDelayedDrag);
3486 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
3487 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
3488 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
3489 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
3490 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
3491 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
3492 },
3493 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
3494 touch = touch || evt.pointerType == 'touch' && evt;
3495 if (!this.nativeDraggable || touch) {
3496 if (this.options.supportPointer) {
3497 on(document, 'pointermove', this._onTouchMove);
3498 } else if (touch) {
3499 on(document, 'touchmove', this._onTouchMove);
3500 } else {
3501 on(document, 'mousemove', this._onTouchMove);
3502 }
3503 } else {
3504 on(dragEl, 'dragend', this);
3505 on(rootEl, 'dragstart', this._onDragStart);
3506 }
3507 try {
3508 if (document.selection) {
3509 _nextTick(function () {
3510 document.selection.empty();
3511 });
3512 } else {
3513 window.getSelection().removeAllRanges();
3514 }
3515 } catch (err) {}
3516 },
3517 _dragStarted: function _dragStarted(fallback, evt) {
3518 awaitingDragStarted = false;
3519 if (rootEl && dragEl) {
3520 pluginEvent('dragStarted', this, {
3521 evt: evt
3522 });
3523 if (this.nativeDraggable) {
3524 on(document, 'dragover', _checkOutsideTargetEl);
3525 }
3526 var options = this.options;
3527
3528 // Apply effect
3529 !fallback && toggleClass(dragEl, options.dragClass, false);
3530 toggleClass(dragEl, options.ghostClass, true);
3531 Sortable.active = this;
3532 fallback && this._appendGhost();
3533
3534 // Drag start event
3535 _dispatchEvent({
3536 sortable: this,
3537 name: 'start',
3538 originalEvent: evt
3539 });
3540 } else {
3541 this._nulling();
3542 }
3543 },
3544 _emulateDragOver: function _emulateDragOver() {
3545 if (touchEvt) {
3546 this._lastX = touchEvt.clientX;
3547 this._lastY = touchEvt.clientY;
3548 _hideGhostForTarget();
3549 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3550 var parent = target;
3551 while (target && target.shadowRoot) {
3552 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3553 if (target === parent) break;
3554 parent = target;
3555 }
3556 dragEl.parentNode[expando]._isOutsideThisEl(target);
3557 if (parent) {
3558 do {
3559 if (parent[expando]) {
3560 var inserted = void 0;
3561 inserted = parent[expando]._onDragOver({
3562 clientX: touchEvt.clientX,
3563 clientY: touchEvt.clientY,
3564 target: target,
3565 rootEl: parent
3566 });
3567 if (inserted && !this.options.dragoverBubble) {
3568 break;
3569 }
3570 }
3571 target = parent; // store last element
3572 }
3573 /* jshint boss:true */ while (parent = getParentOrHost(parent));
3574 }
3575 _unhideGhostForTarget();
3576 }
3577 },
3578 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
3579 if (tapEvt) {
3580 var options = this.options,
3581 fallbackTolerance = options.fallbackTolerance,
3582 fallbackOffset = options.fallbackOffset,
3583 touch = evt.touches ? evt.touches[0] : evt,
3584 ghostMatrix = ghostEl && matrix(ghostEl, true),
3585 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
3586 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
3587 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
3588 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
3589 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
3590
3591 // only set the status to dragging, when we are actually dragging
3592 if (!Sortable.active && !awaitingDragStarted) {
3593 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
3594 return;
3595 }
3596 this._onDragStart(evt, true);
3597 }
3598 if (ghostEl) {
3599 if (ghostMatrix) {
3600 ghostMatrix.e += dx - (lastDx || 0);
3601 ghostMatrix.f += dy - (lastDy || 0);
3602 } else {
3603 ghostMatrix = {
3604 a: 1,
3605 b: 0,
3606 c: 0,
3607 d: 1,
3608 e: dx,
3609 f: dy
3610 };
3611 }
3612 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
3613 css(ghostEl, 'webkitTransform', cssMatrix);
3614 css(ghostEl, 'mozTransform', cssMatrix);
3615 css(ghostEl, 'msTransform', cssMatrix);
3616 css(ghostEl, 'transform', cssMatrix);
3617 lastDx = dx;
3618 lastDy = dy;
3619 touchEvt = touch;
3620 }
3621 evt.cancelable && evt.preventDefault();
3622 }
3623 },
3624 _appendGhost: function _appendGhost() {
3625 // Bug if using scale(): https://stackoverflow.com/questions/2637058
3626 // Not being adjusted for
3627 if (!ghostEl) {
3628 var container = this.options.fallbackOnBody ? document.body : rootEl,
3629 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
3630 options = this.options;
3631
3632 // Position absolutely
3633 if (PositionGhostAbsolutely) {
3634 // Get relatively positioned parent
3635 ghostRelativeParent = container;
3636 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
3637 ghostRelativeParent = ghostRelativeParent.parentNode;
3638 }
3639 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
3640 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
3641 rect.top += ghostRelativeParent.scrollTop;
3642 rect.left += ghostRelativeParent.scrollLeft;
3643 } else {
3644 ghostRelativeParent = getWindowScrollingElement();
3645 }
3646 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
3647 }
3648 ghostEl = dragEl.cloneNode(true);
3649 toggleClass(ghostEl, options.ghostClass, false);
3650 toggleClass(ghostEl, options.fallbackClass, true);
3651 toggleClass(ghostEl, options.dragClass, true);
3652 css(ghostEl, 'transition', '');
3653 css(ghostEl, 'transform', '');
3654 css(ghostEl, 'box-sizing', 'border-box');
3655 css(ghostEl, 'margin', 0);
3656 css(ghostEl, 'top', rect.top);
3657 css(ghostEl, 'left', rect.left);
3658 css(ghostEl, 'width', rect.width);
3659 css(ghostEl, 'height', rect.height);
3660 css(ghostEl, 'opacity', '0.8');
3661 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
3662 css(ghostEl, 'zIndex', '100000');
3663 css(ghostEl, 'pointerEvents', 'none');
3664 Sortable.ghost = ghostEl;
3665 container.appendChild(ghostEl);
3666
3667 // Set transform-origin
3668 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
3669 }
3670 },
3671 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
3672 var _this = this;
3673 var dataTransfer = evt.dataTransfer;
3674 var options = _this.options;
3675 pluginEvent('dragStart', this, {
3676 evt: evt
3677 });
3678 if (Sortable.eventCanceled) {
3679 this._onDrop();
3680 return;
3681 }
3682 pluginEvent('setupClone', this);
3683 if (!Sortable.eventCanceled) {
3684 cloneEl = clone(dragEl);
3685 cloneEl.removeAttribute("id");
3686 cloneEl.draggable = false;
3687 cloneEl.style['will-change'] = '';
3688 this._hideClone();
3689 toggleClass(cloneEl, this.options.chosenClass, false);
3690 Sortable.clone = cloneEl;
3691 }
3692
3693 // #1143: IFrame support workaround
3694 _this.cloneId = _nextTick(function () {
3695 pluginEvent('clone', _this);
3696 if (Sortable.eventCanceled) return;
3697 if (!_this.options.removeCloneOnHide) {
3698 rootEl.insertBefore(cloneEl, dragEl);
3699 }
3700 _this._hideClone();
3701 _dispatchEvent({
3702 sortable: _this,
3703 name: 'clone'
3704 });
3705 });
3706 !fallback && toggleClass(dragEl, options.dragClass, true);
3707
3708 // Set proper drop events
3709 if (fallback) {
3710 ignoreNextClick = true;
3711 _this._loopId = setInterval(_this._emulateDragOver, 50);
3712 } else {
3713 // Undo what was set in _prepareDragStart before drag started
3714 off(document, 'mouseup', _this._onDrop);
3715 off(document, 'touchend', _this._onDrop);
3716 off(document, 'touchcancel', _this._onDrop);
3717 if (dataTransfer) {
3718 dataTransfer.effectAllowed = 'move';
3719 options.setData && options.setData.call(_this, dataTransfer, dragEl);
3720 }
3721 on(document, 'drop', _this);
3722
3723 // #1276 fix:
3724 css(dragEl, 'transform', 'translateZ(0)');
3725 }
3726 awaitingDragStarted = true;
3727 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
3728 on(document, 'selectstart', _this);
3729 moved = true;
3730 window.getSelection().removeAllRanges();
3731 if (Safari) {
3732 css(document.body, 'user-select', 'none');
3733 }
3734 },
3735 // Returns true - if no further action is needed (either inserted or another condition)
3736 _onDragOver: function _onDragOver( /**Event*/evt) {
3737 var el = this.el,
3738 target = evt.target,
3739 dragRect,
3740 targetRect,
3741 revert,
3742 options = this.options,
3743 group = options.group,
3744 activeSortable = Sortable.active,
3745 isOwner = activeGroup === group,
3746 canSort = options.sort,
3747 fromSortable = putSortable || activeSortable,
3748 vertical,
3749 _this = this,
3750 completedFired = false;
3751 if (_silent) return;
3752 function dragOverEvent(name, extra) {
3753 pluginEvent(name, _this, _objectSpread2({
3754 evt: evt,
3755 isOwner: isOwner,
3756 axis: vertical ? 'vertical' : 'horizontal',
3757 revert: revert,
3758 dragRect: dragRect,
3759 targetRect: targetRect,
3760 canSort: canSort,
3761 fromSortable: fromSortable,
3762 target: target,
3763 completed: completed,
3764 onMove: function onMove(target, after) {
3765 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
3766 },
3767 changed: changed
3768 }, extra));
3769 }
3770
3771 // Capture animation state
3772 function capture() {
3773 dragOverEvent('dragOverAnimationCapture');
3774 _this.captureAnimationState();
3775 if (_this !== fromSortable) {
3776 fromSortable.captureAnimationState();
3777 }
3778 }
3779
3780 // Return invocation when dragEl is inserted (or completed)
3781 function completed(insertion) {
3782 dragOverEvent('dragOverCompleted', {
3783 insertion: insertion
3784 });
3785 if (insertion) {
3786 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3787 if (isOwner) {
3788 activeSortable._hideClone();
3789 } else {
3790 activeSortable._showClone(_this);
3791 }
3792 if (_this !== fromSortable) {
3793 // Set ghost class to new sortable's ghost class
3794 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
3795 toggleClass(dragEl, options.ghostClass, true);
3796 }
3797 if (putSortable !== _this && _this !== Sortable.active) {
3798 putSortable = _this;
3799 } else if (_this === Sortable.active && putSortable) {
3800 putSortable = null;
3801 }
3802
3803 // Animation
3804 if (fromSortable === _this) {
3805 _this._ignoreWhileAnimating = target;
3806 }
3807 _this.animateAll(function () {
3808 dragOverEvent('dragOverAnimationComplete');
3809 _this._ignoreWhileAnimating = null;
3810 });
3811 if (_this !== fromSortable) {
3812 fromSortable.animateAll();
3813 fromSortable._ignoreWhileAnimating = null;
3814 }
3815 }
3816
3817 // Null lastTarget if it is not inside a previously swapped element
3818 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
3819 lastTarget = null;
3820 }
3821
3822 // no bubbling and not fallback
3823 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
3824 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
3825
3826 // Do not detect for empty insert if already inserted
3827 !insertion && nearestEmptyInsertDetectEvent(evt);
3828 }
3829 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
3830 return completedFired = true;
3831 }
3832
3833 // Call when dragEl has been inserted
3834 function changed() {
3835 newIndex = index(dragEl);
3836 newDraggableIndex = index(dragEl, options.draggable);
3837 _dispatchEvent({
3838 sortable: _this,
3839 name: 'change',
3840 toEl: el,
3841 newIndex: newIndex,
3842 newDraggableIndex: newDraggableIndex,
3843 originalEvent: evt
3844 });
3845 }
3846 if (evt.preventDefault !== void 0) {
3847 evt.cancelable && evt.preventDefault();
3848 }
3849 target = closest(target, options.draggable, el, true);
3850 dragOverEvent('dragOver');
3851 if (Sortable.eventCanceled) return completedFired;
3852 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
3853 return completed(false);
3854 }
3855 ignoreNextClick = false;
3856 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
3857 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
3858 vertical = this._getDirection(evt, target) === 'vertical';
3859 dragRect = getRect(dragEl);
3860 dragOverEvent('dragOverValid');
3861 if (Sortable.eventCanceled) return completedFired;
3862 if (revert) {
3863 parentEl = rootEl; // actualization
3864 capture();
3865 this._hideClone();
3866 dragOverEvent('revert');
3867 if (!Sortable.eventCanceled) {
3868 if (nextEl) {
3869 rootEl.insertBefore(dragEl, nextEl);
3870 } else {
3871 rootEl.appendChild(dragEl);
3872 }
3873 }
3874 return completed(true);
3875 }
3876 var elLastChild = lastChild(el, options.draggable);
3877 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
3878 // Insert to end of list
3879
3880 // If already at end of list: Do not insert
3881 if (elLastChild === dragEl) {
3882 return completed(false);
3883 }
3884
3885 // if there is a last element, it is the target
3886 if (elLastChild && el === evt.target) {
3887 target = elLastChild;
3888 }
3889 if (target) {
3890 targetRect = getRect(target);
3891 }
3892 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
3893 capture();
3894 if (elLastChild && elLastChild.nextSibling) {
3895 // the last draggable element is not the last node
3896 el.insertBefore(dragEl, elLastChild.nextSibling);
3897 } else {
3898 el.appendChild(dragEl);
3899 }
3900 parentEl = el; // actualization
3901
3902 changed();
3903 return completed(true);
3904 }
3905 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
3906 // Insert to start of list
3907 var firstChild = getChild(el, 0, options, true);
3908 if (firstChild === dragEl) {
3909 return completed(false);
3910 }
3911 target = firstChild;
3912 targetRect = getRect(target);
3913 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
3914 capture();
3915 el.insertBefore(dragEl, firstChild);
3916 parentEl = el; // actualization
3917
3918 changed();
3919 return completed(true);
3920 }
3921 } else if (target.parentNode === el) {
3922 targetRect = getRect(target);
3923 var direction = 0,
3924 targetBeforeFirstSwap,
3925 differentLevel = dragEl.parentNode !== el,
3926 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
3927 side1 = vertical ? 'top' : 'left',
3928 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
3929 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
3930 if (lastTarget !== target) {
3931 targetBeforeFirstSwap = targetRect[side1];
3932 pastFirstInvertThresh = false;
3933 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
3934 }
3935 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
3936 var sibling;
3937 if (direction !== 0) {
3938 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
3939 var dragIndex = index(dragEl);
3940 do {
3941 dragIndex -= direction;
3942 sibling = parentEl.children[dragIndex];
3943 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
3944 }
3945 // If dragEl is already beside target: Do not insert
3946 if (direction === 0 || sibling === target) {
3947 return completed(false);
3948 }
3949 lastTarget = target;
3950 lastDirection = direction;
3951 var nextSibling = target.nextElementSibling,
3952 after = false;
3953 after = direction === 1;
3954 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
3955 if (moveVector !== false) {
3956 if (moveVector === 1 || moveVector === -1) {
3957 after = moveVector === 1;
3958 }
3959 _silent = true;
3960 setTimeout(_unsilent, 30);
3961 capture();
3962 if (after && !nextSibling) {
3963 el.appendChild(dragEl);
3964 } else {
3965 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
3966 }
3967
3968 // Undo chrome's scroll adjustment (has no effect on other browsers)
3969 if (scrolledPastTop) {
3970 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
3971 }
3972 parentEl = dragEl.parentNode; // actualization
3973
3974 // must be done before animation
3975 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
3976 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
3977 }
3978 changed();
3979 return completed(true);
3980 }
3981 }
3982 if (el.contains(dragEl)) {
3983 return completed(false);
3984 }
3985 }
3986 return false;
3987 },
3988 _ignoreWhileAnimating: null,
3989 _offMoveEvents: function _offMoveEvents() {
3990 off(document, 'mousemove', this._onTouchMove);
3991 off(document, 'touchmove', this._onTouchMove);
3992 off(document, 'pointermove', this._onTouchMove);
3993 off(document, 'dragover', nearestEmptyInsertDetectEvent);
3994 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
3995 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
3996 },
3997 _offUpEvents: function _offUpEvents() {
3998 var ownerDocument = this.el.ownerDocument;
3999 off(ownerDocument, 'mouseup', this._onDrop);
4000 off(ownerDocument, 'touchend', this._onDrop);
4001 off(ownerDocument, 'pointerup', this._onDrop);
4002 off(ownerDocument, 'pointercancel', this._onDrop);
4003 off(ownerDocument, 'touchcancel', this._onDrop);
4004 off(document, 'selectstart', this);
4005 },
4006 _onDrop: function _onDrop( /**Event*/evt) {
4007 var el = this.el,
4008 options = this.options;
4009
4010 // Get the index of the dragged element within its parent
4011 newIndex = index(dragEl);
4012 newDraggableIndex = index(dragEl, options.draggable);
4013 pluginEvent('drop', this, {
4014 evt: evt
4015 });
4016 parentEl = dragEl && dragEl.parentNode;
4017
4018 // Get again after plugin event
4019 newIndex = index(dragEl);
4020 newDraggableIndex = index(dragEl, options.draggable);
4021 if (Sortable.eventCanceled) {
4022 this._nulling();
4023 return;
4024 }
4025 awaitingDragStarted = false;
4026 isCircumstantialInvert = false;
4027 pastFirstInvertThresh = false;
4028 clearInterval(this._loopId);
4029 clearTimeout(this._dragStartTimer);
4030 _cancelNextTick(this.cloneId);
4031 _cancelNextTick(this._dragStartId);
4032
4033 // Unbind events
4034 if (this.nativeDraggable) {
4035 off(document, 'drop', this);
4036 off(el, 'dragstart', this._onDragStart);
4037 }
4038 this._offMoveEvents();
4039 this._offUpEvents();
4040 if (Safari) {
4041 css(document.body, 'user-select', '');
4042 }
4043 css(dragEl, 'transform', '');
4044 if (evt) {
4045 if (moved) {
4046 evt.cancelable && evt.preventDefault();
4047 !options.dropBubble && evt.stopPropagation();
4048 }
4049 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
4050 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
4051 // Remove clone(s)
4052 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
4053 }
4054 if (dragEl) {
4055 if (this.nativeDraggable) {
4056 off(dragEl, 'dragend', this);
4057 }
4058 _disableDraggable(dragEl);
4059 dragEl.style['will-change'] = '';
4060
4061 // Remove classes
4062 // ghostClass is added in dragStarted
4063 if (moved && !awaitingDragStarted) {
4064 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
4065 }
4066 toggleClass(dragEl, this.options.chosenClass, false);
4067
4068 // Drag stop event
4069 _dispatchEvent({
4070 sortable: this,
4071 name: 'unchoose',
4072 toEl: parentEl,
4073 newIndex: null,
4074 newDraggableIndex: null,
4075 originalEvent: evt
4076 });
4077 if (rootEl !== parentEl) {
4078 if (newIndex >= 0) {
4079 // Add event
4080 _dispatchEvent({
4081 rootEl: parentEl,
4082 name: 'add',
4083 toEl: parentEl,
4084 fromEl: rootEl,
4085 originalEvent: evt
4086 });
4087
4088 // Remove event
4089 _dispatchEvent({
4090 sortable: this,
4091 name: 'remove',
4092 toEl: parentEl,
4093 originalEvent: evt
4094 });
4095
4096 // drag from one list and drop into another
4097 _dispatchEvent({
4098 rootEl: parentEl,
4099 name: 'sort',
4100 toEl: parentEl,
4101 fromEl: rootEl,
4102 originalEvent: evt
4103 });
4104 _dispatchEvent({
4105 sortable: this,
4106 name: 'sort',
4107 toEl: parentEl,
4108 originalEvent: evt
4109 });
4110 }
4111 putSortable && putSortable.save();
4112 } else {
4113 if (newIndex !== oldIndex) {
4114 if (newIndex >= 0) {
4115 // drag & drop within the same list
4116 _dispatchEvent({
4117 sortable: this,
4118 name: 'update',
4119 toEl: parentEl,
4120 originalEvent: evt
4121 });
4122 _dispatchEvent({
4123 sortable: this,
4124 name: 'sort',
4125 toEl: parentEl,
4126 originalEvent: evt
4127 });
4128 }
4129 }
4130 }
4131 if (Sortable.active) {
4132 /* jshint eqnull:true */
4133 if (newIndex == null || newIndex === -1) {
4134 newIndex = oldIndex;
4135 newDraggableIndex = oldDraggableIndex;
4136 }
4137 _dispatchEvent({
4138 sortable: this,
4139 name: 'end',
4140 toEl: parentEl,
4141 originalEvent: evt
4142 });
4143
4144 // Save sorting
4145 this.save();
4146 }
4147 }
4148 }
4149 this._nulling();
4150 },
4151 _nulling: function _nulling() {
4152 pluginEvent('nulling', this);
4153 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;
4154 savedInputChecked.forEach(function (el) {
4155 el.checked = true;
4156 });
4157 savedInputChecked.length = lastDx = lastDy = 0;
4158 },
4159 handleEvent: function handleEvent( /**Event*/evt) {
4160 switch (evt.type) {
4161 case 'drop':
4162 case 'dragend':
4163 this._onDrop(evt);
4164 break;
4165 case 'dragenter':
4166 case 'dragover':
4167 if (dragEl) {
4168 this._onDragOver(evt);
4169 _globalDragOver(evt);
4170 }
4171 break;
4172 case 'selectstart':
4173 evt.preventDefault();
4174 break;
4175 }
4176 },
4177 /**
4178 * Serializes the item into an array of string.
4179 * @returns {String[]}
4180 */
4181 toArray: function toArray() {
4182 var order = [],
4183 el,
4184 children = this.el.children,
4185 i = 0,
4186 n = children.length,
4187 options = this.options;
4188 for (; i < n; i++) {
4189 el = children[i];
4190 if (closest(el, options.draggable, this.el, false)) {
4191 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
4192 }
4193 }
4194 return order;
4195 },
4196 /**
4197 * Sorts the elements according to the array.
4198 * @param {String[]} order order of the items
4199 */
4200 sort: function sort(order, useAnimation) {
4201 var items = {},
4202 rootEl = this.el;
4203 this.toArray().forEach(function (id, i) {
4204 var el = rootEl.children[i];
4205 if (closest(el, this.options.draggable, rootEl, false)) {
4206 items[id] = el;
4207 }
4208 }, this);
4209 useAnimation && this.captureAnimationState();
4210 order.forEach(function (id) {
4211 if (items[id]) {
4212 rootEl.removeChild(items[id]);
4213 rootEl.appendChild(items[id]);
4214 }
4215 });
4216 useAnimation && this.animateAll();
4217 },
4218 /**
4219 * Save the current sorting
4220 */
4221 save: function save() {
4222 var store = this.options.store;
4223 store && store.set && store.set(this);
4224 },
4225 /**
4226 * 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.
4227 * @param {HTMLElement} el
4228 * @param {String} [selector] default: `options.draggable`
4229 * @returns {HTMLElement|null}
4230 */
4231 closest: function closest$1(el, selector) {
4232 return closest(el, selector || this.options.draggable, this.el, false);
4233 },
4234 /**
4235 * Set/get option
4236 * @param {string} name
4237 * @param {*} [value]
4238 * @returns {*}
4239 */
4240 option: function option(name, value) {
4241 var options = this.options;
4242 if (value === void 0) {
4243 return options[name];
4244 } else {
4245 var modifiedValue = PluginManager.modifyOption(this, name, value);
4246 if (typeof modifiedValue !== 'undefined') {
4247 options[name] = modifiedValue;
4248 } else {
4249 options[name] = value;
4250 }
4251 if (name === 'group') {
4252 _prepareGroup(options);
4253 }
4254 }
4255 },
4256 /**
4257 * Destroy
4258 */
4259 destroy: function destroy() {
4260 pluginEvent('destroy', this);
4261 var el = this.el;
4262 el[expando] = null;
4263 off(el, 'mousedown', this._onTapStart);
4264 off(el, 'touchstart', this._onTapStart);
4265 off(el, 'pointerdown', this._onTapStart);
4266 if (this.nativeDraggable) {
4267 off(el, 'dragover', this);
4268 off(el, 'dragenter', this);
4269 }
4270 // Remove draggable attributes
4271 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
4272 el.removeAttribute('draggable');
4273 });
4274 this._onDrop();
4275 this._disableDelayedDragEvents();
4276 sortables.splice(sortables.indexOf(this.el), 1);
4277 this.el = el = null;
4278 },
4279 _hideClone: function _hideClone() {
4280 if (!cloneHidden) {
4281 pluginEvent('hideClone', this);
4282 if (Sortable.eventCanceled) return;
4283 css(cloneEl, 'display', 'none');
4284 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
4285 cloneEl.parentNode.removeChild(cloneEl);
4286 }
4287 cloneHidden = true;
4288 }
4289 },
4290 _showClone: function _showClone(putSortable) {
4291 if (putSortable.lastPutMode !== 'clone') {
4292 this._hideClone();
4293 return;
4294 }
4295 if (cloneHidden) {
4296 pluginEvent('showClone', this);
4297 if (Sortable.eventCanceled) return;
4298
4299 // show clone at dragEl or original position
4300 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
4301 rootEl.insertBefore(cloneEl, dragEl);
4302 } else if (nextEl) {
4303 rootEl.insertBefore(cloneEl, nextEl);
4304 } else {
4305 rootEl.appendChild(cloneEl);
4306 }
4307 if (this.options.group.revertClone) {
4308 this.animate(dragEl, cloneEl);
4309 }
4310 css(cloneEl, 'display', '');
4311 cloneHidden = false;
4312 }
4313 }
4314 };
4315 function _globalDragOver( /**Event*/evt) {
4316 if (evt.dataTransfer) {
4317 evt.dataTransfer.dropEffect = 'move';
4318 }
4319 evt.cancelable && evt.preventDefault();
4320 }
4321 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
4322 var evt,
4323 sortable = fromEl[expando],
4324 onMoveFn = sortable.options.onMove,
4325 retVal;
4326 // Support for new CustomEvent feature
4327 if (window.CustomEvent && !IE11OrLess && !Edge) {
4328 evt = new CustomEvent('move', {
4329 bubbles: true,
4330 cancelable: true
4331 });
4332 } else {
4333 evt = document.createEvent('Event');
4334 evt.initEvent('move', true, true);
4335 }
4336 evt.to = toEl;
4337 evt.from = fromEl;
4338 evt.dragged = dragEl;
4339 evt.draggedRect = dragRect;
4340 evt.related = targetEl || toEl;
4341 evt.relatedRect = targetRect || getRect(toEl);
4342 evt.willInsertAfter = willInsertAfter;
4343 evt.originalEvent = originalEvent;
4344 fromEl.dispatchEvent(evt);
4345 if (onMoveFn) {
4346 retVal = onMoveFn.call(sortable, evt, originalEvent);
4347 }
4348 return retVal;
4349 }
4350 function _disableDraggable(el) {
4351 el.draggable = false;
4352 }
4353 function _unsilent() {
4354 _silent = false;
4355 }
4356 function _ghostIsFirst(evt, vertical, sortable) {
4357 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
4358 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4359 var spacer = 10;
4360 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;
4361 }
4362 function _ghostIsLast(evt, vertical, sortable) {
4363 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
4364 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4365 var spacer = 10;
4366 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;
4367 }
4368 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
4369 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
4370 targetLength = vertical ? targetRect.height : targetRect.width,
4371 targetS1 = vertical ? targetRect.top : targetRect.left,
4372 targetS2 = vertical ? targetRect.bottom : targetRect.right,
4373 invert = false;
4374 if (!invertSwap) {
4375 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
4376 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
4377 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
4378 // check if past first invert threshold on side opposite of lastDirection
4379 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
4380 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
4381 pastFirstInvertThresh = true;
4382 }
4383 if (!pastFirstInvertThresh) {
4384 // dragEl shadow (target move distance shadow)
4385 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
4386 : mouseOnAxis > targetS2 - targetMoveDistance) {
4387 return -lastDirection;
4388 }
4389 } else {
4390 invert = true;
4391 }
4392 } else {
4393 // Regular
4394 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
4395 return _getInsertDirection(target);
4396 }
4397 }
4398 }
4399 invert = invert || invertSwap;
4400 if (invert) {
4401 // Invert of regular
4402 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
4403 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
4404 }
4405 }
4406 return 0;
4407 }
4408
4409 /**
4410 * Gets the direction dragEl must be swapped relative to target in order to make it
4411 * seem that dragEl has been "inserted" into that element's position
4412 * @param {HTMLElement} target The target whose position dragEl is being inserted at
4413 * @return {Number} Direction dragEl must be swapped
4414 */
4415 function _getInsertDirection(target) {
4416 if (index(dragEl) < index(target)) {
4417 return 1;
4418 } else {
4419 return -1;
4420 }
4421 }
4422
4423 /**
4424 * Generate id
4425 * @param {HTMLElement} el
4426 * @returns {String}
4427 * @private
4428 */
4429 function _generateId(el) {
4430 var str = el.tagName + el.className + el.src + el.href + el.textContent,
4431 i = str.length,
4432 sum = 0;
4433 while (i--) {
4434 sum += str.charCodeAt(i);
4435 }
4436 return sum.toString(36);
4437 }
4438 function _saveInputCheckedState(root) {
4439 savedInputChecked.length = 0;
4440 var inputs = root.getElementsByTagName('input');
4441 var idx = inputs.length;
4442 while (idx--) {
4443 var el = inputs[idx];
4444 el.checked && savedInputChecked.push(el);
4445 }
4446 }
4447 function _nextTick(fn) {
4448 return setTimeout(fn, 0);
4449 }
4450 function _cancelNextTick(id) {
4451 return clearTimeout(id);
4452 }
4453
4454 // Fixed #973:
4455 if (documentExists) {
4456 on(document, 'touchmove', function (evt) {
4457 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
4458 evt.preventDefault();
4459 }
4460 });
4461 }
4462
4463 // Export utils
4464 Sortable.utils = {
4465 on: on,
4466 off: off,
4467 css: css,
4468 find: find,
4469 is: function is(el, selector) {
4470 return !!closest(el, selector, el, false);
4471 },
4472 extend: extend,
4473 throttle: throttle,
4474 closest: closest,
4475 toggleClass: toggleClass,
4476 clone: clone,
4477 index: index,
4478 nextTick: _nextTick,
4479 cancelNextTick: _cancelNextTick,
4480 detectDirection: _detectDirection,
4481 getChild: getChild,
4482 expando: expando
4483 };
4484
4485 /**
4486 * Get the Sortable instance of an element
4487 * @param {HTMLElement} element The element
4488 * @return {Sortable|undefined} The instance of Sortable
4489 */
4490 Sortable.get = function (element) {
4491 return element[expando];
4492 };
4493
4494 /**
4495 * Mount a plugin to Sortable
4496 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
4497 */
4498 Sortable.mount = function () {
4499 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
4500 plugins[_key] = arguments[_key];
4501 }
4502 if (plugins[0].constructor === Array) plugins = plugins[0];
4503 plugins.forEach(function (plugin) {
4504 if (!plugin.prototype || !plugin.prototype.constructor) {
4505 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
4506 }
4507 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
4508 PluginManager.mount(plugin);
4509 });
4510 };
4511
4512 /**
4513 * Create sortable instance
4514 * @param {HTMLElement} el
4515 * @param {Object} [options]
4516 */
4517 Sortable.create = function (el, options) {
4518 return new Sortable(el, options);
4519 };
4520
4521 // Export
4522 Sortable.version = version;
4523
4524 var autoScrolls = [],
4525 scrollEl,
4526 scrollRootEl,
4527 scrolling = false,
4528 lastAutoScrollX,
4529 lastAutoScrollY,
4530 touchEvt$1,
4531 pointerElemChangedInterval;
4532 function AutoScrollPlugin() {
4533 function AutoScroll() {
4534 this.defaults = {
4535 scroll: true,
4536 forceAutoScrollFallback: false,
4537 scrollSensitivity: 30,
4538 scrollSpeed: 10,
4539 bubbleScroll: true
4540 };
4541
4542 // Bind all private methods
4543 for (var fn in this) {
4544 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4545 this[fn] = this[fn].bind(this);
4546 }
4547 }
4548 }
4549 AutoScroll.prototype = {
4550 dragStarted: function dragStarted(_ref) {
4551 var originalEvent = _ref.originalEvent;
4552 if (this.sortable.nativeDraggable) {
4553 on(document, 'dragover', this._handleAutoScroll);
4554 } else {
4555 if (this.options.supportPointer) {
4556 on(document, 'pointermove', this._handleFallbackAutoScroll);
4557 } else if (originalEvent.touches) {
4558 on(document, 'touchmove', this._handleFallbackAutoScroll);
4559 } else {
4560 on(document, 'mousemove', this._handleFallbackAutoScroll);
4561 }
4562 }
4563 },
4564 dragOverCompleted: function dragOverCompleted(_ref2) {
4565 var originalEvent = _ref2.originalEvent;
4566 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
4567 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
4568 this._handleAutoScroll(originalEvent);
4569 }
4570 },
4571 drop: function drop() {
4572 if (this.sortable.nativeDraggable) {
4573 off(document, 'dragover', this._handleAutoScroll);
4574 } else {
4575 off(document, 'pointermove', this._handleFallbackAutoScroll);
4576 off(document, 'touchmove', this._handleFallbackAutoScroll);
4577 off(document, 'mousemove', this._handleFallbackAutoScroll);
4578 }
4579 clearPointerElemChangedInterval();
4580 clearAutoScrolls();
4581 cancelThrottle();
4582 },
4583 nulling: function nulling() {
4584 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
4585 autoScrolls.length = 0;
4586 },
4587 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
4588 this._handleAutoScroll(evt, true);
4589 },
4590 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
4591 var _this = this;
4592 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4593 y = (evt.touches ? evt.touches[0] : evt).clientY,
4594 elem = document.elementFromPoint(x, y);
4595 touchEvt$1 = evt;
4596
4597 // IE does not seem to have native autoscroll,
4598 // Edge's autoscroll seems too conditional,
4599 // MACOS Safari does not have autoscroll,
4600 // Firefox and Chrome are good
4601 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
4602 autoScroll(evt, this.options, elem, fallback);
4603
4604 // Listener for pointer element change
4605 var ogElemScroller = getParentAutoScrollElement(elem, true);
4606 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
4607 pointerElemChangedInterval && clearPointerElemChangedInterval();
4608 // Detect for pointer elem change, emulating native DnD behaviour
4609 pointerElemChangedInterval = setInterval(function () {
4610 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
4611 if (newElem !== ogElemScroller) {
4612 ogElemScroller = newElem;
4613 clearAutoScrolls();
4614 }
4615 autoScroll(evt, _this.options, newElem, fallback);
4616 }, 10);
4617 lastAutoScrollX = x;
4618 lastAutoScrollY = y;
4619 }
4620 } else {
4621 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
4622 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
4623 clearAutoScrolls();
4624 return;
4625 }
4626 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
4627 }
4628 }
4629 };
4630 return _extends(AutoScroll, {
4631 pluginName: 'scroll',
4632 initializeByDefault: true
4633 });
4634 }
4635 function clearAutoScrolls() {
4636 autoScrolls.forEach(function (autoScroll) {
4637 clearInterval(autoScroll.pid);
4638 });
4639 autoScrolls = [];
4640 }
4641 function clearPointerElemChangedInterval() {
4642 clearInterval(pointerElemChangedInterval);
4643 }
4644 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
4645 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
4646 if (!options.scroll) return;
4647 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4648 y = (evt.touches ? evt.touches[0] : evt).clientY,
4649 sens = options.scrollSensitivity,
4650 speed = options.scrollSpeed,
4651 winScroller = getWindowScrollingElement();
4652 var scrollThisInstance = false,
4653 scrollCustomFn;
4654
4655 // New scroll root, set scrollEl
4656 if (scrollRootEl !== rootEl) {
4657 scrollRootEl = rootEl;
4658 clearAutoScrolls();
4659 scrollEl = options.scroll;
4660 scrollCustomFn = options.scrollFn;
4661 if (scrollEl === true) {
4662 scrollEl = getParentAutoScrollElement(rootEl, true);
4663 }
4664 }
4665 var layersOut = 0;
4666 var currentParent = scrollEl;
4667 do {
4668 var el = currentParent,
4669 rect = getRect(el),
4670 top = rect.top,
4671 bottom = rect.bottom,
4672 left = rect.left,
4673 right = rect.right,
4674 width = rect.width,
4675 height = rect.height,
4676 canScrollX = void 0,
4677 canScrollY = void 0,
4678 scrollWidth = el.scrollWidth,
4679 scrollHeight = el.scrollHeight,
4680 elCSS = css(el),
4681 scrollPosX = el.scrollLeft,
4682 scrollPosY = el.scrollTop;
4683 if (el === winScroller) {
4684 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
4685 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
4686 } else {
4687 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
4688 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
4689 }
4690 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
4691 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
4692 if (!autoScrolls[layersOut]) {
4693 for (var i = 0; i <= layersOut; i++) {
4694 if (!autoScrolls[i]) {
4695 autoScrolls[i] = {};
4696 }
4697 }
4698 }
4699 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
4700 autoScrolls[layersOut].el = el;
4701 autoScrolls[layersOut].vx = vx;
4702 autoScrolls[layersOut].vy = vy;
4703 clearInterval(autoScrolls[layersOut].pid);
4704 if (vx != 0 || vy != 0) {
4705 scrollThisInstance = true;
4706 /* jshint loopfunc:true */
4707 autoScrolls[layersOut].pid = setInterval(function () {
4708 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
4709 if (isFallback && this.layer === 0) {
4710 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
4711 }
4712 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
4713 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
4714 if (typeof scrollCustomFn === 'function') {
4715 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
4716 return;
4717 }
4718 }
4719 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
4720 }.bind({
4721 layer: layersOut
4722 }), 24);
4723 }
4724 }
4725 layersOut++;
4726 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
4727 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
4728 }, 30);
4729
4730 var drop = function drop(_ref) {
4731 var originalEvent = _ref.originalEvent,
4732 putSortable = _ref.putSortable,
4733 dragEl = _ref.dragEl,
4734 activeSortable = _ref.activeSortable,
4735 dispatchSortableEvent = _ref.dispatchSortableEvent,
4736 hideGhostForTarget = _ref.hideGhostForTarget,
4737 unhideGhostForTarget = _ref.unhideGhostForTarget;
4738 if (!originalEvent) return;
4739 var toSortable = putSortable || activeSortable;
4740 hideGhostForTarget();
4741 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
4742 var target = document.elementFromPoint(touch.clientX, touch.clientY);
4743 unhideGhostForTarget();
4744 if (toSortable && !toSortable.el.contains(target)) {
4745 dispatchSortableEvent('spill');
4746 this.onSpill({
4747 dragEl: dragEl,
4748 putSortable: putSortable
4749 });
4750 }
4751 };
4752 function Revert() {}
4753 Revert.prototype = {
4754 startIndex: null,
4755 dragStart: function dragStart(_ref2) {
4756 var oldDraggableIndex = _ref2.oldDraggableIndex;
4757 this.startIndex = oldDraggableIndex;
4758 },
4759 onSpill: function onSpill(_ref3) {
4760 var dragEl = _ref3.dragEl,
4761 putSortable = _ref3.putSortable;
4762 this.sortable.captureAnimationState();
4763 if (putSortable) {
4764 putSortable.captureAnimationState();
4765 }
4766 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
4767 if (nextSibling) {
4768 this.sortable.el.insertBefore(dragEl, nextSibling);
4769 } else {
4770 this.sortable.el.appendChild(dragEl);
4771 }
4772 this.sortable.animateAll();
4773 if (putSortable) {
4774 putSortable.animateAll();
4775 }
4776 },
4777 drop: drop
4778 };
4779 _extends(Revert, {
4780 pluginName: 'revertOnSpill'
4781 });
4782 function Remove() {}
4783 Remove.prototype = {
4784 onSpill: function onSpill(_ref4) {
4785 var dragEl = _ref4.dragEl,
4786 putSortable = _ref4.putSortable;
4787 var parentSortable = putSortable || this.sortable;
4788 parentSortable.captureAnimationState();
4789 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
4790 parentSortable.animateAll();
4791 },
4792 drop: drop
4793 };
4794 _extends(Remove, {
4795 pluginName: 'removeOnSpill'
4796 });
4797
4798 var lastSwapEl;
4799 function SwapPlugin() {
4800 function Swap() {
4801 this.defaults = {
4802 swapClass: 'sortable-swap-highlight'
4803 };
4804 }
4805 Swap.prototype = {
4806 dragStart: function dragStart(_ref) {
4807 var dragEl = _ref.dragEl;
4808 lastSwapEl = dragEl;
4809 },
4810 dragOverValid: function dragOverValid(_ref2) {
4811 var completed = _ref2.completed,
4812 target = _ref2.target,
4813 onMove = _ref2.onMove,
4814 activeSortable = _ref2.activeSortable,
4815 changed = _ref2.changed,
4816 cancel = _ref2.cancel;
4817 if (!activeSortable.options.swap) return;
4818 var el = this.sortable.el,
4819 options = this.options;
4820 if (target && target !== el) {
4821 var prevSwapEl = lastSwapEl;
4822 if (onMove(target) !== false) {
4823 toggleClass(target, options.swapClass, true);
4824 lastSwapEl = target;
4825 } else {
4826 lastSwapEl = null;
4827 }
4828 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
4829 toggleClass(prevSwapEl, options.swapClass, false);
4830 }
4831 }
4832 changed();
4833 completed(true);
4834 cancel();
4835 },
4836 drop: function drop(_ref3) {
4837 var activeSortable = _ref3.activeSortable,
4838 putSortable = _ref3.putSortable,
4839 dragEl = _ref3.dragEl;
4840 var toSortable = putSortable || this.sortable;
4841 var options = this.options;
4842 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
4843 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
4844 if (dragEl !== lastSwapEl) {
4845 toSortable.captureAnimationState();
4846 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
4847 swapNodes(dragEl, lastSwapEl);
4848 toSortable.animateAll();
4849 if (toSortable !== activeSortable) activeSortable.animateAll();
4850 }
4851 }
4852 },
4853 nulling: function nulling() {
4854 lastSwapEl = null;
4855 }
4856 };
4857 return _extends(Swap, {
4858 pluginName: 'swap',
4859 eventProperties: function eventProperties() {
4860 return {
4861 swapItem: lastSwapEl
4862 };
4863 }
4864 });
4865 }
4866 function swapNodes(n1, n2) {
4867 var p1 = n1.parentNode,
4868 p2 = n2.parentNode,
4869 i1,
4870 i2;
4871 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
4872 i1 = index(n1);
4873 i2 = index(n2);
4874 if (p1.isEqualNode(p2) && i1 < i2) {
4875 i2++;
4876 }
4877 p1.insertBefore(n2, p1.children[i1]);
4878 p2.insertBefore(n1, p2.children[i2]);
4879 }
4880
4881 var multiDragElements = [],
4882 multiDragClones = [],
4883 lastMultiDragSelect,
4884 // for selection with modifier key down (SHIFT)
4885 multiDragSortable,
4886 initialFolding = false,
4887 // Initial multi-drag fold when drag started
4888 folding = false,
4889 // Folding any other time
4890 dragStarted = false,
4891 dragEl$1,
4892 clonesFromRect,
4893 clonesHidden;
4894 function MultiDragPlugin() {
4895 function MultiDrag(sortable) {
4896 // Bind all private methods
4897 for (var fn in this) {
4898 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4899 this[fn] = this[fn].bind(this);
4900 }
4901 }
4902 if (!sortable.options.avoidImplicitDeselect) {
4903 if (sortable.options.supportPointer) {
4904 on(document, 'pointerup', this._deselectMultiDrag);
4905 } else {
4906 on(document, 'mouseup', this._deselectMultiDrag);
4907 on(document, 'touchend', this._deselectMultiDrag);
4908 }
4909 }
4910 on(document, 'keydown', this._checkKeyDown);
4911 on(document, 'keyup', this._checkKeyUp);
4912 this.defaults = {
4913 selectedClass: 'sortable-selected',
4914 multiDragKey: null,
4915 avoidImplicitDeselect: false,
4916 setData: function setData(dataTransfer, dragEl) {
4917 var data = '';
4918 if (multiDragElements.length && multiDragSortable === sortable) {
4919 multiDragElements.forEach(function (multiDragElement, i) {
4920 data += (!i ? '' : ', ') + multiDragElement.textContent;
4921 });
4922 } else {
4923 data = dragEl.textContent;
4924 }
4925 dataTransfer.setData('Text', data);
4926 }
4927 };
4928 }
4929 MultiDrag.prototype = {
4930 multiDragKeyDown: false,
4931 isMultiDrag: false,
4932 delayStartGlobal: function delayStartGlobal(_ref) {
4933 var dragged = _ref.dragEl;
4934 dragEl$1 = dragged;
4935 },
4936 delayEnded: function delayEnded() {
4937 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
4938 },
4939 setupClone: function setupClone(_ref2) {
4940 var sortable = _ref2.sortable,
4941 cancel = _ref2.cancel;
4942 if (!this.isMultiDrag) return;
4943 for (var i = 0; i < multiDragElements.length; i++) {
4944 multiDragClones.push(clone(multiDragElements[i]));
4945 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
4946 multiDragClones[i].draggable = false;
4947 multiDragClones[i].style['will-change'] = '';
4948 toggleClass(multiDragClones[i], this.options.selectedClass, false);
4949 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
4950 }
4951 sortable._hideClone();
4952 cancel();
4953 },
4954 clone: function clone(_ref3) {
4955 var sortable = _ref3.sortable,
4956 rootEl = _ref3.rootEl,
4957 dispatchSortableEvent = _ref3.dispatchSortableEvent,
4958 cancel = _ref3.cancel;
4959 if (!this.isMultiDrag) return;
4960 if (!this.options.removeCloneOnHide) {
4961 if (multiDragElements.length && multiDragSortable === sortable) {
4962 insertMultiDragClones(true, rootEl);
4963 dispatchSortableEvent('clone');
4964 cancel();
4965 }
4966 }
4967 },
4968 showClone: function showClone(_ref4) {
4969 var cloneNowShown = _ref4.cloneNowShown,
4970 rootEl = _ref4.rootEl,
4971 cancel = _ref4.cancel;
4972 if (!this.isMultiDrag) return;
4973 insertMultiDragClones(false, rootEl);
4974 multiDragClones.forEach(function (clone) {
4975 css(clone, 'display', '');
4976 });
4977 cloneNowShown();
4978 clonesHidden = false;
4979 cancel();
4980 },
4981 hideClone: function hideClone(_ref5) {
4982 var _this = this;
4983 var sortable = _ref5.sortable,
4984 cloneNowHidden = _ref5.cloneNowHidden,
4985 cancel = _ref5.cancel;
4986 if (!this.isMultiDrag) return;
4987 multiDragClones.forEach(function (clone) {
4988 css(clone, 'display', 'none');
4989 if (_this.options.removeCloneOnHide && clone.parentNode) {
4990 clone.parentNode.removeChild(clone);
4991 }
4992 });
4993 cloneNowHidden();
4994 clonesHidden = true;
4995 cancel();
4996 },
4997 dragStartGlobal: function dragStartGlobal(_ref6) {
4998 var sortable = _ref6.sortable;
4999 if (!this.isMultiDrag && multiDragSortable) {
5000 multiDragSortable.multiDrag._deselectMultiDrag();
5001 }
5002 multiDragElements.forEach(function (multiDragElement) {
5003 multiDragElement.sortableIndex = index(multiDragElement);
5004 });
5005
5006 // Sort multi-drag elements
5007 multiDragElements = multiDragElements.sort(function (a, b) {
5008 return a.sortableIndex - b.sortableIndex;
5009 });
5010 dragStarted = true;
5011 },
5012 dragStarted: function dragStarted(_ref7) {
5013 var _this2 = this;
5014 var sortable = _ref7.sortable;
5015 if (!this.isMultiDrag) return;
5016 if (this.options.sort) {
5017 // Capture rects,
5018 // hide multi drag elements (by positioning them absolute),
5019 // set multi drag elements rects to dragRect,
5020 // show multi drag elements,
5021 // animate to rects,
5022 // unset rects & remove from DOM
5023
5024 sortable.captureAnimationState();
5025 if (this.options.animation) {
5026 multiDragElements.forEach(function (multiDragElement) {
5027 if (multiDragElement === dragEl$1) return;
5028 css(multiDragElement, 'position', 'absolute');
5029 });
5030 var dragRect = getRect(dragEl$1, false, true, true);
5031 multiDragElements.forEach(function (multiDragElement) {
5032 if (multiDragElement === dragEl$1) return;
5033 setRect(multiDragElement, dragRect);
5034 });
5035 folding = true;
5036 initialFolding = true;
5037 }
5038 }
5039 sortable.animateAll(function () {
5040 folding = false;
5041 initialFolding = false;
5042 if (_this2.options.animation) {
5043 multiDragElements.forEach(function (multiDragElement) {
5044 unsetRect(multiDragElement);
5045 });
5046 }
5047
5048 // Remove all auxiliary multidrag items from el, if sorting enabled
5049 if (_this2.options.sort) {
5050 removeMultiDragElements();
5051 }
5052 });
5053 },
5054 dragOver: function dragOver(_ref8) {
5055 var target = _ref8.target,
5056 completed = _ref8.completed,
5057 cancel = _ref8.cancel;
5058 if (folding && ~multiDragElements.indexOf(target)) {
5059 completed(false);
5060 cancel();
5061 }
5062 },
5063 revert: function revert(_ref9) {
5064 var fromSortable = _ref9.fromSortable,
5065 rootEl = _ref9.rootEl,
5066 sortable = _ref9.sortable,
5067 dragRect = _ref9.dragRect;
5068 if (multiDragElements.length > 1) {
5069 // Setup unfold animation
5070 multiDragElements.forEach(function (multiDragElement) {
5071 sortable.addAnimationState({
5072 target: multiDragElement,
5073 rect: folding ? getRect(multiDragElement) : dragRect
5074 });
5075 unsetRect(multiDragElement);
5076 multiDragElement.fromRect = dragRect;
5077 fromSortable.removeAnimationState(multiDragElement);
5078 });
5079 folding = false;
5080 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
5081 }
5082 },
5083 dragOverCompleted: function dragOverCompleted(_ref10) {
5084 var sortable = _ref10.sortable,
5085 isOwner = _ref10.isOwner,
5086 insertion = _ref10.insertion,
5087 activeSortable = _ref10.activeSortable,
5088 parentEl = _ref10.parentEl,
5089 putSortable = _ref10.putSortable;
5090 var options = this.options;
5091 if (insertion) {
5092 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5093 if (isOwner) {
5094 activeSortable._hideClone();
5095 }
5096 initialFolding = false;
5097 // If leaving sort:false root, or already folding - Fold to new location
5098 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
5099 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
5100 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
5101 multiDragElements.forEach(function (multiDragElement) {
5102 if (multiDragElement === dragEl$1) return;
5103 setRect(multiDragElement, dragRectAbsolute);
5104
5105 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
5106 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
5107 parentEl.appendChild(multiDragElement);
5108 });
5109 folding = true;
5110 }
5111
5112 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
5113 if (!isOwner) {
5114 // Only remove if not folding (folding will remove them anyways)
5115 if (!folding) {
5116 removeMultiDragElements();
5117 }
5118 if (multiDragElements.length > 1) {
5119 var clonesHiddenBefore = clonesHidden;
5120 activeSortable._showClone(sortable);
5121
5122 // Unfold animation for clones if showing from hidden
5123 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
5124 multiDragClones.forEach(function (clone) {
5125 activeSortable.addAnimationState({
5126 target: clone,
5127 rect: clonesFromRect
5128 });
5129 clone.fromRect = clonesFromRect;
5130 clone.thisAnimationDuration = null;
5131 });
5132 }
5133 } else {
5134 activeSortable._showClone(sortable);
5135 }
5136 }
5137 }
5138 },
5139 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
5140 var dragRect = _ref11.dragRect,
5141 isOwner = _ref11.isOwner,
5142 activeSortable = _ref11.activeSortable;
5143 multiDragElements.forEach(function (multiDragElement) {
5144 multiDragElement.thisAnimationDuration = null;
5145 });
5146 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
5147 clonesFromRect = _extends({}, dragRect);
5148 var dragMatrix = matrix(dragEl$1, true);
5149 clonesFromRect.top -= dragMatrix.f;
5150 clonesFromRect.left -= dragMatrix.e;
5151 }
5152 },
5153 dragOverAnimationComplete: function dragOverAnimationComplete() {
5154 if (folding) {
5155 folding = false;
5156 removeMultiDragElements();
5157 }
5158 },
5159 drop: function drop(_ref12) {
5160 var evt = _ref12.originalEvent,
5161 rootEl = _ref12.rootEl,
5162 parentEl = _ref12.parentEl,
5163 sortable = _ref12.sortable,
5164 dispatchSortableEvent = _ref12.dispatchSortableEvent,
5165 oldIndex = _ref12.oldIndex,
5166 putSortable = _ref12.putSortable;
5167 var toSortable = putSortable || this.sortable;
5168 if (!evt) return;
5169 var options = this.options,
5170 children = parentEl.children;
5171
5172 // Multi-drag selection
5173 if (!dragStarted) {
5174 if (options.multiDragKey && !this.multiDragKeyDown) {
5175 this._deselectMultiDrag();
5176 }
5177 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
5178 if (!~multiDragElements.indexOf(dragEl$1)) {
5179 multiDragElements.push(dragEl$1);
5180 dispatchEvent({
5181 sortable: sortable,
5182 rootEl: rootEl,
5183 name: 'select',
5184 targetEl: dragEl$1,
5185 originalEvent: evt
5186 });
5187
5188 // Modifier activated, select from last to dragEl
5189 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
5190 var lastIndex = index(lastMultiDragSelect),
5191 currentIndex = index(dragEl$1);
5192 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
5193 (function () {
5194 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
5195 // (but previous selection existed)
5196 var n, i;
5197 if (currentIndex > lastIndex) {
5198 i = lastIndex;
5199 n = currentIndex;
5200 } else {
5201 i = currentIndex;
5202 n = lastIndex + 1;
5203 }
5204 var filter = options.filter;
5205 for (; i < n; i++) {
5206 if (~multiDragElements.indexOf(children[i])) continue;
5207 // Check if element is draggable
5208 if (!closest(children[i], options.draggable, parentEl, false)) continue;
5209 // Check if element is filtered
5210 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
5211 return closest(children[i], criteria.trim(), parentEl, false);
5212 }));
5213 if (filtered) continue;
5214 toggleClass(children[i], options.selectedClass, true);
5215 multiDragElements.push(children[i]);
5216 dispatchEvent({
5217 sortable: sortable,
5218 rootEl: rootEl,
5219 name: 'select',
5220 targetEl: children[i],
5221 originalEvent: evt
5222 });
5223 }
5224 })();
5225 }
5226 } else {
5227 lastMultiDragSelect = dragEl$1;
5228 }
5229 multiDragSortable = toSortable;
5230 } else {
5231 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
5232 lastMultiDragSelect = null;
5233 dispatchEvent({
5234 sortable: sortable,
5235 rootEl: rootEl,
5236 name: 'deselect',
5237 targetEl: dragEl$1,
5238 originalEvent: evt
5239 });
5240 }
5241 }
5242
5243 // Multi-drag drop
5244 if (dragStarted && this.isMultiDrag) {
5245 folding = false;
5246 // Do not "unfold" after around dragEl if reverted
5247 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
5248 var dragRect = getRect(dragEl$1),
5249 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
5250 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
5251 toSortable.captureAnimationState();
5252 if (!initialFolding) {
5253 if (options.animation) {
5254 dragEl$1.fromRect = dragRect;
5255 multiDragElements.forEach(function (multiDragElement) {
5256 multiDragElement.thisAnimationDuration = null;
5257 if (multiDragElement !== dragEl$1) {
5258 var rect = folding ? getRect(multiDragElement) : dragRect;
5259 multiDragElement.fromRect = rect;
5260
5261 // Prepare unfold animation
5262 toSortable.addAnimationState({
5263 target: multiDragElement,
5264 rect: rect
5265 });
5266 }
5267 });
5268 }
5269
5270 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
5271 // properly they must all be removed
5272 removeMultiDragElements();
5273 multiDragElements.forEach(function (multiDragElement) {
5274 if (children[multiDragIndex]) {
5275 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
5276 } else {
5277 parentEl.appendChild(multiDragElement);
5278 }
5279 multiDragIndex++;
5280 });
5281
5282 // If initial folding is done, the elements may have changed position because they are now
5283 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
5284 // must be fired here as Sortable will not.
5285 if (oldIndex === index(dragEl$1)) {
5286 var update = false;
5287 multiDragElements.forEach(function (multiDragElement) {
5288 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
5289 update = true;
5290 return;
5291 }
5292 });
5293 if (update) {
5294 dispatchSortableEvent('update');
5295 dispatchSortableEvent('sort');
5296 }
5297 }
5298 }
5299
5300 // Must be done after capturing individual rects (scroll bar)
5301 multiDragElements.forEach(function (multiDragElement) {
5302 unsetRect(multiDragElement);
5303 });
5304 toSortable.animateAll();
5305 }
5306 multiDragSortable = toSortable;
5307 }
5308
5309 // Remove clones if necessary
5310 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5311 multiDragClones.forEach(function (clone) {
5312 clone.parentNode && clone.parentNode.removeChild(clone);
5313 });
5314 }
5315 },
5316 nullingGlobal: function nullingGlobal() {
5317 this.isMultiDrag = dragStarted = false;
5318 multiDragClones.length = 0;
5319 },
5320 destroyGlobal: function destroyGlobal() {
5321 this._deselectMultiDrag();
5322 off(document, 'pointerup', this._deselectMultiDrag);
5323 off(document, 'mouseup', this._deselectMultiDrag);
5324 off(document, 'touchend', this._deselectMultiDrag);
5325 off(document, 'keydown', this._checkKeyDown);
5326 off(document, 'keyup', this._checkKeyUp);
5327 },
5328 _deselectMultiDrag: function _deselectMultiDrag(evt) {
5329 if (typeof dragStarted !== "undefined" && dragStarted) return;
5330
5331 // Only deselect if selection is in this sortable
5332 if (multiDragSortable !== this.sortable) return;
5333
5334 // Only deselect if target is not item in this sortable
5335 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
5336
5337 // Only deselect if left click
5338 if (evt && evt.button !== 0) return;
5339 while (multiDragElements.length) {
5340 var el = multiDragElements[0];
5341 toggleClass(el, this.options.selectedClass, false);
5342 multiDragElements.shift();
5343 dispatchEvent({
5344 sortable: this.sortable,
5345 rootEl: this.sortable.el,
5346 name: 'deselect',
5347 targetEl: el,
5348 originalEvent: evt
5349 });
5350 }
5351 },
5352 _checkKeyDown: function _checkKeyDown(evt) {
5353 if (evt.key === this.options.multiDragKey) {
5354 this.multiDragKeyDown = true;
5355 }
5356 },
5357 _checkKeyUp: function _checkKeyUp(evt) {
5358 if (evt.key === this.options.multiDragKey) {
5359 this.multiDragKeyDown = false;
5360 }
5361 }
5362 };
5363 return _extends(MultiDrag, {
5364 // Static methods & properties
5365 pluginName: 'multiDrag',
5366 utils: {
5367 /**
5368 * Selects the provided multi-drag item
5369 * @param {HTMLElement} el The element to be selected
5370 */
5371 select: function select(el) {
5372 var sortable = el.parentNode[expando];
5373 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
5374 if (multiDragSortable && multiDragSortable !== sortable) {
5375 multiDragSortable.multiDrag._deselectMultiDrag();
5376 multiDragSortable = sortable;
5377 }
5378 toggleClass(el, sortable.options.selectedClass, true);
5379 multiDragElements.push(el);
5380 },
5381 /**
5382 * Deselects the provided multi-drag item
5383 * @param {HTMLElement} el The element to be deselected
5384 */
5385 deselect: function deselect(el) {
5386 var sortable = el.parentNode[expando],
5387 index = multiDragElements.indexOf(el);
5388 if (!sortable || !sortable.options.multiDrag || !~index) return;
5389 toggleClass(el, sortable.options.selectedClass, false);
5390 multiDragElements.splice(index, 1);
5391 }
5392 },
5393 eventProperties: function eventProperties() {
5394 var _this3 = this;
5395 var oldIndicies = [],
5396 newIndicies = [];
5397 multiDragElements.forEach(function (multiDragElement) {
5398 oldIndicies.push({
5399 multiDragElement: multiDragElement,
5400 index: multiDragElement.sortableIndex
5401 });
5402
5403 // multiDragElements will already be sorted if folding
5404 var newIndex;
5405 if (folding && multiDragElement !== dragEl$1) {
5406 newIndex = -1;
5407 } else if (folding) {
5408 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
5409 } else {
5410 newIndex = index(multiDragElement);
5411 }
5412 newIndicies.push({
5413 multiDragElement: multiDragElement,
5414 index: newIndex
5415 });
5416 });
5417 return {
5418 items: _toConsumableArray(multiDragElements),
5419 clones: [].concat(multiDragClones),
5420 oldIndicies: oldIndicies,
5421 newIndicies: newIndicies
5422 };
5423 },
5424 optionListeners: {
5425 multiDragKey: function multiDragKey(key) {
5426 key = key.toLowerCase();
5427 if (key === 'ctrl') {
5428 key = 'Control';
5429 } else if (key.length > 1) {
5430 key = key.charAt(0).toUpperCase() + key.substr(1);
5431 }
5432 return key;
5433 }
5434 }
5435 });
5436 }
5437 function insertMultiDragElements(clonesInserted, rootEl) {
5438 multiDragElements.forEach(function (multiDragElement, i) {
5439 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
5440 if (target) {
5441 rootEl.insertBefore(multiDragElement, target);
5442 } else {
5443 rootEl.appendChild(multiDragElement);
5444 }
5445 });
5446 }
5447
5448 /**
5449 * Insert multi-drag clones
5450 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
5451 * @param {HTMLElement} rootEl
5452 */
5453 function insertMultiDragClones(elementsInserted, rootEl) {
5454 multiDragClones.forEach(function (clone, i) {
5455 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
5456 if (target) {
5457 rootEl.insertBefore(clone, target);
5458 } else {
5459 rootEl.appendChild(clone);
5460 }
5461 });
5462 }
5463 function removeMultiDragElements() {
5464 multiDragElements.forEach(function (multiDragElement) {
5465 if (multiDragElement === dragEl$1) return;
5466 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
5467 });
5468 }
5469
5470 Sortable.mount(new AutoScrollPlugin());
5471 Sortable.mount(Remove, Revert);
5472
5473 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
5474
5475
5476
5477 /***/ }),
5478
5479 /***/ "./node_modules/toastify-js/src/toastify.css":
5480 /*!***************************************************!*\
5481 !*** ./node_modules/toastify-js/src/toastify.css ***!
5482 \***************************************************/
5483 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5484
5485 "use strict";
5486 __webpack_require__.r(__webpack_exports__);
5487 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5488 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5489 /* harmony export */ });
5490 /* 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");
5491 /* 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__);
5492 /* 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");
5493 /* 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__);
5494 /* 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");
5495 /* 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__);
5496 /* 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");
5497 /* 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__);
5498 /* 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");
5499 /* 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__);
5500 /* 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");
5501 /* 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__);
5502 /* 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");
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514 var options = {};
5515
5516 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5517 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5518
5519 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5520
5521 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5522 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5523
5524 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);
5525
5526
5527
5528
5529 /* 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);
5530
5531
5532 /***/ }),
5533
5534 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
5535 /*!****************************************************************************!*\
5536 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5537 \****************************************************************************/
5538 /***/ ((module) => {
5539
5540 "use strict";
5541
5542
5543 var stylesInDOM = [];
5544 function getIndexByIdentifier(identifier) {
5545 var result = -1;
5546 for (var i = 0; i < stylesInDOM.length; i++) {
5547 if (stylesInDOM[i].identifier === identifier) {
5548 result = i;
5549 break;
5550 }
5551 }
5552 return result;
5553 }
5554 function modulesToDom(list, options) {
5555 var idCountMap = {};
5556 var identifiers = [];
5557 for (var i = 0; i < list.length; i++) {
5558 var item = list[i];
5559 var id = options.base ? item[0] + options.base : item[0];
5560 var count = idCountMap[id] || 0;
5561 var identifier = "".concat(id, " ").concat(count);
5562 idCountMap[id] = count + 1;
5563 var indexByIdentifier = getIndexByIdentifier(identifier);
5564 var obj = {
5565 css: item[1],
5566 media: item[2],
5567 sourceMap: item[3],
5568 supports: item[4],
5569 layer: item[5]
5570 };
5571 if (indexByIdentifier !== -1) {
5572 stylesInDOM[indexByIdentifier].references++;
5573 stylesInDOM[indexByIdentifier].updater(obj);
5574 } else {
5575 var updater = addElementStyle(obj, options);
5576 options.byIndex = i;
5577 stylesInDOM.splice(i, 0, {
5578 identifier: identifier,
5579 updater: updater,
5580 references: 1
5581 });
5582 }
5583 identifiers.push(identifier);
5584 }
5585 return identifiers;
5586 }
5587 function addElementStyle(obj, options) {
5588 var api = options.domAPI(options);
5589 api.update(obj);
5590 var updater = function updater(newObj) {
5591 if (newObj) {
5592 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5593 return;
5594 }
5595 api.update(obj = newObj);
5596 } else {
5597 api.remove();
5598 }
5599 };
5600 return updater;
5601 }
5602 module.exports = function (list, options) {
5603 options = options || {};
5604 list = list || [];
5605 var lastIdentifiers = modulesToDom(list, options);
5606 return function update(newList) {
5607 newList = newList || [];
5608 for (var i = 0; i < lastIdentifiers.length; i++) {
5609 var identifier = lastIdentifiers[i];
5610 var index = getIndexByIdentifier(identifier);
5611 stylesInDOM[index].references--;
5612 }
5613 var newLastIdentifiers = modulesToDom(newList, options);
5614 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5615 var _identifier = lastIdentifiers[_i];
5616 var _index = getIndexByIdentifier(_identifier);
5617 if (stylesInDOM[_index].references === 0) {
5618 stylesInDOM[_index].updater();
5619 stylesInDOM.splice(_index, 1);
5620 }
5621 }
5622 lastIdentifiers = newLastIdentifiers;
5623 };
5624 };
5625
5626 /***/ }),
5627
5628 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js":
5629 /*!********************************************************************!*\
5630 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5631 \********************************************************************/
5632 /***/ ((module) => {
5633
5634 "use strict";
5635
5636
5637 var memo = {};
5638
5639 /* istanbul ignore next */
5640 function getTarget(target) {
5641 if (typeof memo[target] === "undefined") {
5642 var styleTarget = document.querySelector(target);
5643
5644 // Special case to return head of iframe instead of iframe itself
5645 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5646 try {
5647 // This will throw an exception if access to iframe is blocked
5648 // due to cross-origin restrictions
5649 styleTarget = styleTarget.contentDocument.head;
5650 } catch (e) {
5651 // istanbul ignore next
5652 styleTarget = null;
5653 }
5654 }
5655 memo[target] = styleTarget;
5656 }
5657 return memo[target];
5658 }
5659
5660 /* istanbul ignore next */
5661 function insertBySelector(insert, style) {
5662 var target = getTarget(insert);
5663 if (!target) {
5664 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
5665 }
5666 target.appendChild(style);
5667 }
5668 module.exports = insertBySelector;
5669
5670 /***/ }),
5671
5672 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js":
5673 /*!**********************************************************************!*\
5674 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
5675 \**********************************************************************/
5676 /***/ ((module) => {
5677
5678 "use strict";
5679
5680
5681 /* istanbul ignore next */
5682 function insertStyleElement(options) {
5683 var element = document.createElement("style");
5684 options.setAttributes(element, options.attributes);
5685 options.insert(element, options.options);
5686 return element;
5687 }
5688 module.exports = insertStyleElement;
5689
5690 /***/ }),
5691
5692 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js":
5693 /*!**********************************************************************************!*\
5694 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
5695 \**********************************************************************************/
5696 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
5697
5698 "use strict";
5699
5700
5701 /* istanbul ignore next */
5702 function setAttributesWithoutAttributes(styleElement) {
5703 var nonce = true ? __webpack_require__.nc : 0;
5704 if (nonce) {
5705 styleElement.setAttribute("nonce", nonce);
5706 }
5707 }
5708 module.exports = setAttributesWithoutAttributes;
5709
5710 /***/ }),
5711
5712 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js":
5713 /*!***************************************************************!*\
5714 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
5715 \***************************************************************/
5716 /***/ ((module) => {
5717
5718 "use strict";
5719
5720
5721 /* istanbul ignore next */
5722 function apply(styleElement, options, obj) {
5723 var css = "";
5724 if (obj.supports) {
5725 css += "@supports (".concat(obj.supports, ") {");
5726 }
5727 if (obj.media) {
5728 css += "@media ".concat(obj.media, " {");
5729 }
5730 var needLayer = typeof obj.layer !== "undefined";
5731 if (needLayer) {
5732 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
5733 }
5734 css += obj.css;
5735 if (needLayer) {
5736 css += "}";
5737 }
5738 if (obj.media) {
5739 css += "}";
5740 }
5741 if (obj.supports) {
5742 css += "}";
5743 }
5744 var sourceMap = obj.sourceMap;
5745 if (sourceMap && typeof btoa !== "undefined") {
5746 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
5747 }
5748
5749 // For old IE
5750 /* istanbul ignore if */
5751 options.styleTagTransform(css, styleElement, options.options);
5752 }
5753 function removeStyleElement(styleElement) {
5754 // istanbul ignore if
5755 if (styleElement.parentNode === null) {
5756 return false;
5757 }
5758 styleElement.parentNode.removeChild(styleElement);
5759 }
5760
5761 /* istanbul ignore next */
5762 function domAPI(options) {
5763 if (typeof document === "undefined") {
5764 return {
5765 update: function update() {},
5766 remove: function remove() {}
5767 };
5768 }
5769 var styleElement = options.insertStyleElement(options);
5770 return {
5771 update: function update(obj) {
5772 apply(styleElement, options, obj);
5773 },
5774 remove: function remove() {
5775 removeStyleElement(styleElement);
5776 }
5777 };
5778 }
5779 module.exports = domAPI;
5780
5781 /***/ }),
5782
5783 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js":
5784 /*!*********************************************************************!*\
5785 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
5786 \*********************************************************************/
5787 /***/ ((module) => {
5788
5789 "use strict";
5790
5791
5792 /* istanbul ignore next */
5793 function styleTagTransform(css, styleElement) {
5794 if (styleElement.styleSheet) {
5795 styleElement.styleSheet.cssText = css;
5796 } else {
5797 while (styleElement.firstChild) {
5798 styleElement.removeChild(styleElement.firstChild);
5799 }
5800 styleElement.appendChild(document.createTextNode(css));
5801 }
5802 }
5803 module.exports = styleTagTransform;
5804
5805 /***/ }),
5806
5807 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js":
5808 /*!**********************************************************!*\
5809 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
5810 \**********************************************************/
5811 /***/ (function(module) {
5812
5813 /*!
5814 * sweetalert2 v11.22.5
5815 * Released under the MIT License.
5816 */
5817 (function (global, factory) {
5818 true ? module.exports = factory() :
5819 0;
5820 })(this, (function () { 'use strict';
5821
5822 function _assertClassBrand(e, t, n) {
5823 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
5824 throw new TypeError("Private element is not present on this object");
5825 }
5826 function _checkPrivateRedeclaration(e, t) {
5827 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
5828 }
5829 function _classPrivateFieldGet2(s, a) {
5830 return s.get(_assertClassBrand(s, a));
5831 }
5832 function _classPrivateFieldInitSpec(e, t, a) {
5833 _checkPrivateRedeclaration(e, t), t.set(e, a);
5834 }
5835 function _classPrivateFieldSet2(s, a, r) {
5836 return s.set(_assertClassBrand(s, a), r), r;
5837 }
5838
5839 const RESTORE_FOCUS_TIMEOUT = 100;
5840
5841 /** @type {GlobalState} */
5842 const globalState = {};
5843 const focusPreviousActiveElement = () => {
5844 if (globalState.previousActiveElement instanceof HTMLElement) {
5845 globalState.previousActiveElement.focus();
5846 globalState.previousActiveElement = null;
5847 } else if (document.body) {
5848 document.body.focus();
5849 }
5850 };
5851
5852 /**
5853 * Restore previous active (focused) element
5854 *
5855 * @param {boolean} returnFocus
5856 * @returns {Promise<void>}
5857 */
5858 const restoreActiveElement = returnFocus => {
5859 return new Promise(resolve => {
5860 if (!returnFocus) {
5861 return resolve();
5862 }
5863 const x = window.scrollX;
5864 const y = window.scrollY;
5865 globalState.restoreFocusTimeout = setTimeout(() => {
5866 focusPreviousActiveElement();
5867 resolve();
5868 }, RESTORE_FOCUS_TIMEOUT); // issues/900
5869
5870 window.scrollTo(x, y);
5871 });
5872 };
5873
5874 const swalPrefix = 'swal2-';
5875
5876 /**
5877 * @typedef {Record<SwalClass, string>} SwalClasses
5878 */
5879
5880 /**
5881 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
5882 * @typedef {Record<SwalIcon, string>} SwalIcons
5883 */
5884
5885 /** @type {SwalClass[]} */
5886 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'];
5887 const swalClasses = classNames.reduce((acc, className) => {
5888 acc[className] = swalPrefix + className;
5889 return acc;
5890 }, /** @type {SwalClasses} */{});
5891
5892 /** @type {SwalIcon[]} */
5893 const icons = ['success', 'warning', 'info', 'question', 'error'];
5894 const iconTypes = icons.reduce((acc, icon) => {
5895 acc[icon] = swalPrefix + icon;
5896 return acc;
5897 }, /** @type {SwalIcons} */{});
5898
5899 const consolePrefix = 'SweetAlert2:';
5900
5901 /**
5902 * Capitalize the first letter of a string
5903 *
5904 * @param {string} str
5905 * @returns {string}
5906 */
5907 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
5908
5909 /**
5910 * Standardize console warnings
5911 *
5912 * @param {string | string[]} message
5913 */
5914 const warn = message => {
5915 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
5916 };
5917
5918 /**
5919 * Standardize console errors
5920 *
5921 * @param {string} message
5922 */
5923 const error = message => {
5924 console.error(`${consolePrefix} ${message}`);
5925 };
5926
5927 /**
5928 * Private global state for `warnOnce`
5929 *
5930 * @type {string[]}
5931 * @private
5932 */
5933 const previousWarnOnceMessages = [];
5934
5935 /**
5936 * Show a console warning, but only if it hasn't already been shown
5937 *
5938 * @param {string} message
5939 */
5940 const warnOnce = message => {
5941 if (!previousWarnOnceMessages.includes(message)) {
5942 previousWarnOnceMessages.push(message);
5943 warn(message);
5944 }
5945 };
5946
5947 /**
5948 * Show a one-time console warning about deprecated params/methods
5949 *
5950 * @param {string} deprecatedParam
5951 * @param {string?} useInstead
5952 */
5953 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
5954 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
5955 };
5956
5957 /**
5958 * If `arg` is a function, call it (with no arguments or context) and return the result.
5959 * Otherwise, just pass the value through
5960 *
5961 * @param {Function | any} arg
5962 * @returns {any}
5963 */
5964 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
5965
5966 /**
5967 * @param {any} arg
5968 * @returns {boolean}
5969 */
5970 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
5971
5972 /**
5973 * @param {any} arg
5974 * @returns {Promise<any>}
5975 */
5976 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
5977
5978 /**
5979 * @param {any} arg
5980 * @returns {boolean}
5981 */
5982 const isPromise = arg => arg && Promise.resolve(arg) === arg;
5983
5984 /**
5985 * Gets the popup container which contains the backdrop and the popup itself.
5986 *
5987 * @returns {HTMLElement | null}
5988 */
5989 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
5990
5991 /**
5992 * @param {string} selectorString
5993 * @returns {HTMLElement | null}
5994 */
5995 const elementBySelector = selectorString => {
5996 const container = getContainer();
5997 return container ? container.querySelector(selectorString) : null;
5998 };
5999
6000 /**
6001 * @param {string} className
6002 * @returns {HTMLElement | null}
6003 */
6004 const elementByClass = className => {
6005 return elementBySelector(`.${className}`);
6006 };
6007
6008 /**
6009 * @returns {HTMLElement | null}
6010 */
6011 const getPopup = () => elementByClass(swalClasses.popup);
6012
6013 /**
6014 * @returns {HTMLElement | null}
6015 */
6016 const getIcon = () => elementByClass(swalClasses.icon);
6017
6018 /**
6019 * @returns {HTMLElement | null}
6020 */
6021 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6022
6023 /**
6024 * @returns {HTMLElement | null}
6025 */
6026 const getTitle = () => elementByClass(swalClasses.title);
6027
6028 /**
6029 * @returns {HTMLElement | null}
6030 */
6031 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6032
6033 /**
6034 * @returns {HTMLElement | null}
6035 */
6036 const getImage = () => elementByClass(swalClasses.image);
6037
6038 /**
6039 * @returns {HTMLElement | null}
6040 */
6041 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6042
6043 /**
6044 * @returns {HTMLElement | null}
6045 */
6046 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6047
6048 /**
6049 * @returns {HTMLButtonElement | null}
6050 */
6051 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6052
6053 /**
6054 * @returns {HTMLButtonElement | null}
6055 */
6056 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6057
6058 /**
6059 * @returns {HTMLButtonElement | null}
6060 */
6061 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6062
6063 /**
6064 * @returns {HTMLElement | null}
6065 */
6066 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6067
6068 /**
6069 * @returns {HTMLElement | null}
6070 */
6071 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6072
6073 /**
6074 * @returns {HTMLElement | null}
6075 */
6076 const getActions = () => elementByClass(swalClasses.actions);
6077
6078 /**
6079 * @returns {HTMLElement | null}
6080 */
6081 const getFooter = () => elementByClass(swalClasses.footer);
6082
6083 /**
6084 * @returns {HTMLElement | null}
6085 */
6086 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6087
6088 /**
6089 * @returns {HTMLElement | null}
6090 */
6091 const getCloseButton = () => elementByClass(swalClasses.close);
6092
6093 // https://github.com/jkup/focusable/blob/master/index.js
6094 const focusable = `
6095 a[href],
6096 area[href],
6097 input:not([disabled]),
6098 select:not([disabled]),
6099 textarea:not([disabled]),
6100 button:not([disabled]),
6101 iframe,
6102 object,
6103 embed,
6104 [tabindex="0"],
6105 [contenteditable],
6106 audio[controls],
6107 video[controls],
6108 summary
6109 `;
6110 /**
6111 * @returns {HTMLElement[]}
6112 */
6113 const getFocusableElements = () => {
6114 const popup = getPopup();
6115 if (!popup) {
6116 return [];
6117 }
6118 /** @type {NodeListOf<HTMLElement>} */
6119 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6120 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6121 // sort according to tabindex
6122 .sort((a, b) => {
6123 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6124 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6125 if (tabindexA > tabindexB) {
6126 return 1;
6127 } else if (tabindexA < tabindexB) {
6128 return -1;
6129 }
6130 return 0;
6131 });
6132
6133 /** @type {NodeListOf<HTMLElement>} */
6134 const otherFocusableElements = popup.querySelectorAll(focusable);
6135 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6136 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6137 };
6138
6139 /**
6140 * @returns {boolean}
6141 */
6142 const isModal = () => {
6143 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6144 };
6145
6146 /**
6147 * @returns {boolean}
6148 */
6149 const isToast = () => {
6150 const popup = getPopup();
6151 if (!popup) {
6152 return false;
6153 }
6154 return hasClass(popup, swalClasses.toast);
6155 };
6156
6157 /**
6158 * @returns {boolean}
6159 */
6160 const isLoading = () => {
6161 const popup = getPopup();
6162 if (!popup) {
6163 return false;
6164 }
6165 return popup.hasAttribute('data-loading');
6166 };
6167
6168 /**
6169 * Securely set innerHTML of an element
6170 * https://github.com/sweetalert2/sweetalert2/issues/1926
6171 *
6172 * @param {HTMLElement} elem
6173 * @param {string} html
6174 */
6175 const setInnerHtml = (elem, html) => {
6176 elem.textContent = '';
6177 if (html) {
6178 const parser = new DOMParser();
6179 const parsed = parser.parseFromString(html, `text/html`);
6180 const head = parsed.querySelector('head');
6181 if (head) {
6182 Array.from(head.childNodes).forEach(child => {
6183 elem.appendChild(child);
6184 });
6185 }
6186 const body = parsed.querySelector('body');
6187 if (body) {
6188 Array.from(body.childNodes).forEach(child => {
6189 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6190 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6191 } else {
6192 elem.appendChild(child);
6193 }
6194 });
6195 }
6196 }
6197 };
6198
6199 /**
6200 * @param {HTMLElement} elem
6201 * @param {string} className
6202 * @returns {boolean}
6203 */
6204 const hasClass = (elem, className) => {
6205 if (!className) {
6206 return false;
6207 }
6208 const classList = className.split(/\s+/);
6209 for (let i = 0; i < classList.length; i++) {
6210 if (!elem.classList.contains(classList[i])) {
6211 return false;
6212 }
6213 }
6214 return true;
6215 };
6216
6217 /**
6218 * @param {HTMLElement} elem
6219 * @param {SweetAlertOptions} params
6220 */
6221 const removeCustomClasses = (elem, params) => {
6222 Array.from(elem.classList).forEach(className => {
6223 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6224 elem.classList.remove(className);
6225 }
6226 });
6227 };
6228
6229 /**
6230 * @param {HTMLElement} elem
6231 * @param {SweetAlertOptions} params
6232 * @param {string} className
6233 */
6234 const applyCustomClass = (elem, params, className) => {
6235 removeCustomClasses(elem, params);
6236 if (!params.customClass) {
6237 return;
6238 }
6239 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6240 if (!customClass) {
6241 return;
6242 }
6243 if (typeof customClass !== 'string' && !customClass.forEach) {
6244 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6245 return;
6246 }
6247 addClass(elem, customClass);
6248 };
6249
6250 /**
6251 * @param {HTMLElement} popup
6252 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6253 * @returns {HTMLInputElement | null}
6254 */
6255 const getInput$1 = (popup, inputClass) => {
6256 if (!inputClass) {
6257 return null;
6258 }
6259 switch (inputClass) {
6260 case 'select':
6261 case 'textarea':
6262 case 'file':
6263 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6264 case 'checkbox':
6265 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6266 case 'radio':
6267 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6268 case 'range':
6269 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6270 default:
6271 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6272 }
6273 };
6274
6275 /**
6276 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6277 */
6278 const focusInput = input => {
6279 input.focus();
6280
6281 // place cursor at end of text in text input
6282 if (input.type !== 'file') {
6283 // http://stackoverflow.com/a/2345915
6284 const val = input.value;
6285 input.value = '';
6286 input.value = val;
6287 }
6288 };
6289
6290 /**
6291 * @param {HTMLElement | HTMLElement[] | null} target
6292 * @param {string | string[] | readonly string[] | undefined} classList
6293 * @param {boolean} condition
6294 */
6295 const toggleClass = (target, classList, condition) => {
6296 if (!target || !classList) {
6297 return;
6298 }
6299 if (typeof classList === 'string') {
6300 classList = classList.split(/\s+/).filter(Boolean);
6301 }
6302 classList.forEach(className => {
6303 if (Array.isArray(target)) {
6304 target.forEach(elem => {
6305 if (condition) {
6306 elem.classList.add(className);
6307 } else {
6308 elem.classList.remove(className);
6309 }
6310 });
6311 } else {
6312 if (condition) {
6313 target.classList.add(className);
6314 } else {
6315 target.classList.remove(className);
6316 }
6317 }
6318 });
6319 };
6320
6321 /**
6322 * @param {HTMLElement | HTMLElement[] | null} target
6323 * @param {string | string[] | readonly string[] | undefined} classList
6324 */
6325 const addClass = (target, classList) => {
6326 toggleClass(target, classList, true);
6327 };
6328
6329 /**
6330 * @param {HTMLElement | HTMLElement[] | null} target
6331 * @param {string | string[] | readonly string[] | undefined} classList
6332 */
6333 const removeClass = (target, classList) => {
6334 toggleClass(target, classList, false);
6335 };
6336
6337 /**
6338 * Get direct child of an element by class name
6339 *
6340 * @param {HTMLElement} elem
6341 * @param {string} className
6342 * @returns {HTMLElement | undefined}
6343 */
6344 const getDirectChildByClass = (elem, className) => {
6345 const children = Array.from(elem.children);
6346 for (let i = 0; i < children.length; i++) {
6347 const child = children[i];
6348 if (child instanceof HTMLElement && hasClass(child, className)) {
6349 return child;
6350 }
6351 }
6352 };
6353
6354 /**
6355 * @param {HTMLElement} elem
6356 * @param {string} property
6357 * @param {*} value
6358 */
6359 const applyNumericalStyle = (elem, property, value) => {
6360 if (value === `${parseInt(value)}`) {
6361 value = parseInt(value);
6362 }
6363 if (value || parseInt(value) === 0) {
6364 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : value);
6365 } else {
6366 elem.style.removeProperty(property);
6367 }
6368 };
6369
6370 /**
6371 * @param {HTMLElement | null} elem
6372 * @param {string} display
6373 */
6374 const show = (elem, display = 'flex') => {
6375 if (!elem) {
6376 return;
6377 }
6378 elem.style.display = display;
6379 };
6380
6381 /**
6382 * @param {HTMLElement | null} elem
6383 */
6384 const hide = elem => {
6385 if (!elem) {
6386 return;
6387 }
6388 elem.style.display = 'none';
6389 };
6390
6391 /**
6392 * @param {HTMLElement | null} elem
6393 * @param {string} display
6394 */
6395 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6396 if (!elem) {
6397 return;
6398 }
6399 new MutationObserver(() => {
6400 toggle(elem, elem.innerHTML, display);
6401 }).observe(elem, {
6402 childList: true,
6403 subtree: true
6404 });
6405 };
6406
6407 /**
6408 * @param {HTMLElement} parent
6409 * @param {string} selector
6410 * @param {string} property
6411 * @param {string} value
6412 */
6413 const setStyle = (parent, selector, property, value) => {
6414 /** @type {HTMLElement | null} */
6415 const el = parent.querySelector(selector);
6416 if (el) {
6417 el.style.setProperty(property, value);
6418 }
6419 };
6420
6421 /**
6422 * @param {HTMLElement} elem
6423 * @param {any} condition
6424 * @param {string} display
6425 */
6426 const toggle = (elem, condition, display = 'flex') => {
6427 if (condition) {
6428 show(elem, display);
6429 } else {
6430 hide(elem);
6431 }
6432 };
6433
6434 /**
6435 * borrowed from jquery $(elem).is(':visible') implementation
6436 *
6437 * @param {HTMLElement | null} elem
6438 * @returns {boolean}
6439 */
6440 const isVisible$1 = elem => !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6441
6442 /**
6443 * @returns {boolean}
6444 */
6445 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6446
6447 /**
6448 * @param {HTMLElement} elem
6449 * @returns {boolean}
6450 */
6451 const isScrollable = elem => !!(elem.scrollHeight > elem.clientHeight);
6452
6453 /**
6454 * @param {HTMLElement} element
6455 * @param {HTMLElement} stopElement
6456 * @returns {boolean}
6457 */
6458 const selfOrParentIsScrollable = (element, stopElement) => {
6459 let parent = element;
6460 while (parent && parent !== stopElement) {
6461 if (isScrollable(parent)) {
6462 return true;
6463 }
6464 parent = parent.parentElement;
6465 }
6466 return false;
6467 };
6468
6469 /**
6470 * borrowed from https://stackoverflow.com/a/46352119
6471 *
6472 * @param {HTMLElement} elem
6473 * @returns {boolean}
6474 */
6475 const hasCssAnimation = elem => {
6476 const style = window.getComputedStyle(elem);
6477 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6478 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6479 return animDuration > 0 || transDuration > 0;
6480 };
6481
6482 /**
6483 * @param {number} timer
6484 * @param {boolean} reset
6485 */
6486 const animateTimerProgressBar = (timer, reset = false) => {
6487 const timerProgressBar = getTimerProgressBar();
6488 if (!timerProgressBar) {
6489 return;
6490 }
6491 if (isVisible$1(timerProgressBar)) {
6492 if (reset) {
6493 timerProgressBar.style.transition = 'none';
6494 timerProgressBar.style.width = '100%';
6495 }
6496 setTimeout(() => {
6497 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6498 timerProgressBar.style.width = '0%';
6499 }, 10);
6500 }
6501 };
6502 const stopTimerProgressBar = () => {
6503 const timerProgressBar = getTimerProgressBar();
6504 if (!timerProgressBar) {
6505 return;
6506 }
6507 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6508 timerProgressBar.style.removeProperty('transition');
6509 timerProgressBar.style.width = '100%';
6510 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6511 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6512 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6513 };
6514
6515 /**
6516 * Detect Node env
6517 *
6518 * @returns {boolean}
6519 */
6520 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6521
6522 const sweetHTML = `
6523 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6524 <button type="button" class="${swalClasses.close}"></button>
6525 <ul class="${swalClasses['progress-steps']}"></ul>
6526 <div class="${swalClasses.icon}"></div>
6527 <img class="${swalClasses.image}" />
6528 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6529 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6530 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6531 <input type="file" class="${swalClasses.file}" />
6532 <div class="${swalClasses.range}">
6533 <input type="range" />
6534 <output></output>
6535 </div>
6536 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6537 <div class="${swalClasses.radio}"></div>
6538 <label class="${swalClasses.checkbox}">
6539 <input type="checkbox" id="${swalClasses.checkbox}" />
6540 <span class="${swalClasses.label}"></span>
6541 </label>
6542 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6543 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6544 <div class="${swalClasses.actions}">
6545 <div class="${swalClasses.loader}"></div>
6546 <button type="button" class="${swalClasses.confirm}"></button>
6547 <button type="button" class="${swalClasses.deny}"></button>
6548 <button type="button" class="${swalClasses.cancel}"></button>
6549 </div>
6550 <div class="${swalClasses.footer}"></div>
6551 <div class="${swalClasses['timer-progress-bar-container']}">
6552 <div class="${swalClasses['timer-progress-bar']}"></div>
6553 </div>
6554 </div>
6555 `.replace(/(^|\n)\s*/g, '');
6556
6557 /**
6558 * @returns {boolean}
6559 */
6560 const resetOldContainer = () => {
6561 const oldContainer = getContainer();
6562 if (!oldContainer) {
6563 return false;
6564 }
6565 oldContainer.remove();
6566 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['has-column']]);
6567 return true;
6568 };
6569 const resetValidationMessage$1 = () => {
6570 globalState.currentInstance.resetValidationMessage();
6571 };
6572 const addInputChangeListeners = () => {
6573 const popup = getPopup();
6574 const input = getDirectChildByClass(popup, swalClasses.input);
6575 const file = getDirectChildByClass(popup, swalClasses.file);
6576 /** @type {HTMLInputElement} */
6577 const range = popup.querySelector(`.${swalClasses.range} input`);
6578 /** @type {HTMLOutputElement} */
6579 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6580 const select = getDirectChildByClass(popup, swalClasses.select);
6581 /** @type {HTMLInputElement} */
6582 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6583 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6584 input.oninput = resetValidationMessage$1;
6585 file.onchange = resetValidationMessage$1;
6586 select.onchange = resetValidationMessage$1;
6587 checkbox.onchange = resetValidationMessage$1;
6588 textarea.oninput = resetValidationMessage$1;
6589 range.oninput = () => {
6590 resetValidationMessage$1();
6591 rangeOutput.value = range.value;
6592 };
6593 range.onchange = () => {
6594 resetValidationMessage$1();
6595 rangeOutput.value = range.value;
6596 };
6597 };
6598
6599 /**
6600 * @param {string | HTMLElement} target
6601 * @returns {HTMLElement}
6602 */
6603 const getTarget = target => typeof target === 'string' ? document.querySelector(target) : target;
6604
6605 /**
6606 * @param {SweetAlertOptions} params
6607 */
6608 const setupAccessibility = params => {
6609 const popup = getPopup();
6610 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6611 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6612 if (!params.toast) {
6613 popup.setAttribute('aria-modal', 'true');
6614 }
6615 };
6616
6617 /**
6618 * @param {HTMLElement} targetElement
6619 */
6620 const setupRTL = targetElement => {
6621 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6622 addClass(getContainer(), swalClasses.rtl);
6623 }
6624 };
6625
6626 /**
6627 * Add modal + backdrop + no-war message for Russians to DOM
6628 *
6629 * @param {SweetAlertOptions} params
6630 */
6631 const init = params => {
6632 // Clean up the old popup container if it exists
6633 const oldContainerExisted = resetOldContainer();
6634 if (isNodeEnv()) {
6635 error('SweetAlert2 requires document to initialize');
6636 return;
6637 }
6638 const container = document.createElement('div');
6639 container.className = swalClasses.container;
6640 if (oldContainerExisted) {
6641 addClass(container, swalClasses['no-transition']);
6642 }
6643 setInnerHtml(container, sweetHTML);
6644 container.dataset['swal2Theme'] = params.theme;
6645 const targetElement = getTarget(params.target);
6646 targetElement.appendChild(container);
6647 if (params.topLayer) {
6648 container.setAttribute('popover', '');
6649 container.showPopover();
6650 }
6651 setupAccessibility(params);
6652 setupRTL(targetElement);
6653 addInputChangeListeners();
6654 };
6655
6656 /**
6657 * @param {HTMLElement | object | string} param
6658 * @param {HTMLElement} target
6659 */
6660 const parseHtmlToContainer = (param, target) => {
6661 // DOM element
6662 if (param instanceof HTMLElement) {
6663 target.appendChild(param);
6664 }
6665
6666 // Object
6667 else if (typeof param === 'object') {
6668 handleObject(param, target);
6669 }
6670
6671 // Plain string
6672 else if (param) {
6673 setInnerHtml(target, param);
6674 }
6675 };
6676
6677 /**
6678 * @param {any} param
6679 * @param {HTMLElement} target
6680 */
6681 const handleObject = (param, target) => {
6682 // JQuery element(s)
6683 if (param.jquery) {
6684 handleJqueryElem(target, param);
6685 }
6686
6687 // For other objects use their string representation
6688 else {
6689 setInnerHtml(target, param.toString());
6690 }
6691 };
6692
6693 /**
6694 * @param {HTMLElement} target
6695 * @param {any} elem
6696 */
6697 const handleJqueryElem = (target, elem) => {
6698 target.textContent = '';
6699 if (0 in elem) {
6700 for (let i = 0; i in elem; i++) {
6701 target.appendChild(elem[i].cloneNode(true));
6702 }
6703 } else {
6704 target.appendChild(elem.cloneNode(true));
6705 }
6706 };
6707
6708 /**
6709 * @param {SweetAlert} instance
6710 * @param {SweetAlertOptions} params
6711 */
6712 const renderActions = (instance, params) => {
6713 const actions = getActions();
6714 const loader = getLoader();
6715 if (!actions || !loader) {
6716 return;
6717 }
6718
6719 // Actions (buttons) wrapper
6720 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
6721 hide(actions);
6722 } else {
6723 show(actions);
6724 }
6725
6726 // Custom class
6727 applyCustomClass(actions, params, 'actions');
6728
6729 // Render all the buttons
6730 renderButtons(actions, loader, params);
6731
6732 // Loader
6733 setInnerHtml(loader, params.loaderHtml || '');
6734 applyCustomClass(loader, params, 'loader');
6735 };
6736
6737 /**
6738 * @param {HTMLElement} actions
6739 * @param {HTMLElement} loader
6740 * @param {SweetAlertOptions} params
6741 */
6742 function renderButtons(actions, loader, params) {
6743 const confirmButton = getConfirmButton();
6744 const denyButton = getDenyButton();
6745 const cancelButton = getCancelButton();
6746 if (!confirmButton || !denyButton || !cancelButton) {
6747 return;
6748 }
6749
6750 // Render buttons
6751 renderButton(confirmButton, 'confirm', params);
6752 renderButton(denyButton, 'deny', params);
6753 renderButton(cancelButton, 'cancel', params);
6754 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
6755 if (params.reverseButtons) {
6756 if (params.toast) {
6757 actions.insertBefore(cancelButton, confirmButton);
6758 actions.insertBefore(denyButton, confirmButton);
6759 } else {
6760 actions.insertBefore(cancelButton, loader);
6761 actions.insertBefore(denyButton, loader);
6762 actions.insertBefore(confirmButton, loader);
6763 }
6764 }
6765 }
6766
6767 /**
6768 * @param {HTMLElement} confirmButton
6769 * @param {HTMLElement} denyButton
6770 * @param {HTMLElement} cancelButton
6771 * @param {SweetAlertOptions} params
6772 */
6773 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
6774 if (!params.buttonsStyling) {
6775 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
6776 return;
6777 }
6778 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
6779
6780 // Apply custom background colors to action buttons
6781 if (params.confirmButtonColor) {
6782 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
6783 }
6784 if (params.denyButtonColor) {
6785 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
6786 }
6787 if (params.cancelButtonColor) {
6788 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
6789 }
6790
6791 // Apply the outline color to action buttons
6792 applyOutlineColor(confirmButton);
6793 applyOutlineColor(denyButton);
6794 applyOutlineColor(cancelButton);
6795 }
6796
6797 /**
6798 * @param {HTMLElement} button
6799 */
6800 function applyOutlineColor(button) {
6801 const buttonStyle = window.getComputedStyle(button);
6802 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
6803 // If the button already has a custom outline color, no need to change it
6804 return;
6805 }
6806 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
6807 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
6808 }
6809
6810 /**
6811 * @param {HTMLElement} button
6812 * @param {'confirm' | 'deny' | 'cancel'} buttonType
6813 * @param {SweetAlertOptions} params
6814 */
6815 function renderButton(button, buttonType, params) {
6816 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
6817 toggle(button, params[`show${buttonName}Button`], 'inline-block');
6818 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
6819 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
6820
6821 // Add buttons custom classes
6822 button.className = swalClasses[buttonType];
6823 applyCustomClass(button, params, `${buttonType}Button`);
6824 }
6825
6826 /**
6827 * @param {SweetAlert} instance
6828 * @param {SweetAlertOptions} params
6829 */
6830 const renderCloseButton = (instance, params) => {
6831 const closeButton = getCloseButton();
6832 if (!closeButton) {
6833 return;
6834 }
6835 setInnerHtml(closeButton, params.closeButtonHtml || '');
6836
6837 // Custom class
6838 applyCustomClass(closeButton, params, 'closeButton');
6839 toggle(closeButton, params.showCloseButton);
6840 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
6841 };
6842
6843 /**
6844 * @param {SweetAlert} instance
6845 * @param {SweetAlertOptions} params
6846 */
6847 const renderContainer = (instance, params) => {
6848 const container = getContainer();
6849 if (!container) {
6850 return;
6851 }
6852 handleBackdropParam(container, params.backdrop);
6853 handlePositionParam(container, params.position);
6854 handleGrowParam(container, params.grow);
6855
6856 // Custom class
6857 applyCustomClass(container, params, 'container');
6858 };
6859
6860 /**
6861 * @param {HTMLElement} container
6862 * @param {SweetAlertOptions['backdrop']} backdrop
6863 */
6864 function handleBackdropParam(container, backdrop) {
6865 if (typeof backdrop === 'string') {
6866 container.style.background = backdrop;
6867 } else if (!backdrop) {
6868 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
6869 }
6870 }
6871
6872 /**
6873 * @param {HTMLElement} container
6874 * @param {SweetAlertOptions['position']} position
6875 */
6876 function handlePositionParam(container, position) {
6877 if (!position) {
6878 return;
6879 }
6880 if (position in swalClasses) {
6881 addClass(container, swalClasses[position]);
6882 } else {
6883 warn('The "position" parameter is not valid, defaulting to "center"');
6884 addClass(container, swalClasses.center);
6885 }
6886 }
6887
6888 /**
6889 * @param {HTMLElement} container
6890 * @param {SweetAlertOptions['grow']} grow
6891 */
6892 function handleGrowParam(container, grow) {
6893 if (!grow) {
6894 return;
6895 }
6896 addClass(container, swalClasses[`grow-${grow}`]);
6897 }
6898
6899 /**
6900 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
6901 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
6902 * This is the approach that Babel will probably take to implement private methods/fields
6903 * https://github.com/tc39/proposal-private-methods
6904 * https://github.com/babel/babel/pull/7555
6905 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
6906 * then we can use that language feature.
6907 */
6908
6909 var privateProps = {
6910 innerParams: new WeakMap(),
6911 domCache: new WeakMap()
6912 };
6913
6914 /// <reference path="../../../../sweetalert2.d.ts"/>
6915
6916
6917 /** @type {InputClass[]} */
6918 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
6919
6920 /**
6921 * @param {SweetAlert} instance
6922 * @param {SweetAlertOptions} params
6923 */
6924 const renderInput = (instance, params) => {
6925 const popup = getPopup();
6926 if (!popup) {
6927 return;
6928 }
6929 const innerParams = privateProps.innerParams.get(instance);
6930 const rerender = !innerParams || params.input !== innerParams.input;
6931 inputClasses.forEach(inputClass => {
6932 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
6933 if (!inputContainer) {
6934 return;
6935 }
6936
6937 // set attributes
6938 setAttributes(inputClass, params.inputAttributes);
6939
6940 // set class
6941 inputContainer.className = swalClasses[inputClass];
6942 if (rerender) {
6943 hide(inputContainer);
6944 }
6945 });
6946 if (params.input) {
6947 if (rerender) {
6948 showInput(params);
6949 }
6950 // set custom class
6951 setCustomClass(params);
6952 }
6953 };
6954
6955 /**
6956 * @param {SweetAlertOptions} params
6957 */
6958 const showInput = params => {
6959 if (!params.input) {
6960 return;
6961 }
6962 if (!renderInputType[params.input]) {
6963 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
6964 return;
6965 }
6966 const inputContainer = getInputContainer(params.input);
6967 if (!inputContainer) {
6968 return;
6969 }
6970 const input = renderInputType[params.input](inputContainer, params);
6971 show(inputContainer);
6972
6973 // input autofocus
6974 if (params.inputAutoFocus) {
6975 setTimeout(() => {
6976 focusInput(input);
6977 });
6978 }
6979 };
6980
6981 /**
6982 * @param {HTMLInputElement} input
6983 */
6984 const removeAttributes = input => {
6985 for (let i = 0; i < input.attributes.length; i++) {
6986 const attrName = input.attributes[i].name;
6987 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
6988 input.removeAttribute(attrName);
6989 }
6990 }
6991 };
6992
6993 /**
6994 * @param {InputClass} inputClass
6995 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
6996 */
6997 const setAttributes = (inputClass, inputAttributes) => {
6998 const popup = getPopup();
6999 if (!popup) {
7000 return;
7001 }
7002 const input = getInput$1(popup, inputClass);
7003 if (!input) {
7004 return;
7005 }
7006 removeAttributes(input);
7007 for (const attr in inputAttributes) {
7008 input.setAttribute(attr, inputAttributes[attr]);
7009 }
7010 };
7011
7012 /**
7013 * @param {SweetAlertOptions} params
7014 */
7015 const setCustomClass = params => {
7016 if (!params.input) {
7017 return;
7018 }
7019 const inputContainer = getInputContainer(params.input);
7020 if (inputContainer) {
7021 applyCustomClass(inputContainer, params, 'input');
7022 }
7023 };
7024
7025 /**
7026 * @param {HTMLInputElement | HTMLTextAreaElement} input
7027 * @param {SweetAlertOptions} params
7028 */
7029 const setInputPlaceholder = (input, params) => {
7030 if (!input.placeholder && params.inputPlaceholder) {
7031 input.placeholder = params.inputPlaceholder;
7032 }
7033 };
7034
7035 /**
7036 * @param {Input} input
7037 * @param {Input} prependTo
7038 * @param {SweetAlertOptions} params
7039 */
7040 const setInputLabel = (input, prependTo, params) => {
7041 if (params.inputLabel) {
7042 const label = document.createElement('label');
7043 const labelClass = swalClasses['input-label'];
7044 label.setAttribute('for', input.id);
7045 label.className = labelClass;
7046 if (typeof params.customClass === 'object') {
7047 addClass(label, params.customClass.inputLabel);
7048 }
7049 label.innerText = params.inputLabel;
7050 prependTo.insertAdjacentElement('beforebegin', label);
7051 }
7052 };
7053
7054 /**
7055 * @param {SweetAlertInput} inputType
7056 * @returns {HTMLElement | undefined}
7057 */
7058 const getInputContainer = inputType => {
7059 const popup = getPopup();
7060 if (!popup) {
7061 return;
7062 }
7063 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7064 };
7065
7066 /**
7067 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7068 * @param {SweetAlertOptions['inputValue']} inputValue
7069 */
7070 const checkAndSetInputValue = (input, inputValue) => {
7071 if (['string', 'number'].includes(typeof inputValue)) {
7072 input.value = `${inputValue}`;
7073 } else if (!isPromise(inputValue)) {
7074 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7075 }
7076 };
7077
7078 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7079 const renderInputType = {};
7080
7081 /**
7082 * @param {HTMLInputElement} input
7083 * @param {SweetAlertOptions} params
7084 * @returns {HTMLInputElement}
7085 */
7086 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} */
7087 (input, params) => {
7088 checkAndSetInputValue(input, params.inputValue);
7089 setInputLabel(input, input, params);
7090 setInputPlaceholder(input, params);
7091 input.type = params.input;
7092 return input;
7093 };
7094
7095 /**
7096 * @param {HTMLInputElement} input
7097 * @param {SweetAlertOptions} params
7098 * @returns {HTMLInputElement}
7099 */
7100 renderInputType.file = (input, params) => {
7101 setInputLabel(input, input, params);
7102 setInputPlaceholder(input, params);
7103 return input;
7104 };
7105
7106 /**
7107 * @param {HTMLInputElement} range
7108 * @param {SweetAlertOptions} params
7109 * @returns {HTMLInputElement}
7110 */
7111 renderInputType.range = (range, params) => {
7112 const rangeInput = range.querySelector('input');
7113 const rangeOutput = range.querySelector('output');
7114 checkAndSetInputValue(rangeInput, params.inputValue);
7115 rangeInput.type = params.input;
7116 checkAndSetInputValue(rangeOutput, params.inputValue);
7117 setInputLabel(rangeInput, range, params);
7118 return range;
7119 };
7120
7121 /**
7122 * @param {HTMLSelectElement} select
7123 * @param {SweetAlertOptions} params
7124 * @returns {HTMLSelectElement}
7125 */
7126 renderInputType.select = (select, params) => {
7127 select.textContent = '';
7128 if (params.inputPlaceholder) {
7129 const placeholder = document.createElement('option');
7130 setInnerHtml(placeholder, params.inputPlaceholder);
7131 placeholder.value = '';
7132 placeholder.disabled = true;
7133 placeholder.selected = true;
7134 select.appendChild(placeholder);
7135 }
7136 setInputLabel(select, select, params);
7137 return select;
7138 };
7139
7140 /**
7141 * @param {HTMLInputElement} radio
7142 * @returns {HTMLInputElement}
7143 */
7144 renderInputType.radio = radio => {
7145 radio.textContent = '';
7146 return radio;
7147 };
7148
7149 /**
7150 * @param {HTMLLabelElement} checkboxContainer
7151 * @param {SweetAlertOptions} params
7152 * @returns {HTMLInputElement}
7153 */
7154 renderInputType.checkbox = (checkboxContainer, params) => {
7155 const checkbox = getInput$1(getPopup(), 'checkbox');
7156 checkbox.value = '1';
7157 checkbox.checked = Boolean(params.inputValue);
7158 const label = checkboxContainer.querySelector('span');
7159 setInnerHtml(label, params.inputPlaceholder || params.inputLabel);
7160 return checkbox;
7161 };
7162
7163 /**
7164 * @param {HTMLTextAreaElement} textarea
7165 * @param {SweetAlertOptions} params
7166 * @returns {HTMLTextAreaElement}
7167 */
7168 renderInputType.textarea = (textarea, params) => {
7169 checkAndSetInputValue(textarea, params.inputValue);
7170 setInputPlaceholder(textarea, params);
7171 setInputLabel(textarea, textarea, params);
7172
7173 /**
7174 * @param {HTMLElement} el
7175 * @returns {number}
7176 */
7177 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7178
7179 // https://github.com/sweetalert2/sweetalert2/issues/2291
7180 setTimeout(() => {
7181 // https://github.com/sweetalert2/sweetalert2/issues/1699
7182 if ('MutationObserver' in window) {
7183 const initialPopupWidth = parseInt(window.getComputedStyle(getPopup()).width);
7184 const textareaResizeHandler = () => {
7185 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7186 if (!document.body.contains(textarea)) {
7187 return;
7188 }
7189 const textareaWidth = textarea.offsetWidth + getMargin(textarea);
7190 if (textareaWidth > initialPopupWidth) {
7191 getPopup().style.width = `${textareaWidth}px`;
7192 } else {
7193 applyNumericalStyle(getPopup(), 'width', params.width);
7194 }
7195 };
7196 new MutationObserver(textareaResizeHandler).observe(textarea, {
7197 attributes: true,
7198 attributeFilter: ['style']
7199 });
7200 }
7201 });
7202 return textarea;
7203 };
7204
7205 /**
7206 * @param {SweetAlert} instance
7207 * @param {SweetAlertOptions} params
7208 */
7209 const renderContent = (instance, params) => {
7210 const htmlContainer = getHtmlContainer();
7211 if (!htmlContainer) {
7212 return;
7213 }
7214 showWhenInnerHtmlPresent(htmlContainer);
7215 applyCustomClass(htmlContainer, params, 'htmlContainer');
7216
7217 // Content as HTML
7218 if (params.html) {
7219 parseHtmlToContainer(params.html, htmlContainer);
7220 show(htmlContainer, 'block');
7221 }
7222
7223 // Content as plain text
7224 else if (params.text) {
7225 htmlContainer.textContent = params.text;
7226 show(htmlContainer, 'block');
7227 }
7228
7229 // No content
7230 else {
7231 hide(htmlContainer);
7232 }
7233 renderInput(instance, params);
7234 };
7235
7236 /**
7237 * @param {SweetAlert} instance
7238 * @param {SweetAlertOptions} params
7239 */
7240 const renderFooter = (instance, params) => {
7241 const footer = getFooter();
7242 if (!footer) {
7243 return;
7244 }
7245 showWhenInnerHtmlPresent(footer);
7246 toggle(footer, params.footer, 'block');
7247 if (params.footer) {
7248 parseHtmlToContainer(params.footer, footer);
7249 }
7250
7251 // Custom class
7252 applyCustomClass(footer, params, 'footer');
7253 };
7254
7255 /**
7256 * @param {SweetAlert} instance
7257 * @param {SweetAlertOptions} params
7258 */
7259 const renderIcon = (instance, params) => {
7260 const innerParams = privateProps.innerParams.get(instance);
7261 const icon = getIcon();
7262 if (!icon) {
7263 return;
7264 }
7265
7266 // if the given icon already rendered, apply the styling without re-rendering the icon
7267 if (innerParams && params.icon === innerParams.icon) {
7268 // Custom or default content
7269 setContent(icon, params);
7270 applyStyles(icon, params);
7271 return;
7272 }
7273 if (!params.icon && !params.iconHtml) {
7274 hide(icon);
7275 return;
7276 }
7277 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7278 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7279 hide(icon);
7280 return;
7281 }
7282 show(icon);
7283
7284 // Custom or default content
7285 setContent(icon, params);
7286 applyStyles(icon, params);
7287
7288 // Animate icon
7289 addClass(icon, params.showClass && params.showClass.icon);
7290
7291 // Re-adjust the success icon on system theme change
7292 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7293 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7294 };
7295
7296 /**
7297 * @param {HTMLElement} icon
7298 * @param {SweetAlertOptions} params
7299 */
7300 const applyStyles = (icon, params) => {
7301 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7302 if (params.icon !== iconType) {
7303 removeClass(icon, iconClassName);
7304 }
7305 }
7306 addClass(icon, params.icon && iconTypes[params.icon]);
7307
7308 // Icon color
7309 setColor(icon, params);
7310
7311 // Success icon background color
7312 adjustSuccessIconBackgroundColor();
7313
7314 // Custom class
7315 applyCustomClass(icon, params, 'icon');
7316 };
7317
7318 // Adjust success icon background color to match the popup background color
7319 const adjustSuccessIconBackgroundColor = () => {
7320 const popup = getPopup();
7321 if (!popup) {
7322 return;
7323 }
7324 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7325 /** @type {NodeListOf<HTMLElement>} */
7326 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7327 for (let i = 0; i < successIconParts.length; i++) {
7328 successIconParts[i].style.backgroundColor = popupBackgroundColor;
7329 }
7330 };
7331
7332 /**
7333 *
7334 * @param {SweetAlertOptions} params
7335 * @returns {string}
7336 */
7337 const successIconHtml = params => `
7338 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7339 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7340 <div class="swal2-success-ring"></div>
7341 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7342 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7343 `;
7344 const errorIconHtml = `
7345 <span class="swal2-x-mark">
7346 <span class="swal2-x-mark-line-left"></span>
7347 <span class="swal2-x-mark-line-right"></span>
7348 </span>
7349 `;
7350
7351 /**
7352 * @param {HTMLElement} icon
7353 * @param {SweetAlertOptions} params
7354 */
7355 const setContent = (icon, params) => {
7356 if (!params.icon && !params.iconHtml) {
7357 return;
7358 }
7359 let oldContent = icon.innerHTML;
7360 let newContent = '';
7361 if (params.iconHtml) {
7362 newContent = iconContent(params.iconHtml);
7363 } else if (params.icon === 'success') {
7364 newContent = successIconHtml(params);
7365 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7366 } else if (params.icon === 'error') {
7367 newContent = errorIconHtml;
7368 } else if (params.icon) {
7369 const defaultIconHtml = {
7370 question: '?',
7371 warning: '!',
7372 info: 'i'
7373 };
7374 newContent = iconContent(defaultIconHtml[params.icon]);
7375 }
7376 if (oldContent.trim() !== newContent.trim()) {
7377 setInnerHtml(icon, newContent);
7378 }
7379 };
7380
7381 /**
7382 * @param {HTMLElement} icon
7383 * @param {SweetAlertOptions} params
7384 */
7385 const setColor = (icon, params) => {
7386 if (!params.iconColor) {
7387 return;
7388 }
7389 icon.style.color = params.iconColor;
7390 icon.style.borderColor = params.iconColor;
7391 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7392 setStyle(icon, sel, 'background-color', params.iconColor);
7393 }
7394 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7395 };
7396
7397 /**
7398 * @param {string} content
7399 * @returns {string}
7400 */
7401 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7402
7403 /**
7404 * @param {SweetAlert} instance
7405 * @param {SweetAlertOptions} params
7406 */
7407 const renderImage = (instance, params) => {
7408 const image = getImage();
7409 if (!image) {
7410 return;
7411 }
7412 if (!params.imageUrl) {
7413 hide(image);
7414 return;
7415 }
7416 show(image, '');
7417
7418 // Src, alt
7419 image.setAttribute('src', params.imageUrl);
7420 image.setAttribute('alt', params.imageAlt || '');
7421
7422 // Width, height
7423 applyNumericalStyle(image, 'width', params.imageWidth);
7424 applyNumericalStyle(image, 'height', params.imageHeight);
7425
7426 // Class
7427 image.className = swalClasses.image;
7428 applyCustomClass(image, params, 'image');
7429 };
7430
7431 let dragging = false;
7432 let mousedownX = 0;
7433 let mousedownY = 0;
7434 let initialX = 0;
7435 let initialY = 0;
7436
7437 /**
7438 * @param {HTMLElement} popup
7439 */
7440 const addDraggableListeners = popup => {
7441 popup.addEventListener('mousedown', down);
7442 document.body.addEventListener('mousemove', move);
7443 popup.addEventListener('mouseup', up);
7444 popup.addEventListener('touchstart', down);
7445 document.body.addEventListener('touchmove', move);
7446 popup.addEventListener('touchend', up);
7447 };
7448
7449 /**
7450 * @param {HTMLElement} popup
7451 */
7452 const removeDraggableListeners = popup => {
7453 popup.removeEventListener('mousedown', down);
7454 document.body.removeEventListener('mousemove', move);
7455 popup.removeEventListener('mouseup', up);
7456 popup.removeEventListener('touchstart', down);
7457 document.body.removeEventListener('touchmove', move);
7458 popup.removeEventListener('touchend', up);
7459 };
7460
7461 /**
7462 * @param {MouseEvent | TouchEvent} event
7463 */
7464 const down = event => {
7465 const popup = getPopup();
7466 if (event.target === popup || getIcon().contains(/** @type {HTMLElement} */event.target)) {
7467 dragging = true;
7468 const clientXY = getClientXY(event);
7469 mousedownX = clientXY.clientX;
7470 mousedownY = clientXY.clientY;
7471 initialX = parseInt(popup.style.insetInlineStart) || 0;
7472 initialY = parseInt(popup.style.insetBlockStart) || 0;
7473 addClass(popup, 'swal2-dragging');
7474 }
7475 };
7476
7477 /**
7478 * @param {MouseEvent | TouchEvent} event
7479 */
7480 const move = event => {
7481 const popup = getPopup();
7482 if (dragging) {
7483 let {
7484 clientX,
7485 clientY
7486 } = getClientXY(event);
7487 popup.style.insetInlineStart = `${initialX + (clientX - mousedownX)}px`;
7488 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7489 }
7490 };
7491 const up = () => {
7492 const popup = getPopup();
7493 dragging = false;
7494 removeClass(popup, 'swal2-dragging');
7495 };
7496
7497 /**
7498 * @param {MouseEvent | TouchEvent} event
7499 * @returns {{ clientX: number, clientY: number }}
7500 */
7501 const getClientXY = event => {
7502 let clientX = 0,
7503 clientY = 0;
7504 if (event.type.startsWith('mouse')) {
7505 clientX = /** @type {MouseEvent} */event.clientX;
7506 clientY = /** @type {MouseEvent} */event.clientY;
7507 } else if (event.type.startsWith('touch')) {
7508 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
7509 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
7510 }
7511 return {
7512 clientX,
7513 clientY
7514 };
7515 };
7516
7517 /**
7518 * @param {SweetAlert} instance
7519 * @param {SweetAlertOptions} params
7520 */
7521 const renderPopup = (instance, params) => {
7522 const container = getContainer();
7523 const popup = getPopup();
7524 if (!container || !popup) {
7525 return;
7526 }
7527
7528 // Width
7529 // https://github.com/sweetalert2/sweetalert2/issues/2170
7530 if (params.toast) {
7531 applyNumericalStyle(container, 'width', params.width);
7532 popup.style.width = '100%';
7533 const loader = getLoader();
7534 if (loader) {
7535 popup.insertBefore(loader, getIcon());
7536 }
7537 } else {
7538 applyNumericalStyle(popup, 'width', params.width);
7539 }
7540
7541 // Padding
7542 applyNumericalStyle(popup, 'padding', params.padding);
7543
7544 // Color
7545 if (params.color) {
7546 popup.style.color = params.color;
7547 }
7548
7549 // Background
7550 if (params.background) {
7551 popup.style.background = params.background;
7552 }
7553 hide(getValidationMessage());
7554
7555 // Classes
7556 addClasses$1(popup, params);
7557 if (params.draggable && !params.toast) {
7558 addClass(popup, swalClasses.draggable);
7559 addDraggableListeners(popup);
7560 } else {
7561 removeClass(popup, swalClasses.draggable);
7562 removeDraggableListeners(popup);
7563 }
7564 };
7565
7566 /**
7567 * @param {HTMLElement} popup
7568 * @param {SweetAlertOptions} params
7569 */
7570 const addClasses$1 = (popup, params) => {
7571 const showClass = params.showClass || {};
7572 // Default Class + showClass when updating Swal.update({})
7573 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7574 if (params.toast) {
7575 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7576 addClass(popup, swalClasses.toast);
7577 } else {
7578 addClass(popup, swalClasses.modal);
7579 }
7580
7581 // Custom class
7582 applyCustomClass(popup, params, 'popup');
7583 // TODO: remove in the next major
7584 if (typeof params.customClass === 'string') {
7585 addClass(popup, params.customClass);
7586 }
7587
7588 // Icon class (#1842)
7589 if (params.icon) {
7590 addClass(popup, swalClasses[`icon-${params.icon}`]);
7591 }
7592 };
7593
7594 /**
7595 * @param {SweetAlert} instance
7596 * @param {SweetAlertOptions} params
7597 */
7598 const renderProgressSteps = (instance, params) => {
7599 const progressStepsContainer = getProgressSteps();
7600 if (!progressStepsContainer) {
7601 return;
7602 }
7603 const {
7604 progressSteps,
7605 currentProgressStep
7606 } = params;
7607 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
7608 hide(progressStepsContainer);
7609 return;
7610 }
7611 show(progressStepsContainer);
7612 progressStepsContainer.textContent = '';
7613 if (currentProgressStep >= progressSteps.length) {
7614 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
7615 }
7616 progressSteps.forEach((step, index) => {
7617 const stepEl = createStepElement(step);
7618 progressStepsContainer.appendChild(stepEl);
7619 if (index === currentProgressStep) {
7620 addClass(stepEl, swalClasses['active-progress-step']);
7621 }
7622 if (index !== progressSteps.length - 1) {
7623 const lineEl = createLineElement(params);
7624 progressStepsContainer.appendChild(lineEl);
7625 }
7626 });
7627 };
7628
7629 /**
7630 * @param {string} step
7631 * @returns {HTMLLIElement}
7632 */
7633 const createStepElement = step => {
7634 const stepEl = document.createElement('li');
7635 addClass(stepEl, swalClasses['progress-step']);
7636 setInnerHtml(stepEl, step);
7637 return stepEl;
7638 };
7639
7640 /**
7641 * @param {SweetAlertOptions} params
7642 * @returns {HTMLLIElement}
7643 */
7644 const createLineElement = params => {
7645 const lineEl = document.createElement('li');
7646 addClass(lineEl, swalClasses['progress-step-line']);
7647 if (params.progressStepsDistance) {
7648 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
7649 }
7650 return lineEl;
7651 };
7652
7653 /**
7654 * @param {SweetAlert} instance
7655 * @param {SweetAlertOptions} params
7656 */
7657 const renderTitle = (instance, params) => {
7658 const title = getTitle();
7659 if (!title) {
7660 return;
7661 }
7662 showWhenInnerHtmlPresent(title);
7663 toggle(title, params.title || params.titleText, 'block');
7664 if (params.title) {
7665 parseHtmlToContainer(params.title, title);
7666 }
7667 if (params.titleText) {
7668 title.innerText = params.titleText;
7669 }
7670
7671 // Custom class
7672 applyCustomClass(title, params, 'title');
7673 };
7674
7675 /**
7676 * @param {SweetAlert} instance
7677 * @param {SweetAlertOptions} params
7678 */
7679 const render = (instance, params) => {
7680 renderPopup(instance, params);
7681 renderContainer(instance, params);
7682 renderProgressSteps(instance, params);
7683 renderIcon(instance, params);
7684 renderImage(instance, params);
7685 renderTitle(instance, params);
7686 renderCloseButton(instance, params);
7687 renderContent(instance, params);
7688 renderActions(instance, params);
7689 renderFooter(instance, params);
7690 const popup = getPopup();
7691 if (typeof params.didRender === 'function' && popup) {
7692 params.didRender(popup);
7693 }
7694 globalState.eventEmitter.emit('didRender', popup);
7695 };
7696
7697 /*
7698 * Global function to determine if SweetAlert2 popup is shown
7699 */
7700 const isVisible = () => {
7701 return isVisible$1(getPopup());
7702 };
7703
7704 /*
7705 * Global function to click 'Confirm' button
7706 */
7707 const clickConfirm = () => {
7708 var _dom$getConfirmButton;
7709 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
7710 };
7711
7712 /*
7713 * Global function to click 'Deny' button
7714 */
7715 const clickDeny = () => {
7716 var _dom$getDenyButton;
7717 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
7718 };
7719
7720 /*
7721 * Global function to click 'Cancel' button
7722 */
7723 const clickCancel = () => {
7724 var _dom$getCancelButton;
7725 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
7726 };
7727
7728 /** @typedef {'cancel' | 'backdrop' | 'close' | 'esc' | 'timer'} DismissReason */
7729
7730 /** @type {Record<DismissReason, DismissReason>} */
7731 const DismissReason = Object.freeze({
7732 cancel: 'cancel',
7733 backdrop: 'backdrop',
7734 close: 'close',
7735 esc: 'esc',
7736 timer: 'timer'
7737 });
7738
7739 /**
7740 * @param {GlobalState} globalState
7741 */
7742 const removeKeydownHandler = globalState => {
7743 if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
7744 globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
7745 capture: globalState.keydownListenerCapture
7746 });
7747 globalState.keydownHandlerAdded = false;
7748 }
7749 };
7750
7751 /**
7752 * @param {GlobalState} globalState
7753 * @param {SweetAlertOptions} innerParams
7754 * @param {*} dismissWith
7755 */
7756 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
7757 removeKeydownHandler(globalState);
7758 if (!innerParams.toast) {
7759 globalState.keydownHandler = e => keydownHandler(innerParams, e, dismissWith);
7760 globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup();
7761 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
7762 globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, {
7763 capture: globalState.keydownListenerCapture
7764 });
7765 globalState.keydownHandlerAdded = true;
7766 }
7767 };
7768
7769 /**
7770 * @param {number} index
7771 * @param {number} increment
7772 */
7773 const setFocus = (index, increment) => {
7774 var _dom$getPopup;
7775 const focusableElements = getFocusableElements();
7776 // search for visible elements and select the next possible match
7777 if (focusableElements.length) {
7778 index = index + increment;
7779
7780 // shift + tab when .swal2-popup is focused
7781 if (index === -2) {
7782 index = focusableElements.length - 1;
7783 }
7784
7785 // rollover to first item
7786 if (index === focusableElements.length) {
7787 index = 0;
7788
7789 // go to last item
7790 } else if (index === -1) {
7791 index = focusableElements.length - 1;
7792 }
7793 focusableElements[index].focus();
7794 return;
7795 }
7796 // no visible focusable elements, focus the popup
7797 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
7798 };
7799 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
7800 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
7801
7802 /**
7803 * @param {SweetAlertOptions} innerParams
7804 * @param {KeyboardEvent} event
7805 * @param {Function} dismissWith
7806 */
7807 const keydownHandler = (innerParams, event, dismissWith) => {
7808 if (!innerParams) {
7809 return; // This instance has already been destroyed
7810 }
7811
7812 // Ignore keydown during IME composition
7813 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
7814 // https://github.com/sweetalert2/sweetalert2/issues/720
7815 // https://github.com/sweetalert2/sweetalert2/issues/2406
7816 if (event.isComposing || event.keyCode === 229) {
7817 return;
7818 }
7819 if (innerParams.stopKeydownPropagation) {
7820 event.stopPropagation();
7821 }
7822
7823 // ENTER
7824 if (event.key === 'Enter') {
7825 handleEnter(event, innerParams);
7826 }
7827
7828 // TAB
7829 else if (event.key === 'Tab') {
7830 handleTab(event);
7831 }
7832
7833 // ARROWS - switch focus between buttons
7834 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
7835 handleArrows(event.key);
7836 }
7837
7838 // ESC
7839 else if (event.key === 'Escape') {
7840 handleEsc(event, innerParams, dismissWith);
7841 }
7842 };
7843
7844 /**
7845 * @param {KeyboardEvent} event
7846 * @param {SweetAlertOptions} innerParams
7847 */
7848 const handleEnter = (event, innerParams) => {
7849 // https://github.com/sweetalert2/sweetalert2/issues/2386
7850 if (!callIfFunction(innerParams.allowEnterKey)) {
7851 return;
7852 }
7853 const input = getInput$1(getPopup(), innerParams.input);
7854 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
7855 if (['textarea', 'file'].includes(innerParams.input)) {
7856 return; // do not submit
7857 }
7858 clickConfirm();
7859 event.preventDefault();
7860 }
7861 };
7862
7863 /**
7864 * @param {KeyboardEvent} event
7865 */
7866 const handleTab = event => {
7867 const targetElement = event.target;
7868 const focusableElements = getFocusableElements();
7869 let btnIndex = -1;
7870 for (let i = 0; i < focusableElements.length; i++) {
7871 if (targetElement === focusableElements[i]) {
7872 btnIndex = i;
7873 break;
7874 }
7875 }
7876
7877 // Cycle to the next button
7878 if (!event.shiftKey) {
7879 setFocus(btnIndex, 1);
7880 }
7881
7882 // Cycle to the prev button
7883 else {
7884 setFocus(btnIndex, -1);
7885 }
7886 event.stopPropagation();
7887 event.preventDefault();
7888 };
7889
7890 /**
7891 * @param {string} key
7892 */
7893 const handleArrows = key => {
7894 const actions = getActions();
7895 const confirmButton = getConfirmButton();
7896 const denyButton = getDenyButton();
7897 const cancelButton = getCancelButton();
7898 if (!actions || !confirmButton || !denyButton || !cancelButton) {
7899 return;
7900 }
7901 /** @type HTMLElement[] */
7902 const buttons = [confirmButton, denyButton, cancelButton];
7903 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
7904 return;
7905 }
7906 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
7907 let buttonToFocus = document.activeElement;
7908 if (!buttonToFocus) {
7909 return;
7910 }
7911 for (let i = 0; i < actions.children.length; i++) {
7912 buttonToFocus = buttonToFocus[sibling];
7913 if (!buttonToFocus) {
7914 return;
7915 }
7916 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
7917 break;
7918 }
7919 }
7920 if (buttonToFocus instanceof HTMLButtonElement) {
7921 buttonToFocus.focus();
7922 }
7923 };
7924
7925 /**
7926 * @param {KeyboardEvent} event
7927 * @param {SweetAlertOptions} innerParams
7928 * @param {Function} dismissWith
7929 */
7930 const handleEsc = (event, innerParams, dismissWith) => {
7931 event.preventDefault();
7932 if (callIfFunction(innerParams.allowEscapeKey)) {
7933 dismissWith(DismissReason.esc);
7934 }
7935 };
7936
7937 /**
7938 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7939 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7940 * This is the approach that Babel will probably take to implement private methods/fields
7941 * https://github.com/tc39/proposal-private-methods
7942 * https://github.com/babel/babel/pull/7555
7943 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7944 * then we can use that language feature.
7945 */
7946
7947 var privateMethods = {
7948 swalPromiseResolve: new WeakMap(),
7949 swalPromiseReject: new WeakMap()
7950 };
7951
7952 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
7953 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
7954 // elements not within the active modal dialog will not be surfaced if a user opens a screen
7955 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
7956
7957 const setAriaHidden = () => {
7958 const container = getContainer();
7959 const bodyChildren = Array.from(document.body.children);
7960 bodyChildren.forEach(el => {
7961 if (el.contains(container)) {
7962 return;
7963 }
7964 if (el.hasAttribute('aria-hidden')) {
7965 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
7966 }
7967 el.setAttribute('aria-hidden', 'true');
7968 });
7969 };
7970 const unsetAriaHidden = () => {
7971 const bodyChildren = Array.from(document.body.children);
7972 bodyChildren.forEach(el => {
7973 if (el.hasAttribute('data-previous-aria-hidden')) {
7974 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
7975 el.removeAttribute('data-previous-aria-hidden');
7976 } else {
7977 el.removeAttribute('aria-hidden');
7978 }
7979 });
7980 };
7981
7982 // @ts-ignore
7983 const isSafariOrIOS = typeof window !== 'undefined' && !!window.GestureEvent; // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
7984
7985 /**
7986 * Fix iOS scrolling
7987 * http://stackoverflow.com/q/39626302
7988 */
7989 const iOSfix = () => {
7990 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
7991 const offset = document.body.scrollTop;
7992 document.body.style.top = `${offset * -1}px`;
7993 addClass(document.body, swalClasses.iosfix);
7994 lockBodyScroll();
7995 }
7996 };
7997
7998 /**
7999 * https://github.com/sweetalert2/sweetalert2/issues/1246
8000 */
8001 const lockBodyScroll = () => {
8002 const container = getContainer();
8003 if (!container) {
8004 return;
8005 }
8006 /** @type {boolean} */
8007 let preventTouchMove;
8008 /**
8009 * @param {TouchEvent} event
8010 */
8011 container.ontouchstart = event => {
8012 preventTouchMove = shouldPreventTouchMove(event);
8013 };
8014 /**
8015 * @param {TouchEvent} event
8016 */
8017 container.ontouchmove = event => {
8018 if (preventTouchMove) {
8019 event.preventDefault();
8020 event.stopPropagation();
8021 }
8022 };
8023 };
8024
8025 /**
8026 * @param {TouchEvent} event
8027 * @returns {boolean}
8028 */
8029 const shouldPreventTouchMove = event => {
8030 const target = event.target;
8031 const container = getContainer();
8032 const htmlContainer = getHtmlContainer();
8033 if (!container || !htmlContainer) {
8034 return false;
8035 }
8036 if (isStylus(event) || isZoom(event)) {
8037 return false;
8038 }
8039 if (target === container) {
8040 return true;
8041 }
8042 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8043 // #2823
8044 target.tagName !== 'INPUT' &&
8045 // #1603
8046 target.tagName !== 'TEXTAREA' &&
8047 // #2266
8048 !(isScrollable(htmlContainer) &&
8049 // #1944
8050 htmlContainer.contains(target))) {
8051 return true;
8052 }
8053 return false;
8054 };
8055
8056 /**
8057 * https://github.com/sweetalert2/sweetalert2/issues/1786
8058 *
8059 * @param {*} event
8060 * @returns {boolean}
8061 */
8062 const isStylus = event => {
8063 return event.touches && event.touches.length && event.touches[0].touchType === 'stylus';
8064 };
8065
8066 /**
8067 * https://github.com/sweetalert2/sweetalert2/issues/1891
8068 *
8069 * @param {TouchEvent} event
8070 * @returns {boolean}
8071 */
8072 const isZoom = event => {
8073 return event.touches && event.touches.length > 1;
8074 };
8075 const undoIOSfix = () => {
8076 if (hasClass(document.body, swalClasses.iosfix)) {
8077 const offset = parseInt(document.body.style.top, 10);
8078 removeClass(document.body, swalClasses.iosfix);
8079 document.body.style.top = '';
8080 document.body.scrollTop = offset * -1;
8081 }
8082 };
8083
8084 /**
8085 * Measure scrollbar width for padding body during modal show/hide
8086 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8087 *
8088 * @returns {number}
8089 */
8090 const measureScrollbar = () => {
8091 const scrollDiv = document.createElement('div');
8092 scrollDiv.className = swalClasses['scrollbar-measure'];
8093 document.body.appendChild(scrollDiv);
8094 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8095 document.body.removeChild(scrollDiv);
8096 return scrollbarWidth;
8097 };
8098
8099 /**
8100 * Remember state in cases where opening and handling a modal will fiddle with it.
8101 * @type {number | null}
8102 */
8103 let previousBodyPadding = null;
8104
8105 /**
8106 * @param {string} initialBodyOverflow
8107 */
8108 const replaceScrollbarWithPadding = initialBodyOverflow => {
8109 // for queues, do not do this more than once
8110 if (previousBodyPadding !== null) {
8111 return;
8112 }
8113 // if the body has overflow
8114 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8115 ) {
8116 // add padding so the content doesn't shift after removal of scrollbar
8117 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8118 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8119 }
8120 };
8121 const undoReplaceScrollbarWithPadding = () => {
8122 if (previousBodyPadding !== null) {
8123 document.body.style.paddingRight = `${previousBodyPadding}px`;
8124 previousBodyPadding = null;
8125 }
8126 };
8127
8128 /**
8129 * @param {SweetAlert} instance
8130 * @param {HTMLElement} container
8131 * @param {boolean} returnFocus
8132 * @param {Function} didClose
8133 */
8134 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8135 if (isToast()) {
8136 triggerDidCloseAndDispose(instance, didClose);
8137 } else {
8138 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8139 removeKeydownHandler(globalState);
8140 }
8141
8142 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8143 // for some reason removing the container in Safari will scroll the document to bottom
8144 if (isSafariOrIOS) {
8145 container.setAttribute('style', 'display:none !important');
8146 container.removeAttribute('class');
8147 container.innerHTML = '';
8148 } else {
8149 container.remove();
8150 }
8151 if (isModal()) {
8152 undoReplaceScrollbarWithPadding();
8153 undoIOSfix();
8154 unsetAriaHidden();
8155 }
8156 removeBodyClasses();
8157 }
8158
8159 /**
8160 * Remove SweetAlert2 classes from body
8161 */
8162 function removeBodyClasses() {
8163 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8164 }
8165
8166 /**
8167 * Instance method to close sweetAlert
8168 *
8169 * @param {any} resolveValue
8170 */
8171 function close(resolveValue) {
8172 resolveValue = prepareResolveValue(resolveValue);
8173 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8174 const didClose = triggerClosePopup(this);
8175 if (this.isAwaitingPromise) {
8176 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8177 if (!resolveValue.isDismissed) {
8178 handleAwaitingPromise(this);
8179 swalPromiseResolve(resolveValue);
8180 }
8181 } else if (didClose) {
8182 // Resolve Swal promise
8183 swalPromiseResolve(resolveValue);
8184 }
8185 }
8186 const triggerClosePopup = instance => {
8187 const popup = getPopup();
8188 if (!popup) {
8189 return false;
8190 }
8191 const innerParams = privateProps.innerParams.get(instance);
8192 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8193 return false;
8194 }
8195 removeClass(popup, innerParams.showClass.popup);
8196 addClass(popup, innerParams.hideClass.popup);
8197 const backdrop = getContainer();
8198 removeClass(backdrop, innerParams.showClass.backdrop);
8199 addClass(backdrop, innerParams.hideClass.backdrop);
8200 handlePopupAnimation(instance, popup, innerParams);
8201 return true;
8202 };
8203
8204 /**
8205 * @param {any} error
8206 */
8207 function rejectPromise(error) {
8208 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8209 handleAwaitingPromise(this);
8210 if (rejectPromise) {
8211 // Reject Swal promise
8212 rejectPromise(error);
8213 }
8214 }
8215
8216 /**
8217 * @param {SweetAlert} instance
8218 */
8219 const handleAwaitingPromise = instance => {
8220 if (instance.isAwaitingPromise) {
8221 delete instance.isAwaitingPromise;
8222 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8223 if (!privateProps.innerParams.get(instance)) {
8224 instance._destroy();
8225 }
8226 }
8227 };
8228
8229 /**
8230 * @param {any} resolveValue
8231 * @returns {SweetAlertResult}
8232 */
8233 const prepareResolveValue = resolveValue => {
8234 // When user calls Swal.close()
8235 if (typeof resolveValue === 'undefined') {
8236 return {
8237 isConfirmed: false,
8238 isDenied: false,
8239 isDismissed: true
8240 };
8241 }
8242 return Object.assign({
8243 isConfirmed: false,
8244 isDenied: false,
8245 isDismissed: false
8246 }, resolveValue);
8247 };
8248
8249 /**
8250 * @param {SweetAlert} instance
8251 * @param {HTMLElement} popup
8252 * @param {SweetAlertOptions} innerParams
8253 */
8254 const handlePopupAnimation = (instance, popup, innerParams) => {
8255 var _globalState$eventEmi;
8256 const container = getContainer();
8257 // If animation is supported, animate
8258 const animationIsSupported = hasCssAnimation(popup);
8259 if (typeof innerParams.willClose === 'function') {
8260 innerParams.willClose(popup);
8261 }
8262 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8263 if (animationIsSupported) {
8264 animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
8265 } else {
8266 // Otherwise, remove immediately
8267 removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
8268 }
8269 };
8270
8271 /**
8272 * @param {SweetAlert} instance
8273 * @param {HTMLElement} popup
8274 * @param {HTMLElement} container
8275 * @param {boolean} returnFocus
8276 * @param {Function} didClose
8277 */
8278 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8279 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8280 /**
8281 * @param {AnimationEvent | TransitionEvent} e
8282 */
8283 const swalCloseAnimationFinished = function (e) {
8284 if (e.target === popup) {
8285 var _globalState$swalClos;
8286 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8287 delete globalState.swalCloseEventFinishedCallback;
8288 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8289 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8290 }
8291 };
8292 popup.addEventListener('animationend', swalCloseAnimationFinished);
8293 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8294 };
8295
8296 /**
8297 * @param {SweetAlert} instance
8298 * @param {Function} didClose
8299 */
8300 const triggerDidCloseAndDispose = (instance, didClose) => {
8301 setTimeout(() => {
8302 var _globalState$eventEmi2;
8303 if (typeof didClose === 'function') {
8304 didClose.bind(instance.params)();
8305 }
8306 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8307 // instance might have been destroyed already
8308 if (instance._destroy) {
8309 instance._destroy();
8310 }
8311 });
8312 };
8313
8314 /**
8315 * Shows loader (spinner), this is useful with AJAX requests.
8316 * By default the loader be shown instead of the "Confirm" button.
8317 *
8318 * @param {HTMLButtonElement | null} [buttonToReplace]
8319 */
8320 const showLoading = buttonToReplace => {
8321 let popup = getPopup();
8322 if (!popup) {
8323 new Swal();
8324 }
8325 popup = getPopup();
8326 if (!popup) {
8327 return;
8328 }
8329 const loader = getLoader();
8330 if (isToast()) {
8331 hide(getIcon());
8332 } else {
8333 replaceButton(popup, buttonToReplace);
8334 }
8335 show(loader);
8336 popup.setAttribute('data-loading', 'true');
8337 popup.setAttribute('aria-busy', 'true');
8338 popup.focus();
8339 };
8340
8341 /**
8342 * @param {HTMLElement} popup
8343 * @param {HTMLButtonElement | null} [buttonToReplace]
8344 */
8345 const replaceButton = (popup, buttonToReplace) => {
8346 const actions = getActions();
8347 const loader = getLoader();
8348 if (!actions || !loader) {
8349 return;
8350 }
8351 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8352 buttonToReplace = getConfirmButton();
8353 }
8354 show(actions);
8355 if (buttonToReplace) {
8356 hide(buttonToReplace);
8357 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8358 actions.insertBefore(loader, buttonToReplace);
8359 }
8360 addClass([popup, actions], swalClasses.loading);
8361 };
8362
8363 /**
8364 * @param {SweetAlert} instance
8365 * @param {SweetAlertOptions} params
8366 */
8367 const handleInputOptionsAndValue = (instance, params) => {
8368 if (params.input === 'select' || params.input === 'radio') {
8369 handleInputOptions(instance, params);
8370 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8371 showLoading(getConfirmButton());
8372 handleInputValue(instance, params);
8373 }
8374 };
8375
8376 /**
8377 * @param {SweetAlert} instance
8378 * @param {SweetAlertOptions} innerParams
8379 * @returns {SweetAlertInputValue}
8380 */
8381 const getInputValue = (instance, innerParams) => {
8382 const input = instance.getInput();
8383 if (!input) {
8384 return null;
8385 }
8386 switch (innerParams.input) {
8387 case 'checkbox':
8388 return getCheckboxValue(input);
8389 case 'radio':
8390 return getRadioValue(input);
8391 case 'file':
8392 return getFileValue(input);
8393 default:
8394 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8395 }
8396 };
8397
8398 /**
8399 * @param {HTMLInputElement} input
8400 * @returns {number}
8401 */
8402 const getCheckboxValue = input => input.checked ? 1 : 0;
8403
8404 /**
8405 * @param {HTMLInputElement} input
8406 * @returns {string | null}
8407 */
8408 const getRadioValue = input => input.checked ? input.value : null;
8409
8410 /**
8411 * @param {HTMLInputElement} input
8412 * @returns {FileList | File | null}
8413 */
8414 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8415
8416 /**
8417 * @param {SweetAlert} instance
8418 * @param {SweetAlertOptions} params
8419 */
8420 const handleInputOptions = (instance, params) => {
8421 const popup = getPopup();
8422 if (!popup) {
8423 return;
8424 }
8425 /**
8426 * @param {Record<string, any>} inputOptions
8427 */
8428 const processInputOptions = inputOptions => {
8429 if (params.input === 'select') {
8430 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8431 } else if (params.input === 'radio') {
8432 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8433 }
8434 };
8435 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8436 showLoading(getConfirmButton());
8437 asPromise(params.inputOptions).then(inputOptions => {
8438 instance.hideLoading();
8439 processInputOptions(inputOptions);
8440 });
8441 } else if (typeof params.inputOptions === 'object') {
8442 processInputOptions(params.inputOptions);
8443 } else {
8444 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8445 }
8446 };
8447
8448 /**
8449 * @param {SweetAlert} instance
8450 * @param {SweetAlertOptions} params
8451 */
8452 const handleInputValue = (instance, params) => {
8453 const input = instance.getInput();
8454 if (!input) {
8455 return;
8456 }
8457 hide(input);
8458 asPromise(params.inputValue).then(inputValue => {
8459 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8460 show(input);
8461 input.focus();
8462 instance.hideLoading();
8463 }).catch(err => {
8464 error(`Error in inputValue promise: ${err}`);
8465 input.value = '';
8466 show(input);
8467 input.focus();
8468 instance.hideLoading();
8469 });
8470 };
8471
8472 /**
8473 * @param {HTMLElement} popup
8474 * @param {InputOptionFlattened[]} inputOptions
8475 * @param {SweetAlertOptions} params
8476 */
8477 function populateSelectOptions(popup, inputOptions, params) {
8478 const select = getDirectChildByClass(popup, swalClasses.select);
8479 if (!select) {
8480 return;
8481 }
8482 /**
8483 * @param {HTMLElement} parent
8484 * @param {string} optionLabel
8485 * @param {string} optionValue
8486 */
8487 const renderOption = (parent, optionLabel, optionValue) => {
8488 const option = document.createElement('option');
8489 option.value = optionValue;
8490 setInnerHtml(option, optionLabel);
8491 option.selected = isSelected(optionValue, params.inputValue);
8492 parent.appendChild(option);
8493 };
8494 inputOptions.forEach(inputOption => {
8495 const optionValue = inputOption[0];
8496 const optionLabel = inputOption[1];
8497 // <optgroup> spec:
8498 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8499 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8500 // check whether this is a <optgroup>
8501 if (Array.isArray(optionLabel)) {
8502 // if it is an array, then it is an <optgroup>
8503 const optgroup = document.createElement('optgroup');
8504 optgroup.label = optionValue;
8505 optgroup.disabled = false; // not configurable for now
8506 select.appendChild(optgroup);
8507 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8508 } else {
8509 // case of <option>
8510 renderOption(select, optionLabel, optionValue);
8511 }
8512 });
8513 select.focus();
8514 }
8515
8516 /**
8517 * @param {HTMLElement} popup
8518 * @param {InputOptionFlattened[]} inputOptions
8519 * @param {SweetAlertOptions} params
8520 */
8521 function populateRadioOptions(popup, inputOptions, params) {
8522 const radio = getDirectChildByClass(popup, swalClasses.radio);
8523 if (!radio) {
8524 return;
8525 }
8526 inputOptions.forEach(inputOption => {
8527 const radioValue = inputOption[0];
8528 const radioLabel = inputOption[1];
8529 const radioInput = document.createElement('input');
8530 const radioLabelElement = document.createElement('label');
8531 radioInput.type = 'radio';
8532 radioInput.name = swalClasses.radio;
8533 radioInput.value = radioValue;
8534 if (isSelected(radioValue, params.inputValue)) {
8535 radioInput.checked = true;
8536 }
8537 const label = document.createElement('span');
8538 setInnerHtml(label, radioLabel);
8539 label.className = swalClasses.label;
8540 radioLabelElement.appendChild(radioInput);
8541 radioLabelElement.appendChild(label);
8542 radio.appendChild(radioLabelElement);
8543 });
8544 const radios = radio.querySelectorAll('input');
8545 if (radios.length) {
8546 radios[0].focus();
8547 }
8548 }
8549
8550 /**
8551 * Converts `inputOptions` into an array of `[value, label]`s
8552 *
8553 * @param {Record<string, any>} inputOptions
8554 * @typedef {string[]} InputOptionFlattened
8555 * @returns {InputOptionFlattened[]}
8556 */
8557 const formatInputOptions = inputOptions => {
8558 /** @type {InputOptionFlattened[]} */
8559 const result = [];
8560 if (inputOptions instanceof Map) {
8561 inputOptions.forEach((value, key) => {
8562 let valueFormatted = value;
8563 if (typeof valueFormatted === 'object') {
8564 // case of <optgroup>
8565 valueFormatted = formatInputOptions(valueFormatted);
8566 }
8567 result.push([key, valueFormatted]);
8568 });
8569 } else {
8570 Object.keys(inputOptions).forEach(key => {
8571 let valueFormatted = inputOptions[key];
8572 if (typeof valueFormatted === 'object') {
8573 // case of <optgroup>
8574 valueFormatted = formatInputOptions(valueFormatted);
8575 }
8576 result.push([key, valueFormatted]);
8577 });
8578 }
8579 return result;
8580 };
8581
8582 /**
8583 * @param {string} optionValue
8584 * @param {SweetAlertInputValue} inputValue
8585 * @returns {boolean}
8586 */
8587 const isSelected = (optionValue, inputValue) => {
8588 return !!inputValue && inputValue.toString() === optionValue.toString();
8589 };
8590
8591 /**
8592 * @param {SweetAlert} instance
8593 */
8594 const handleConfirmButtonClick = instance => {
8595 const innerParams = privateProps.innerParams.get(instance);
8596 instance.disableButtons();
8597 if (innerParams.input) {
8598 handleConfirmOrDenyWithInput(instance, 'confirm');
8599 } else {
8600 confirm(instance, true);
8601 }
8602 };
8603
8604 /**
8605 * @param {SweetAlert} instance
8606 */
8607 const handleDenyButtonClick = instance => {
8608 const innerParams = privateProps.innerParams.get(instance);
8609 instance.disableButtons();
8610 if (innerParams.returnInputValueOnDeny) {
8611 handleConfirmOrDenyWithInput(instance, 'deny');
8612 } else {
8613 deny(instance, false);
8614 }
8615 };
8616
8617 /**
8618 * @param {SweetAlert} instance
8619 * @param {Function} dismissWith
8620 */
8621 const handleCancelButtonClick = (instance, dismissWith) => {
8622 instance.disableButtons();
8623 dismissWith(DismissReason.cancel);
8624 };
8625
8626 /**
8627 * @param {SweetAlert} instance
8628 * @param {'confirm' | 'deny'} type
8629 */
8630 const handleConfirmOrDenyWithInput = (instance, type) => {
8631 const innerParams = privateProps.innerParams.get(instance);
8632 if (!innerParams.input) {
8633 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
8634 return;
8635 }
8636 const input = instance.getInput();
8637 const inputValue = getInputValue(instance, innerParams);
8638 if (innerParams.inputValidator) {
8639 handleInputValidator(instance, inputValue, type);
8640 } else if (input && !input.checkValidity()) {
8641 instance.enableButtons();
8642 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
8643 } else if (type === 'deny') {
8644 deny(instance, inputValue);
8645 } else {
8646 confirm(instance, inputValue);
8647 }
8648 };
8649
8650 /**
8651 * @param {SweetAlert} instance
8652 * @param {SweetAlertInputValue} inputValue
8653 * @param {'confirm' | 'deny'} type
8654 */
8655 const handleInputValidator = (instance, inputValue, type) => {
8656 const innerParams = privateProps.innerParams.get(instance);
8657 instance.disableInput();
8658 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
8659 validationPromise.then(validationMessage => {
8660 instance.enableButtons();
8661 instance.enableInput();
8662 if (validationMessage) {
8663 instance.showValidationMessage(validationMessage);
8664 } else if (type === 'deny') {
8665 deny(instance, inputValue);
8666 } else {
8667 confirm(instance, inputValue);
8668 }
8669 });
8670 };
8671
8672 /**
8673 * @param {SweetAlert} instance
8674 * @param {any} value
8675 */
8676 const deny = (instance, value) => {
8677 const innerParams = privateProps.innerParams.get(instance || undefined);
8678 if (innerParams.showLoaderOnDeny) {
8679 showLoading(getDenyButton());
8680 }
8681 if (innerParams.preDeny) {
8682 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
8683 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
8684 preDenyPromise.then(preDenyValue => {
8685 if (preDenyValue === false) {
8686 instance.hideLoading();
8687 handleAwaitingPromise(instance);
8688 } else {
8689 instance.close({
8690 isDenied: true,
8691 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
8692 });
8693 }
8694 }).catch(error => rejectWith(instance || undefined, error));
8695 } else {
8696 instance.close({
8697 isDenied: true,
8698 value
8699 });
8700 }
8701 };
8702
8703 /**
8704 * @param {SweetAlert} instance
8705 * @param {any} value
8706 */
8707 const succeedWith = (instance, value) => {
8708 instance.close({
8709 isConfirmed: true,
8710 value
8711 });
8712 };
8713
8714 /**
8715 *
8716 * @param {SweetAlert} instance
8717 * @param {string} error
8718 */
8719 const rejectWith = (instance, error) => {
8720 instance.rejectPromise(error);
8721 };
8722
8723 /**
8724 *
8725 * @param {SweetAlert} instance
8726 * @param {any} value
8727 */
8728 const confirm = (instance, value) => {
8729 const innerParams = privateProps.innerParams.get(instance || undefined);
8730 if (innerParams.showLoaderOnConfirm) {
8731 showLoading();
8732 }
8733 if (innerParams.preConfirm) {
8734 instance.resetValidationMessage();
8735 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
8736 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
8737 preConfirmPromise.then(preConfirmValue => {
8738 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
8739 instance.hideLoading();
8740 handleAwaitingPromise(instance);
8741 } else {
8742 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
8743 }
8744 }).catch(error => rejectWith(instance || undefined, error));
8745 } else {
8746 succeedWith(instance, value);
8747 }
8748 };
8749
8750 /**
8751 * Hides loader and shows back the button which was hidden by .showLoading()
8752 */
8753 function hideLoading() {
8754 // do nothing if popup is closed
8755 const innerParams = privateProps.innerParams.get(this);
8756 if (!innerParams) {
8757 return;
8758 }
8759 const domCache = privateProps.domCache.get(this);
8760 hide(domCache.loader);
8761 if (isToast()) {
8762 if (innerParams.icon) {
8763 show(getIcon());
8764 }
8765 } else {
8766 showRelatedButton(domCache);
8767 }
8768 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
8769 domCache.popup.removeAttribute('aria-busy');
8770 domCache.popup.removeAttribute('data-loading');
8771 domCache.confirmButton.disabled = false;
8772 domCache.denyButton.disabled = false;
8773 domCache.cancelButton.disabled = false;
8774 }
8775 const showRelatedButton = domCache => {
8776 const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
8777 if (buttonToReplace.length) {
8778 show(buttonToReplace[0], 'inline-block');
8779 } else if (allButtonsAreHidden()) {
8780 hide(domCache.actions);
8781 }
8782 };
8783
8784 /**
8785 * Gets the input DOM node, this method works with input parameter.
8786 *
8787 * @returns {HTMLInputElement | null}
8788 */
8789 function getInput() {
8790 const innerParams = privateProps.innerParams.get(this);
8791 const domCache = privateProps.domCache.get(this);
8792 if (!domCache) {
8793 return null;
8794 }
8795 return getInput$1(domCache.popup, innerParams.input);
8796 }
8797
8798 /**
8799 * @param {SweetAlert} instance
8800 * @param {string[]} buttons
8801 * @param {boolean} disabled
8802 */
8803 function setButtonsDisabled(instance, buttons, disabled) {
8804 const domCache = privateProps.domCache.get(instance);
8805 buttons.forEach(button => {
8806 domCache[button].disabled = disabled;
8807 });
8808 }
8809
8810 /**
8811 * @param {HTMLInputElement | null} input
8812 * @param {boolean} disabled
8813 */
8814 function setInputDisabled(input, disabled) {
8815 const popup = getPopup();
8816 if (!popup || !input) {
8817 return;
8818 }
8819 if (input.type === 'radio') {
8820 /** @type {NodeListOf<HTMLInputElement>} */
8821 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
8822 for (let i = 0; i < radios.length; i++) {
8823 radios[i].disabled = disabled;
8824 }
8825 } else {
8826 input.disabled = disabled;
8827 }
8828 }
8829
8830 /**
8831 * Enable all the buttons
8832 * @this {SweetAlert}
8833 */
8834 function enableButtons() {
8835 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
8836 }
8837
8838 /**
8839 * Disable all the buttons
8840 * @this {SweetAlert}
8841 */
8842 function disableButtons() {
8843 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
8844 }
8845
8846 /**
8847 * Enable the input field
8848 * @this {SweetAlert}
8849 */
8850 function enableInput() {
8851 setInputDisabled(this.getInput(), false);
8852 }
8853
8854 /**
8855 * Disable the input field
8856 * @this {SweetAlert}
8857 */
8858 function disableInput() {
8859 setInputDisabled(this.getInput(), true);
8860 }
8861
8862 /**
8863 * Show block with validation message
8864 *
8865 * @param {string} error
8866 * @this {SweetAlert}
8867 */
8868 function showValidationMessage(error) {
8869 const domCache = privateProps.domCache.get(this);
8870 const params = privateProps.innerParams.get(this);
8871 setInnerHtml(domCache.validationMessage, error);
8872 domCache.validationMessage.className = swalClasses['validation-message'];
8873 if (params.customClass && params.customClass.validationMessage) {
8874 addClass(domCache.validationMessage, params.customClass.validationMessage);
8875 }
8876 show(domCache.validationMessage);
8877 const input = this.getInput();
8878 if (input) {
8879 input.setAttribute('aria-invalid', 'true');
8880 input.setAttribute('aria-describedby', swalClasses['validation-message']);
8881 focusInput(input);
8882 addClass(input, swalClasses.inputerror);
8883 }
8884 }
8885
8886 /**
8887 * Hide block with validation message
8888 *
8889 * @this {SweetAlert}
8890 */
8891 function resetValidationMessage() {
8892 const domCache = privateProps.domCache.get(this);
8893 if (domCache.validationMessage) {
8894 hide(domCache.validationMessage);
8895 }
8896 const input = this.getInput();
8897 if (input) {
8898 input.removeAttribute('aria-invalid');
8899 input.removeAttribute('aria-describedby');
8900 removeClass(input, swalClasses.inputerror);
8901 }
8902 }
8903
8904 const defaultParams = {
8905 title: '',
8906 titleText: '',
8907 text: '',
8908 html: '',
8909 footer: '',
8910 icon: undefined,
8911 iconColor: undefined,
8912 iconHtml: undefined,
8913 template: undefined,
8914 toast: false,
8915 draggable: false,
8916 animation: true,
8917 theme: 'light',
8918 showClass: {
8919 popup: 'swal2-show',
8920 backdrop: 'swal2-backdrop-show',
8921 icon: 'swal2-icon-show'
8922 },
8923 hideClass: {
8924 popup: 'swal2-hide',
8925 backdrop: 'swal2-backdrop-hide',
8926 icon: 'swal2-icon-hide'
8927 },
8928 customClass: {},
8929 target: 'body',
8930 color: undefined,
8931 backdrop: true,
8932 heightAuto: true,
8933 allowOutsideClick: true,
8934 allowEscapeKey: true,
8935 allowEnterKey: true,
8936 stopKeydownPropagation: true,
8937 keydownListenerCapture: false,
8938 showConfirmButton: true,
8939 showDenyButton: false,
8940 showCancelButton: false,
8941 preConfirm: undefined,
8942 preDeny: undefined,
8943 confirmButtonText: 'OK',
8944 confirmButtonAriaLabel: '',
8945 confirmButtonColor: undefined,
8946 denyButtonText: 'No',
8947 denyButtonAriaLabel: '',
8948 denyButtonColor: undefined,
8949 cancelButtonText: 'Cancel',
8950 cancelButtonAriaLabel: '',
8951 cancelButtonColor: undefined,
8952 buttonsStyling: true,
8953 reverseButtons: false,
8954 focusConfirm: true,
8955 focusDeny: false,
8956 focusCancel: false,
8957 returnFocus: true,
8958 showCloseButton: false,
8959 closeButtonHtml: '&times;',
8960 closeButtonAriaLabel: 'Close this dialog',
8961 loaderHtml: '',
8962 showLoaderOnConfirm: false,
8963 showLoaderOnDeny: false,
8964 imageUrl: undefined,
8965 imageWidth: undefined,
8966 imageHeight: undefined,
8967 imageAlt: '',
8968 timer: undefined,
8969 timerProgressBar: false,
8970 width: undefined,
8971 padding: undefined,
8972 background: undefined,
8973 input: undefined,
8974 inputPlaceholder: '',
8975 inputLabel: '',
8976 inputValue: '',
8977 inputOptions: {},
8978 inputAutoFocus: true,
8979 inputAutoTrim: true,
8980 inputAttributes: {},
8981 inputValidator: undefined,
8982 returnInputValueOnDeny: false,
8983 validationMessage: undefined,
8984 grow: false,
8985 position: 'center',
8986 progressSteps: [],
8987 currentProgressStep: undefined,
8988 progressStepsDistance: undefined,
8989 willOpen: undefined,
8990 didOpen: undefined,
8991 didRender: undefined,
8992 willClose: undefined,
8993 didClose: undefined,
8994 didDestroy: undefined,
8995 scrollbarPadding: true,
8996 topLayer: false
8997 };
8998 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'];
8999
9000 /** @type {Record<string, string | undefined>} */
9001 const deprecatedParams = {
9002 allowEnterKey: undefined
9003 };
9004 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9005
9006 /**
9007 * Is valid parameter
9008 *
9009 * @param {string} paramName
9010 * @returns {boolean}
9011 */
9012 const isValidParameter = paramName => {
9013 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9014 };
9015
9016 /**
9017 * Is valid parameter for Swal.update() method
9018 *
9019 * @param {string} paramName
9020 * @returns {boolean}
9021 */
9022 const isUpdatableParameter = paramName => {
9023 return updatableParams.indexOf(paramName) !== -1;
9024 };
9025
9026 /**
9027 * Is deprecated parameter
9028 *
9029 * @param {string} paramName
9030 * @returns {string | undefined}
9031 */
9032 const isDeprecatedParameter = paramName => {
9033 return deprecatedParams[paramName];
9034 };
9035
9036 /**
9037 * @param {string} param
9038 */
9039 const checkIfParamIsValid = param => {
9040 if (!isValidParameter(param)) {
9041 warn(`Unknown parameter "${param}"`);
9042 }
9043 };
9044
9045 /**
9046 * @param {string} param
9047 */
9048 const checkIfToastParamIsValid = param => {
9049 if (toastIncompatibleParams.includes(param)) {
9050 warn(`The parameter "${param}" is incompatible with toasts`);
9051 }
9052 };
9053
9054 /**
9055 * @param {string} param
9056 */
9057 const checkIfParamIsDeprecated = param => {
9058 const isDeprecated = isDeprecatedParameter(param);
9059 if (isDeprecated) {
9060 warnAboutDeprecation(param, isDeprecated);
9061 }
9062 };
9063
9064 /**
9065 * Show relevant warnings for given params
9066 *
9067 * @param {SweetAlertOptions} params
9068 */
9069 const showWarningsForParams = params => {
9070 if (params.backdrop === false && params.allowOutsideClick) {
9071 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9072 }
9073 if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
9074 warn(`Invalid theme "${params.theme}"`);
9075 }
9076 for (const param in params) {
9077 checkIfParamIsValid(param);
9078 if (params.toast) {
9079 checkIfToastParamIsValid(param);
9080 }
9081 checkIfParamIsDeprecated(param);
9082 }
9083 };
9084
9085 /**
9086 * Updates popup parameters.
9087 *
9088 * @param {SweetAlertOptions} params
9089 */
9090 function update(params) {
9091 const container = getContainer();
9092 const popup = getPopup();
9093 const innerParams = privateProps.innerParams.get(this);
9094 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9095 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.`);
9096 return;
9097 }
9098 const validUpdatableParams = filterValidParams(params);
9099 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9100 showWarningsForParams(updatedParams);
9101 container.dataset['swal2Theme'] = updatedParams.theme;
9102 render(this, updatedParams);
9103 privateProps.innerParams.set(this, updatedParams);
9104 Object.defineProperties(this, {
9105 params: {
9106 value: Object.assign({}, this.params, params),
9107 writable: false,
9108 enumerable: true
9109 }
9110 });
9111 }
9112
9113 /**
9114 * @param {SweetAlertOptions} params
9115 * @returns {SweetAlertOptions}
9116 */
9117 const filterValidParams = params => {
9118 const validUpdatableParams = {};
9119 Object.keys(params).forEach(param => {
9120 if (isUpdatableParameter(param)) {
9121 validUpdatableParams[param] = params[param];
9122 } else {
9123 warn(`Invalid parameter to update: ${param}`);
9124 }
9125 });
9126 return validUpdatableParams;
9127 };
9128
9129 /**
9130 * Dispose the current SweetAlert2 instance
9131 */
9132 function _destroy() {
9133 const domCache = privateProps.domCache.get(this);
9134 const innerParams = privateProps.innerParams.get(this);
9135 if (!innerParams) {
9136 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9137 return; // This instance has already been destroyed
9138 }
9139
9140 // Check if there is another Swal closing
9141 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9142 globalState.swalCloseEventFinishedCallback();
9143 delete globalState.swalCloseEventFinishedCallback;
9144 }
9145 if (typeof innerParams.didDestroy === 'function') {
9146 innerParams.didDestroy();
9147 }
9148 globalState.eventEmitter.emit('didDestroy');
9149 disposeSwal(this);
9150 }
9151
9152 /**
9153 * @param {SweetAlert} instance
9154 */
9155 const disposeSwal = instance => {
9156 disposeWeakMaps(instance);
9157 // Unset this.params so GC will dispose it (#1569)
9158 delete instance.params;
9159 // Unset globalState props so GC will dispose globalState (#1569)
9160 delete globalState.keydownHandler;
9161 delete globalState.keydownTarget;
9162 // Unset currentInstance
9163 delete globalState.currentInstance;
9164 };
9165
9166 /**
9167 * @param {SweetAlert} instance
9168 */
9169 const disposeWeakMaps = instance => {
9170 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9171 if (instance.isAwaitingPromise) {
9172 unsetWeakMaps(privateProps, instance);
9173 instance.isAwaitingPromise = true;
9174 } else {
9175 unsetWeakMaps(privateMethods, instance);
9176 unsetWeakMaps(privateProps, instance);
9177 delete instance.isAwaitingPromise;
9178 // Unset instance methods
9179 delete instance.disableButtons;
9180 delete instance.enableButtons;
9181 delete instance.getInput;
9182 delete instance.disableInput;
9183 delete instance.enableInput;
9184 delete instance.hideLoading;
9185 delete instance.disableLoading;
9186 delete instance.showValidationMessage;
9187 delete instance.resetValidationMessage;
9188 delete instance.close;
9189 delete instance.closePopup;
9190 delete instance.closeModal;
9191 delete instance.closeToast;
9192 delete instance.rejectPromise;
9193 delete instance.update;
9194 delete instance._destroy;
9195 }
9196 };
9197
9198 /**
9199 * @param {object} obj
9200 * @param {SweetAlert} instance
9201 */
9202 const unsetWeakMaps = (obj, instance) => {
9203 for (const i in obj) {
9204 obj[i].delete(instance);
9205 }
9206 };
9207
9208 var instanceMethods = /*#__PURE__*/Object.freeze({
9209 __proto__: null,
9210 _destroy: _destroy,
9211 close: close,
9212 closeModal: close,
9213 closePopup: close,
9214 closeToast: close,
9215 disableButtons: disableButtons,
9216 disableInput: disableInput,
9217 disableLoading: hideLoading,
9218 enableButtons: enableButtons,
9219 enableInput: enableInput,
9220 getInput: getInput,
9221 handleAwaitingPromise: handleAwaitingPromise,
9222 hideLoading: hideLoading,
9223 rejectPromise: rejectPromise,
9224 resetValidationMessage: resetValidationMessage,
9225 showValidationMessage: showValidationMessage,
9226 update: update
9227 });
9228
9229 /**
9230 * @param {SweetAlertOptions} innerParams
9231 * @param {DomCache} domCache
9232 * @param {Function} dismissWith
9233 */
9234 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9235 if (innerParams.toast) {
9236 handleToastClick(innerParams, domCache, dismissWith);
9237 } else {
9238 // Ignore click events that had mousedown on the popup but mouseup on the container
9239 // This can happen when the user drags a slider
9240 handleModalMousedown(domCache);
9241
9242 // Ignore click events that had mousedown on the container but mouseup on the popup
9243 handleContainerMousedown(domCache);
9244 handleModalClick(innerParams, domCache, dismissWith);
9245 }
9246 };
9247
9248 /**
9249 * @param {SweetAlertOptions} innerParams
9250 * @param {DomCache} domCache
9251 * @param {Function} dismissWith
9252 */
9253 const handleToastClick = (innerParams, domCache, dismissWith) => {
9254 // Closing toast by internal click
9255 domCache.popup.onclick = () => {
9256 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9257 return;
9258 }
9259 dismissWith(DismissReason.close);
9260 };
9261 };
9262
9263 /**
9264 * @param {SweetAlertOptions} innerParams
9265 * @returns {boolean}
9266 */
9267 const isAnyButtonShown = innerParams => {
9268 return !!(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9269 };
9270 let ignoreOutsideClick = false;
9271
9272 /**
9273 * @param {DomCache} domCache
9274 */
9275 const handleModalMousedown = domCache => {
9276 domCache.popup.onmousedown = () => {
9277 domCache.container.onmouseup = function (e) {
9278 domCache.container.onmouseup = () => {};
9279 // We only check if the mouseup target is the container because usually it doesn't
9280 // have any other direct children aside of the popup
9281 if (e.target === domCache.container) {
9282 ignoreOutsideClick = true;
9283 }
9284 };
9285 };
9286 };
9287
9288 /**
9289 * @param {DomCache} domCache
9290 */
9291 const handleContainerMousedown = domCache => {
9292 domCache.container.onmousedown = e => {
9293 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9294 if (e.target === domCache.container) {
9295 e.preventDefault();
9296 }
9297 domCache.popup.onmouseup = function (e) {
9298 domCache.popup.onmouseup = () => {};
9299 // We also need to check if the mouseup target is a child of the popup
9300 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9301 ignoreOutsideClick = true;
9302 }
9303 };
9304 };
9305 };
9306
9307 /**
9308 * @param {SweetAlertOptions} innerParams
9309 * @param {DomCache} domCache
9310 * @param {Function} dismissWith
9311 */
9312 const handleModalClick = (innerParams, domCache, dismissWith) => {
9313 domCache.container.onclick = e => {
9314 if (ignoreOutsideClick) {
9315 ignoreOutsideClick = false;
9316 return;
9317 }
9318 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9319 dismissWith(DismissReason.backdrop);
9320 }
9321 };
9322 };
9323
9324 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
9325 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9326 const argsToParams = args => {
9327 const params = {};
9328 if (typeof args[0] === 'object' && !isElement(args[0])) {
9329 Object.assign(params, args[0]);
9330 } else {
9331 ['title', 'html', 'icon'].forEach((name, index) => {
9332 const arg = args[index];
9333 if (typeof arg === 'string' || isElement(arg)) {
9334 params[name] = arg;
9335 } else if (arg !== undefined) {
9336 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9337 }
9338 });
9339 }
9340 return params;
9341 };
9342
9343 /**
9344 * Main method to create a new SweetAlert2 popup
9345 *
9346 * @param {...SweetAlertOptions} args
9347 * @returns {Promise<SweetAlertResult>}
9348 */
9349 function fire(...args) {
9350 return new this(...args);
9351 }
9352
9353 /**
9354 * Returns an extended version of `Swal` containing `params` as defaults.
9355 * Useful for reusing Swal configuration.
9356 *
9357 * For example:
9358 *
9359 * Before:
9360 * const textPromptOptions = { input: 'text', showCancelButton: true }
9361 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9362 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9363 *
9364 * After:
9365 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9366 * const {value: firstName} = await TextPrompt('What is your first name?')
9367 * const {value: lastName} = await TextPrompt('What is your last name?')
9368 *
9369 * @param {SweetAlertOptions} mixinParams
9370 * @returns {SweetAlert}
9371 */
9372 function mixin(mixinParams) {
9373 class MixinSwal extends this {
9374 _main(params, priorityMixinParams) {
9375 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9376 }
9377 }
9378 // @ts-ignore
9379 return MixinSwal;
9380 }
9381
9382 /**
9383 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9384 * Otherwise, returns undefined.
9385 *
9386 * @returns {number | undefined}
9387 */
9388 const getTimerLeft = () => {
9389 return globalState.timeout && globalState.timeout.getTimerLeft();
9390 };
9391
9392 /**
9393 * Stop timer. Returns number of milliseconds of timer remained.
9394 * If `timer` parameter isn't set, returns undefined.
9395 *
9396 * @returns {number | undefined}
9397 */
9398 const stopTimer = () => {
9399 if (globalState.timeout) {
9400 stopTimerProgressBar();
9401 return globalState.timeout.stop();
9402 }
9403 };
9404
9405 /**
9406 * Resume timer. Returns number of milliseconds of timer remained.
9407 * If `timer` parameter isn't set, returns undefined.
9408 *
9409 * @returns {number | undefined}
9410 */
9411 const resumeTimer = () => {
9412 if (globalState.timeout) {
9413 const remaining = globalState.timeout.start();
9414 animateTimerProgressBar(remaining);
9415 return remaining;
9416 }
9417 };
9418
9419 /**
9420 * Resume timer. Returns number of milliseconds of timer remained.
9421 * If `timer` parameter isn't set, returns undefined.
9422 *
9423 * @returns {number | undefined}
9424 */
9425 const toggleTimer = () => {
9426 const timer = globalState.timeout;
9427 return timer && (timer.running ? stopTimer() : resumeTimer());
9428 };
9429
9430 /**
9431 * Increase timer. Returns number of milliseconds of an updated timer.
9432 * If `timer` parameter isn't set, returns undefined.
9433 *
9434 * @param {number} ms
9435 * @returns {number | undefined}
9436 */
9437 const increaseTimer = ms => {
9438 if (globalState.timeout) {
9439 const remaining = globalState.timeout.increase(ms);
9440 animateTimerProgressBar(remaining, true);
9441 return remaining;
9442 }
9443 };
9444
9445 /**
9446 * Check if timer is running. Returns true if timer is running
9447 * or false if timer is paused or stopped.
9448 * If `timer` parameter isn't set, returns undefined
9449 *
9450 * @returns {boolean}
9451 */
9452 const isTimerRunning = () => {
9453 return !!(globalState.timeout && globalState.timeout.isRunning());
9454 };
9455
9456 let bodyClickListenerAdded = false;
9457 const clickHandlers = {};
9458
9459 /**
9460 * @param {string} attr
9461 */
9462 function bindClickHandler(attr = 'data-swal-template') {
9463 clickHandlers[attr] = this;
9464 if (!bodyClickListenerAdded) {
9465 document.body.addEventListener('click', bodyClickListener);
9466 bodyClickListenerAdded = true;
9467 }
9468 }
9469 const bodyClickListener = event => {
9470 for (let el = event.target; el && el !== document; el = el.parentNode) {
9471 for (const attr in clickHandlers) {
9472 const template = el.getAttribute(attr);
9473 if (template) {
9474 clickHandlers[attr].fire({
9475 template
9476 });
9477 return;
9478 }
9479 }
9480 }
9481 };
9482
9483 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9484
9485 class EventEmitter {
9486 constructor() {
9487 /** @type {Events} */
9488 this.events = {};
9489 }
9490
9491 /**
9492 * @param {string} eventName
9493 * @returns {EventHandlers}
9494 */
9495 _getHandlersByEventName(eventName) {
9496 if (typeof this.events[eventName] === 'undefined') {
9497 // not Set because we need to keep the FIFO order
9498 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9499 this.events[eventName] = [];
9500 }
9501 return this.events[eventName];
9502 }
9503
9504 /**
9505 * @param {string} eventName
9506 * @param {EventHandler} eventHandler
9507 */
9508 on(eventName, eventHandler) {
9509 const currentHandlers = this._getHandlersByEventName(eventName);
9510 if (!currentHandlers.includes(eventHandler)) {
9511 currentHandlers.push(eventHandler);
9512 }
9513 }
9514
9515 /**
9516 * @param {string} eventName
9517 * @param {EventHandler} eventHandler
9518 */
9519 once(eventName, eventHandler) {
9520 /**
9521 * @param {Array} args
9522 */
9523 const onceFn = (...args) => {
9524 this.removeListener(eventName, onceFn);
9525 eventHandler.apply(this, args);
9526 };
9527 this.on(eventName, onceFn);
9528 }
9529
9530 /**
9531 * @param {string} eventName
9532 * @param {Array} args
9533 */
9534 emit(eventName, ...args) {
9535 this._getHandlersByEventName(eventName).forEach(
9536 /**
9537 * @param {EventHandler} eventHandler
9538 */
9539 eventHandler => {
9540 try {
9541 eventHandler.apply(this, args);
9542 } catch (error) {
9543 console.error(error);
9544 }
9545 });
9546 }
9547
9548 /**
9549 * @param {string} eventName
9550 * @param {EventHandler} eventHandler
9551 */
9552 removeListener(eventName, eventHandler) {
9553 const currentHandlers = this._getHandlersByEventName(eventName);
9554 const index = currentHandlers.indexOf(eventHandler);
9555 if (index > -1) {
9556 currentHandlers.splice(index, 1);
9557 }
9558 }
9559
9560 /**
9561 * @param {string} eventName
9562 */
9563 removeAllListeners(eventName) {
9564 if (this.events[eventName] !== undefined) {
9565 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
9566 this.events[eventName].length = 0;
9567 }
9568 }
9569 reset() {
9570 this.events = {};
9571 }
9572 }
9573
9574 globalState.eventEmitter = new EventEmitter();
9575
9576 /**
9577 * @param {string} eventName
9578 * @param {EventHandler} eventHandler
9579 */
9580 const on = (eventName, eventHandler) => {
9581 globalState.eventEmitter.on(eventName, eventHandler);
9582 };
9583
9584 /**
9585 * @param {string} eventName
9586 * @param {EventHandler} eventHandler
9587 */
9588 const once = (eventName, eventHandler) => {
9589 globalState.eventEmitter.once(eventName, eventHandler);
9590 };
9591
9592 /**
9593 * @param {string} [eventName]
9594 * @param {EventHandler} [eventHandler]
9595 */
9596 const off = (eventName, eventHandler) => {
9597 // Remove all handlers for all events
9598 if (!eventName) {
9599 globalState.eventEmitter.reset();
9600 return;
9601 }
9602 if (eventHandler) {
9603 // Remove a specific handler
9604 globalState.eventEmitter.removeListener(eventName, eventHandler);
9605 } else {
9606 // Remove all handlers for a specific event
9607 globalState.eventEmitter.removeAllListeners(eventName);
9608 }
9609 };
9610
9611 var staticMethods = /*#__PURE__*/Object.freeze({
9612 __proto__: null,
9613 argsToParams: argsToParams,
9614 bindClickHandler: bindClickHandler,
9615 clickCancel: clickCancel,
9616 clickConfirm: clickConfirm,
9617 clickDeny: clickDeny,
9618 enableLoading: showLoading,
9619 fire: fire,
9620 getActions: getActions,
9621 getCancelButton: getCancelButton,
9622 getCloseButton: getCloseButton,
9623 getConfirmButton: getConfirmButton,
9624 getContainer: getContainer,
9625 getDenyButton: getDenyButton,
9626 getFocusableElements: getFocusableElements,
9627 getFooter: getFooter,
9628 getHtmlContainer: getHtmlContainer,
9629 getIcon: getIcon,
9630 getIconContent: getIconContent,
9631 getImage: getImage,
9632 getInputLabel: getInputLabel,
9633 getLoader: getLoader,
9634 getPopup: getPopup,
9635 getProgressSteps: getProgressSteps,
9636 getTimerLeft: getTimerLeft,
9637 getTimerProgressBar: getTimerProgressBar,
9638 getTitle: getTitle,
9639 getValidationMessage: getValidationMessage,
9640 increaseTimer: increaseTimer,
9641 isDeprecatedParameter: isDeprecatedParameter,
9642 isLoading: isLoading,
9643 isTimerRunning: isTimerRunning,
9644 isUpdatableParameter: isUpdatableParameter,
9645 isValidParameter: isValidParameter,
9646 isVisible: isVisible,
9647 mixin: mixin,
9648 off: off,
9649 on: on,
9650 once: once,
9651 resumeTimer: resumeTimer,
9652 showLoading: showLoading,
9653 stopTimer: stopTimer,
9654 toggleTimer: toggleTimer
9655 });
9656
9657 class Timer {
9658 /**
9659 * @param {Function} callback
9660 * @param {number} delay
9661 */
9662 constructor(callback, delay) {
9663 this.callback = callback;
9664 this.remaining = delay;
9665 this.running = false;
9666 this.start();
9667 }
9668
9669 /**
9670 * @returns {number}
9671 */
9672 start() {
9673 if (!this.running) {
9674 this.running = true;
9675 this.started = new Date();
9676 this.id = setTimeout(this.callback, this.remaining);
9677 }
9678 return this.remaining;
9679 }
9680
9681 /**
9682 * @returns {number}
9683 */
9684 stop() {
9685 if (this.started && this.running) {
9686 this.running = false;
9687 clearTimeout(this.id);
9688 this.remaining -= new Date().getTime() - this.started.getTime();
9689 }
9690 return this.remaining;
9691 }
9692
9693 /**
9694 * @param {number} n
9695 * @returns {number}
9696 */
9697 increase(n) {
9698 const running = this.running;
9699 if (running) {
9700 this.stop();
9701 }
9702 this.remaining += n;
9703 if (running) {
9704 this.start();
9705 }
9706 return this.remaining;
9707 }
9708
9709 /**
9710 * @returns {number}
9711 */
9712 getTimerLeft() {
9713 if (this.running) {
9714 this.stop();
9715 this.start();
9716 }
9717 return this.remaining;
9718 }
9719
9720 /**
9721 * @returns {boolean}
9722 */
9723 isRunning() {
9724 return this.running;
9725 }
9726 }
9727
9728 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
9729
9730 /**
9731 * @param {SweetAlertOptions} params
9732 * @returns {SweetAlertOptions}
9733 */
9734 const getTemplateParams = params => {
9735 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
9736 if (!template) {
9737 return {};
9738 }
9739 /** @type {DocumentFragment} */
9740 const templateContent = template.content;
9741 showWarningsForElements(templateContent);
9742 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
9743 return result;
9744 };
9745
9746 /**
9747 * @param {DocumentFragment} templateContent
9748 * @returns {Record<string, any>}
9749 */
9750 const getSwalParams = templateContent => {
9751 /** @type {Record<string, any>} */
9752 const result = {};
9753 /** @type {HTMLElement[]} */
9754 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
9755 swalParams.forEach(param => {
9756 showWarningsForAttributes(param, ['name', 'value']);
9757 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
9758 const value = param.getAttribute('value');
9759 if (!paramName || !value) {
9760 return;
9761 }
9762 if (typeof defaultParams[paramName] === 'boolean') {
9763 result[paramName] = value !== 'false';
9764 } else if (typeof defaultParams[paramName] === 'object') {
9765 result[paramName] = JSON.parse(value);
9766 } else {
9767 result[paramName] = value;
9768 }
9769 });
9770 return result;
9771 };
9772
9773 /**
9774 * @param {DocumentFragment} templateContent
9775 * @returns {Record<string, any>}
9776 */
9777 const getSwalFunctionParams = templateContent => {
9778 /** @type {Record<string, any>} */
9779 const result = {};
9780 /** @type {HTMLElement[]} */
9781 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
9782 swalFunctions.forEach(param => {
9783 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
9784 const value = param.getAttribute('value');
9785 if (!paramName || !value) {
9786 return;
9787 }
9788 result[paramName] = new Function(`return ${value}`)();
9789 });
9790 return result;
9791 };
9792
9793 /**
9794 * @param {DocumentFragment} templateContent
9795 * @returns {Record<string, any>}
9796 */
9797 const getSwalButtons = templateContent => {
9798 /** @type {Record<string, any>} */
9799 const result = {};
9800 /** @type {HTMLElement[]} */
9801 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
9802 swalButtons.forEach(button => {
9803 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
9804 const type = button.getAttribute('type');
9805 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
9806 return;
9807 }
9808 result[`${type}ButtonText`] = button.innerHTML;
9809 result[`show${capitalizeFirstLetter(type)}Button`] = true;
9810 if (button.hasAttribute('color')) {
9811 result[`${type}ButtonColor`] = button.getAttribute('color');
9812 }
9813 if (button.hasAttribute('aria-label')) {
9814 result[`${type}ButtonAriaLabel`] = button.getAttribute('aria-label');
9815 }
9816 });
9817 return result;
9818 };
9819
9820 /**
9821 * @param {DocumentFragment} templateContent
9822 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
9823 */
9824 const getSwalImage = templateContent => {
9825 const result = {};
9826 /** @type {HTMLElement | null} */
9827 const image = templateContent.querySelector('swal-image');
9828 if (image) {
9829 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
9830 if (image.hasAttribute('src')) {
9831 result.imageUrl = image.getAttribute('src') || undefined;
9832 }
9833 if (image.hasAttribute('width')) {
9834 result.imageWidth = image.getAttribute('width') || undefined;
9835 }
9836 if (image.hasAttribute('height')) {
9837 result.imageHeight = image.getAttribute('height') || undefined;
9838 }
9839 if (image.hasAttribute('alt')) {
9840 result.imageAlt = image.getAttribute('alt') || undefined;
9841 }
9842 }
9843 return result;
9844 };
9845
9846 /**
9847 * @param {DocumentFragment} templateContent
9848 * @returns {Record<string, any>}
9849 */
9850 const getSwalIcon = templateContent => {
9851 const result = {};
9852 /** @type {HTMLElement | null} */
9853 const icon = templateContent.querySelector('swal-icon');
9854 if (icon) {
9855 showWarningsForAttributes(icon, ['type', 'color']);
9856 if (icon.hasAttribute('type')) {
9857 result.icon = icon.getAttribute('type');
9858 }
9859 if (icon.hasAttribute('color')) {
9860 result.iconColor = icon.getAttribute('color');
9861 }
9862 result.iconHtml = icon.innerHTML;
9863 }
9864 return result;
9865 };
9866
9867 /**
9868 * @param {DocumentFragment} templateContent
9869 * @returns {Record<string, any>}
9870 */
9871 const getSwalInput = templateContent => {
9872 /** @type {Record<string, any>} */
9873 const result = {};
9874 /** @type {HTMLElement | null} */
9875 const input = templateContent.querySelector('swal-input');
9876 if (input) {
9877 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
9878 result.input = input.getAttribute('type') || 'text';
9879 if (input.hasAttribute('label')) {
9880 result.inputLabel = input.getAttribute('label');
9881 }
9882 if (input.hasAttribute('placeholder')) {
9883 result.inputPlaceholder = input.getAttribute('placeholder');
9884 }
9885 if (input.hasAttribute('value')) {
9886 result.inputValue = input.getAttribute('value');
9887 }
9888 }
9889 /** @type {HTMLElement[]} */
9890 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
9891 if (inputOptions.length) {
9892 result.inputOptions = {};
9893 inputOptions.forEach(option => {
9894 showWarningsForAttributes(option, ['value']);
9895 const optionValue = option.getAttribute('value');
9896 if (!optionValue) {
9897 return;
9898 }
9899 const optionName = option.innerHTML;
9900 result.inputOptions[optionValue] = optionName;
9901 });
9902 }
9903 return result;
9904 };
9905
9906 /**
9907 * @param {DocumentFragment} templateContent
9908 * @param {string[]} paramNames
9909 * @returns {Record<string, any>}
9910 */
9911 const getSwalStringParams = (templateContent, paramNames) => {
9912 /** @type {Record<string, any>} */
9913 const result = {};
9914 for (const i in paramNames) {
9915 const paramName = paramNames[i];
9916 /** @type {HTMLElement | null} */
9917 const tag = templateContent.querySelector(paramName);
9918 if (tag) {
9919 showWarningsForAttributes(tag, []);
9920 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
9921 }
9922 }
9923 return result;
9924 };
9925
9926 /**
9927 * @param {DocumentFragment} templateContent
9928 */
9929 const showWarningsForElements = templateContent => {
9930 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
9931 Array.from(templateContent.children).forEach(el => {
9932 const tagName = el.tagName.toLowerCase();
9933 if (!allowedElements.includes(tagName)) {
9934 warn(`Unrecognized element <${tagName}>`);
9935 }
9936 });
9937 };
9938
9939 /**
9940 * @param {HTMLElement} el
9941 * @param {string[]} allowedAttributes
9942 */
9943 const showWarningsForAttributes = (el, allowedAttributes) => {
9944 Array.from(el.attributes).forEach(attribute => {
9945 if (allowedAttributes.indexOf(attribute.name) === -1) {
9946 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.'}`]);
9947 }
9948 });
9949 };
9950
9951 const SHOW_CLASS_TIMEOUT = 10;
9952
9953 /**
9954 * Open popup, add necessary classes and styles, fix scrollbar
9955 *
9956 * @param {SweetAlertOptions} params
9957 */
9958 const openPopup = params => {
9959 const container = getContainer();
9960 const popup = getPopup();
9961 if (typeof params.willOpen === 'function') {
9962 params.willOpen(popup);
9963 }
9964 globalState.eventEmitter.emit('willOpen', popup);
9965 const bodyStyles = window.getComputedStyle(document.body);
9966 const initialBodyOverflow = bodyStyles.overflowY;
9967 addClasses(container, popup, params);
9968
9969 // scrolling is 'hidden' until animation is done, after that 'auto'
9970 setTimeout(() => {
9971 setScrollingVisibility(container, popup);
9972 }, SHOW_CLASS_TIMEOUT);
9973 if (isModal()) {
9974 fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow);
9975 setAriaHidden();
9976 }
9977 if (!isToast() && !globalState.previousActiveElement) {
9978 globalState.previousActiveElement = document.activeElement;
9979 }
9980 if (typeof params.didOpen === 'function') {
9981 setTimeout(() => params.didOpen(popup));
9982 }
9983 globalState.eventEmitter.emit('didOpen', popup);
9984 removeClass(container, swalClasses['no-transition']);
9985 };
9986
9987 /**
9988 * @param {AnimationEvent} event
9989 */
9990 const swalOpenAnimationFinished = event => {
9991 const popup = getPopup();
9992 if (event.target !== popup) {
9993 return;
9994 }
9995 const container = getContainer();
9996 popup.removeEventListener('animationend', swalOpenAnimationFinished);
9997 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
9998 container.style.overflowY = 'auto';
9999 };
10000
10001 /**
10002 * @param {HTMLElement} container
10003 * @param {HTMLElement} popup
10004 */
10005 const setScrollingVisibility = (container, popup) => {
10006 if (hasCssAnimation(popup)) {
10007 container.style.overflowY = 'hidden';
10008 popup.addEventListener('animationend', swalOpenAnimationFinished);
10009 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10010 } else {
10011 container.style.overflowY = 'auto';
10012 }
10013 };
10014
10015 /**
10016 * @param {HTMLElement} container
10017 * @param {boolean} scrollbarPadding
10018 * @param {string} initialBodyOverflow
10019 */
10020 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10021 iOSfix();
10022 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10023 replaceScrollbarWithPadding(initialBodyOverflow);
10024 }
10025
10026 // sweetalert2/issues/1247
10027 setTimeout(() => {
10028 container.scrollTop = 0;
10029 });
10030 };
10031
10032 /**
10033 * @param {HTMLElement} container
10034 * @param {HTMLElement} popup
10035 * @param {SweetAlertOptions} params
10036 */
10037 const addClasses = (container, popup, params) => {
10038 addClass(container, params.showClass.backdrop);
10039 if (params.animation) {
10040 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10041 popup.style.setProperty('opacity', '0', 'important');
10042 show(popup, 'grid');
10043 setTimeout(() => {
10044 // Animate popup right after showing it
10045 addClass(popup, params.showClass.popup);
10046 // and remove the opacity workaround
10047 popup.style.removeProperty('opacity');
10048 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10049 } else {
10050 show(popup, 'grid');
10051 }
10052 addClass([document.documentElement, document.body], swalClasses.shown);
10053 if (params.heightAuto && params.backdrop && !params.toast) {
10054 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10055 }
10056 };
10057
10058 var defaultInputValidators = {
10059 /**
10060 * @param {string} string
10061 * @param {string} [validationMessage]
10062 * @returns {Promise<string | void>}
10063 */
10064 email: (string, validationMessage) => {
10065 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10066 },
10067 /**
10068 * @param {string} string
10069 * @param {string} [validationMessage]
10070 * @returns {Promise<string | void>}
10071 */
10072 url: (string, validationMessage) => {
10073 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10074 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');
10075 }
10076 };
10077
10078 /**
10079 * @param {SweetAlertOptions} params
10080 */
10081 function setDefaultInputValidators(params) {
10082 // Use default `inputValidator` for supported input types if not provided
10083 if (params.inputValidator) {
10084 return;
10085 }
10086 if (params.input === 'email') {
10087 params.inputValidator = defaultInputValidators['email'];
10088 }
10089 if (params.input === 'url') {
10090 params.inputValidator = defaultInputValidators['url'];
10091 }
10092 }
10093
10094 /**
10095 * @param {SweetAlertOptions} params
10096 */
10097 function validateCustomTargetElement(params) {
10098 // Determine if the custom target element is valid
10099 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10100 warn('Target parameter is not valid, defaulting to "body"');
10101 params.target = 'body';
10102 }
10103 }
10104
10105 /**
10106 * Set type, text and actions on popup
10107 *
10108 * @param {SweetAlertOptions} params
10109 */
10110 function setParameters(params) {
10111 setDefaultInputValidators(params);
10112
10113 // showLoaderOnConfirm && preConfirm
10114 if (params.showLoaderOnConfirm && !params.preConfirm) {
10115 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');
10116 }
10117 validateCustomTargetElement(params);
10118
10119 // Replace newlines with <br> in title
10120 if (typeof params.title === 'string') {
10121 params.title = params.title.split('\n').join('<br />');
10122 }
10123 init(params);
10124 }
10125
10126 /** @type {SweetAlert} */
10127 let currentInstance;
10128 var _promise = /*#__PURE__*/new WeakMap();
10129 class SweetAlert {
10130 /**
10131 * @param {...any} args
10132 * @this {SweetAlert}
10133 */
10134 constructor(...args) {
10135 /**
10136 * @type {Promise<SweetAlertResult>}
10137 */
10138 _classPrivateFieldInitSpec(this, _promise, void 0);
10139 // Prevent run in Node env
10140 if (typeof window === 'undefined') {
10141 return;
10142 }
10143 currentInstance = this;
10144
10145 // @ts-ignore
10146 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10147
10148 /** @type {Readonly<SweetAlertOptions>} */
10149 this.params = outerParams;
10150
10151 /** @type {boolean} */
10152 this.isAwaitingPromise = false;
10153 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10154 }
10155 _main(userParams, mixinParams = {}) {
10156 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10157 if (globalState.currentInstance) {
10158 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10159 const {
10160 isAwaitingPromise
10161 } = globalState.currentInstance;
10162 globalState.currentInstance._destroy();
10163 if (!isAwaitingPromise) {
10164 swalPromiseResolve({
10165 isDismissed: true
10166 });
10167 }
10168 if (isModal()) {
10169 unsetAriaHidden();
10170 }
10171 }
10172 globalState.currentInstance = currentInstance;
10173 const innerParams = prepareParams(userParams, mixinParams);
10174 setParameters(innerParams);
10175 Object.freeze(innerParams);
10176
10177 // clear the previous timer
10178 if (globalState.timeout) {
10179 globalState.timeout.stop();
10180 delete globalState.timeout;
10181 }
10182
10183 // clear the restore focus timeout
10184 clearTimeout(globalState.restoreFocusTimeout);
10185 const domCache = populateDomCache(currentInstance);
10186 render(currentInstance, innerParams);
10187 privateProps.innerParams.set(currentInstance, innerParams);
10188 return swalPromise(currentInstance, domCache, innerParams);
10189 }
10190
10191 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10192 then(onFulfilled) {
10193 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10194 }
10195 finally(onFinally) {
10196 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10197 }
10198 }
10199
10200 /**
10201 * @param {SweetAlert} instance
10202 * @param {DomCache} domCache
10203 * @param {SweetAlertOptions} innerParams
10204 * @returns {Promise}
10205 */
10206 const swalPromise = (instance, domCache, innerParams) => {
10207 return new Promise((resolve, reject) => {
10208 // functions to handle all closings/dismissals
10209 /**
10210 * @param {DismissReason} dismiss
10211 */
10212 const dismissWith = dismiss => {
10213 instance.close({
10214 isDismissed: true,
10215 dismiss
10216 });
10217 };
10218 privateMethods.swalPromiseResolve.set(instance, resolve);
10219 privateMethods.swalPromiseReject.set(instance, reject);
10220 domCache.confirmButton.onclick = () => {
10221 handleConfirmButtonClick(instance);
10222 };
10223 domCache.denyButton.onclick = () => {
10224 handleDenyButtonClick(instance);
10225 };
10226 domCache.cancelButton.onclick = () => {
10227 handleCancelButtonClick(instance, dismissWith);
10228 };
10229 domCache.closeButton.onclick = () => {
10230 dismissWith(DismissReason.close);
10231 };
10232 handlePopupClick(innerParams, domCache, dismissWith);
10233 addKeydownHandler(globalState, innerParams, dismissWith);
10234 handleInputOptionsAndValue(instance, innerParams);
10235 openPopup(innerParams);
10236 setupTimer(globalState, innerParams, dismissWith);
10237 initFocus(domCache, innerParams);
10238
10239 // Scroll container to top on open (#1247, #1946)
10240 setTimeout(() => {
10241 domCache.container.scrollTop = 0;
10242 });
10243 });
10244 };
10245
10246 /**
10247 * @param {SweetAlertOptions} userParams
10248 * @param {SweetAlertOptions} mixinParams
10249 * @returns {SweetAlertOptions}
10250 */
10251 const prepareParams = (userParams, mixinParams) => {
10252 const templateParams = getTemplateParams(userParams);
10253 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10254 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10255 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10256 if (params.animation === false) {
10257 params.showClass = {
10258 backdrop: 'swal2-noanimation'
10259 };
10260 params.hideClass = {};
10261 }
10262 return params;
10263 };
10264
10265 /**
10266 * @param {SweetAlert} instance
10267 * @returns {DomCache}
10268 */
10269 const populateDomCache = instance => {
10270 const domCache = {
10271 popup: getPopup(),
10272 container: getContainer(),
10273 actions: getActions(),
10274 confirmButton: getConfirmButton(),
10275 denyButton: getDenyButton(),
10276 cancelButton: getCancelButton(),
10277 loader: getLoader(),
10278 closeButton: getCloseButton(),
10279 validationMessage: getValidationMessage(),
10280 progressSteps: getProgressSteps()
10281 };
10282 privateProps.domCache.set(instance, domCache);
10283 return domCache;
10284 };
10285
10286 /**
10287 * @param {GlobalState} globalState
10288 * @param {SweetAlertOptions} innerParams
10289 * @param {Function} dismissWith
10290 */
10291 const setupTimer = (globalState, innerParams, dismissWith) => {
10292 const timerProgressBar = getTimerProgressBar();
10293 hide(timerProgressBar);
10294 if (innerParams.timer) {
10295 globalState.timeout = new Timer(() => {
10296 dismissWith('timer');
10297 delete globalState.timeout;
10298 }, innerParams.timer);
10299 if (innerParams.timerProgressBar) {
10300 show(timerProgressBar);
10301 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10302 setTimeout(() => {
10303 if (globalState.timeout && globalState.timeout.running) {
10304 // timer can be already stopped or unset at this point
10305 animateTimerProgressBar(innerParams.timer);
10306 }
10307 });
10308 }
10309 }
10310 };
10311
10312 /**
10313 * Initialize focus in the popup:
10314 *
10315 * 1. If `toast` is `true`, don't steal focus from the document.
10316 * 2. Else if there is an [autofocus] element, focus it.
10317 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10318 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10319 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10320 * 6. Else focus the first focusable element in a popup (if any).
10321 *
10322 * @param {DomCache} domCache
10323 * @param {SweetAlertOptions} innerParams
10324 */
10325 const initFocus = (domCache, innerParams) => {
10326 if (innerParams.toast) {
10327 return;
10328 }
10329 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10330 if (!callIfFunction(innerParams.allowEnterKey)) {
10331 warnAboutDeprecation('allowEnterKey');
10332 blurActiveElement();
10333 return;
10334 }
10335 if (focusAutofocus(domCache)) {
10336 return;
10337 }
10338 if (focusButton(domCache, innerParams)) {
10339 return;
10340 }
10341 setFocus(-1, 1);
10342 };
10343
10344 /**
10345 * @param {DomCache} domCache
10346 * @returns {boolean}
10347 */
10348 const focusAutofocus = domCache => {
10349 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10350 for (const autofocusElement of autofocusElements) {
10351 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10352 autofocusElement.focus();
10353 return true;
10354 }
10355 }
10356 return false;
10357 };
10358
10359 /**
10360 * @param {DomCache} domCache
10361 * @param {SweetAlertOptions} innerParams
10362 * @returns {boolean}
10363 */
10364 const focusButton = (domCache, innerParams) => {
10365 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10366 domCache.denyButton.focus();
10367 return true;
10368 }
10369 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10370 domCache.cancelButton.focus();
10371 return true;
10372 }
10373 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10374 domCache.confirmButton.focus();
10375 return true;
10376 }
10377 return false;
10378 };
10379 const blurActiveElement = () => {
10380 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
10381 document.activeElement.blur();
10382 }
10383 };
10384
10385 // Assign instance methods from src/instanceMethods/*.js to prototype
10386 SweetAlert.prototype.disableButtons = disableButtons;
10387 SweetAlert.prototype.enableButtons = enableButtons;
10388 SweetAlert.prototype.getInput = getInput;
10389 SweetAlert.prototype.disableInput = disableInput;
10390 SweetAlert.prototype.enableInput = enableInput;
10391 SweetAlert.prototype.hideLoading = hideLoading;
10392 SweetAlert.prototype.disableLoading = hideLoading;
10393 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10394 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10395 SweetAlert.prototype.close = close;
10396 SweetAlert.prototype.closePopup = close;
10397 SweetAlert.prototype.closeModal = close;
10398 SweetAlert.prototype.closeToast = close;
10399 SweetAlert.prototype.rejectPromise = rejectPromise;
10400 SweetAlert.prototype.update = update;
10401 SweetAlert.prototype._destroy = _destroy;
10402
10403 // Assign static methods from src/staticMethods/*.js to constructor
10404 Object.assign(SweetAlert, staticMethods);
10405
10406 // Proxy to instance methods to constructor, for now, for backwards compatibility
10407 Object.keys(instanceMethods).forEach(key => {
10408 /**
10409 * @param {...any} args
10410 * @returns {any | undefined}
10411 */
10412 SweetAlert[key] = function (...args) {
10413 if (currentInstance && currentInstance[key]) {
10414 return currentInstance[key](...args);
10415 }
10416 return null;
10417 };
10418 });
10419 SweetAlert.DismissReason = DismissReason;
10420 SweetAlert.version = '11.22.5';
10421
10422 const Swal = SweetAlert;
10423 // @ts-ignore
10424 Swal.default = Swal;
10425
10426 return Swal;
10427
10428 }));
10429 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10430 "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.1s;--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-icon-animations: true;--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 $swal2-outline-color;--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:all}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;container-name:swal2-popup}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;word-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;word-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)}@container swal2-popup style(--swal2-icon-animations:true){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}@container swal2-popup style(--swal2-icon-animations:true){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}@container swal2-popup style(--swal2-icon-animations:true){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}@container swal2-popup style(--swal2-icon-animations:true){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)}@container swal2-popup style(--swal2-icon-animations:true){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:all}.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}@container swal2-popup style(--swal2-icon-animations:true){.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:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);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}}");
10431
10432 /***/ }),
10433
10434 /***/ "./node_modules/toastify-js/src/toastify.js":
10435 /*!**************************************************!*\
10436 !*** ./node_modules/toastify-js/src/toastify.js ***!
10437 \**************************************************/
10438 /***/ (function(module) {
10439
10440 /*!
10441 * Toastify js 1.12.0
10442 * https://github.com/apvarun/toastify-js
10443 * @license MIT licensed
10444 *
10445 * Copyright (C) 2018 Varun A P
10446 */
10447 (function(root, factory) {
10448 if ( true && module.exports) {
10449 module.exports = factory();
10450 } else {
10451 root.Toastify = factory();
10452 }
10453 })(this, function(global) {
10454 // Object initialization
10455 var Toastify = function(options) {
10456 // Returning a new init object
10457 return new Toastify.lib.init(options);
10458 },
10459 // Library version
10460 version = "1.12.0";
10461
10462 // Set the default global options
10463 Toastify.defaults = {
10464 oldestFirst: true,
10465 text: "Toastify is awesome!",
10466 node: undefined,
10467 duration: 3000,
10468 selector: undefined,
10469 callback: function () {
10470 },
10471 destination: undefined,
10472 newWindow: false,
10473 close: false,
10474 gravity: "toastify-top",
10475 positionLeft: false,
10476 position: '',
10477 backgroundColor: '',
10478 avatar: "",
10479 className: "",
10480 stopOnFocus: true,
10481 onClick: function () {
10482 },
10483 offset: {x: 0, y: 0},
10484 escapeMarkup: true,
10485 ariaLive: 'polite',
10486 style: {background: ''}
10487 };
10488
10489 // Defining the prototype of the object
10490 Toastify.lib = Toastify.prototype = {
10491 toastify: version,
10492
10493 constructor: Toastify,
10494
10495 // Initializing the object with required parameters
10496 init: function(options) {
10497 // Verifying and validating the input object
10498 if (!options) {
10499 options = {};
10500 }
10501
10502 // Creating the options object
10503 this.options = {};
10504
10505 this.toastElement = null;
10506
10507 // Validating the options
10508 this.options.text = options.text || Toastify.defaults.text; // Display message
10509 this.options.node = options.node || Toastify.defaults.node; // Display content as node
10510 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
10511 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
10512 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
10513 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
10514 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
10515 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
10516 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
10517 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
10518 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
10519 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
10520 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
10521 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
10522 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
10523 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
10524 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
10525 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
10526 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
10527 this.options.style = options.style || Toastify.defaults.style;
10528 if(options.backgroundColor) {
10529 this.options.style.background = options.backgroundColor;
10530 }
10531
10532 // Returning the current object for chaining functions
10533 return this;
10534 },
10535
10536 // Building the DOM element
10537 buildToast: function() {
10538 // Validating if the options are defined
10539 if (!this.options) {
10540 throw "Toastify is not initialized";
10541 }
10542
10543 // Creating the DOM object
10544 var divElement = document.createElement("div");
10545 divElement.className = "toastify on " + this.options.className;
10546
10547 // Positioning toast to left or right or center
10548 if (!!this.options.position) {
10549 divElement.className += " toastify-" + this.options.position;
10550 } else {
10551 // To be depreciated in further versions
10552 if (this.options.positionLeft === true) {
10553 divElement.className += " toastify-left";
10554 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
10555 } else {
10556 // Default position
10557 divElement.className += " toastify-right";
10558 }
10559 }
10560
10561 // Assigning gravity of element
10562 divElement.className += " " + this.options.gravity;
10563
10564 if (this.options.backgroundColor) {
10565 // This is being deprecated in favor of using the style HTML DOM property
10566 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
10567 }
10568
10569 // Loop through our style object and apply styles to divElement
10570 for (var property in this.options.style) {
10571 divElement.style[property] = this.options.style[property];
10572 }
10573
10574 // Announce the toast to screen readers
10575 if (this.options.ariaLive) {
10576 divElement.setAttribute('aria-live', this.options.ariaLive)
10577 }
10578
10579 // Adding the toast message/node
10580 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
10581 // If we have a valid node, we insert it
10582 divElement.appendChild(this.options.node)
10583 } else {
10584 if (this.options.escapeMarkup) {
10585 divElement.innerText = this.options.text;
10586 } else {
10587 divElement.innerHTML = this.options.text;
10588 }
10589
10590 if (this.options.avatar !== "") {
10591 var avatarElement = document.createElement("img");
10592 avatarElement.src = this.options.avatar;
10593
10594 avatarElement.className = "toastify-avatar";
10595
10596 if (this.options.position == "left" || this.options.positionLeft === true) {
10597 // Adding close icon on the left of content
10598 divElement.appendChild(avatarElement);
10599 } else {
10600 // Adding close icon on the right of content
10601 divElement.insertAdjacentElement("afterbegin", avatarElement);
10602 }
10603 }
10604 }
10605
10606 // Adding a close icon to the toast
10607 if (this.options.close === true) {
10608 // Create a span for close element
10609 var closeElement = document.createElement("button");
10610 closeElement.type = "button";
10611 closeElement.setAttribute("aria-label", "Close");
10612 closeElement.className = "toast-close";
10613 closeElement.innerHTML = "&#10006;";
10614
10615 // Triggering the removal of toast from DOM on close click
10616 closeElement.addEventListener(
10617 "click",
10618 function(event) {
10619 event.stopPropagation();
10620 this.removeElement(this.toastElement);
10621 window.clearTimeout(this.toastElement.timeOutValue);
10622 }.bind(this)
10623 );
10624
10625 //Calculating screen width
10626 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
10627
10628 // Adding the close icon to the toast element
10629 // Display on the right if screen width is less than or equal to 360px
10630 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
10631 // Adding close icon on the left of content
10632 divElement.insertAdjacentElement("afterbegin", closeElement);
10633 } else {
10634 // Adding close icon on the right of content
10635 divElement.appendChild(closeElement);
10636 }
10637 }
10638
10639 // Clear timeout while toast is focused
10640 if (this.options.stopOnFocus && this.options.duration > 0) {
10641 var self = this;
10642 // stop countdown
10643 divElement.addEventListener(
10644 "mouseover",
10645 function(event) {
10646 window.clearTimeout(divElement.timeOutValue);
10647 }
10648 )
10649 // add back the timeout
10650 divElement.addEventListener(
10651 "mouseleave",
10652 function() {
10653 divElement.timeOutValue = window.setTimeout(
10654 function() {
10655 // Remove the toast from DOM
10656 self.removeElement(divElement);
10657 },
10658 self.options.duration
10659 )
10660 }
10661 )
10662 }
10663
10664 // Adding an on-click destination path
10665 if (typeof this.options.destination !== "undefined") {
10666 divElement.addEventListener(
10667 "click",
10668 function(event) {
10669 event.stopPropagation();
10670 if (this.options.newWindow === true) {
10671 window.open(this.options.destination, "_blank");
10672 } else {
10673 window.location = this.options.destination;
10674 }
10675 }.bind(this)
10676 );
10677 }
10678
10679 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
10680 divElement.addEventListener(
10681 "click",
10682 function(event) {
10683 event.stopPropagation();
10684 this.options.onClick();
10685 }.bind(this)
10686 );
10687 }
10688
10689 // Adding offset
10690 if(typeof this.options.offset === "object") {
10691
10692 var x = getAxisOffsetAValue("x", this.options);
10693 var y = getAxisOffsetAValue("y", this.options);
10694
10695 var xOffset = this.options.position == "left" ? x : "-" + x;
10696 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
10697
10698 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
10699
10700 }
10701
10702 // Returning the generated element
10703 return divElement;
10704 },
10705
10706 // Displaying the toast
10707 showToast: function() {
10708 // Creating the DOM object for the toast
10709 this.toastElement = this.buildToast();
10710
10711 // Getting the root element to with the toast needs to be added
10712 var rootElement;
10713 if (typeof this.options.selector === "string") {
10714 rootElement = document.getElementById(this.options.selector);
10715 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
10716 rootElement = this.options.selector;
10717 } else {
10718 rootElement = document.body;
10719 }
10720
10721 // Validating if root element is present in DOM
10722 if (!rootElement) {
10723 throw "Root element is not defined";
10724 }
10725
10726 // Adding the DOM element
10727 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
10728 rootElement.insertBefore(this.toastElement, elementToInsert);
10729
10730 // Repositioning the toasts in case multiple toasts are present
10731 Toastify.reposition();
10732
10733 if (this.options.duration > 0) {
10734 this.toastElement.timeOutValue = window.setTimeout(
10735 function() {
10736 // Remove the toast from DOM
10737 this.removeElement(this.toastElement);
10738 }.bind(this),
10739 this.options.duration
10740 ); // Binding `this` for function invocation
10741 }
10742
10743 // Supporting function chaining
10744 return this;
10745 },
10746
10747 hideToast: function() {
10748 if (this.toastElement.timeOutValue) {
10749 clearTimeout(this.toastElement.timeOutValue);
10750 }
10751 this.removeElement(this.toastElement);
10752 },
10753
10754 // Removing the element from the DOM
10755 removeElement: function(toastElement) {
10756 // Hiding the element
10757 // toastElement.classList.remove("on");
10758 toastElement.className = toastElement.className.replace(" on", "");
10759
10760 // Removing the element from DOM after transition end
10761 window.setTimeout(
10762 function() {
10763 // remove options node if any
10764 if (this.options.node && this.options.node.parentNode) {
10765 this.options.node.parentNode.removeChild(this.options.node);
10766 }
10767
10768 // Remove the element from the DOM, only when the parent node was not removed before.
10769 if (toastElement.parentNode) {
10770 toastElement.parentNode.removeChild(toastElement);
10771 }
10772
10773 // Calling the callback function
10774 this.options.callback.call(toastElement);
10775
10776 // Repositioning the toasts again
10777 Toastify.reposition();
10778 }.bind(this),
10779 400
10780 ); // Binding `this` for function invocation
10781 },
10782 };
10783
10784 // Positioning the toasts on the DOM
10785 Toastify.reposition = function() {
10786
10787 // Top margins with gravity
10788 var topLeftOffsetSize = {
10789 top: 15,
10790 bottom: 15,
10791 };
10792 var topRightOffsetSize = {
10793 top: 15,
10794 bottom: 15,
10795 };
10796 var offsetSize = {
10797 top: 15,
10798 bottom: 15,
10799 };
10800
10801 // Get all toast messages on the DOM
10802 var allToasts = document.getElementsByClassName("toastify");
10803
10804 var classUsed;
10805
10806 // Modifying the position of each toast element
10807 for (var i = 0; i < allToasts.length; i++) {
10808 // Getting the applied gravity
10809 if (containsClass(allToasts[i], "toastify-top") === true) {
10810 classUsed = "toastify-top";
10811 } else {
10812 classUsed = "toastify-bottom";
10813 }
10814
10815 var height = allToasts[i].offsetHeight;
10816 classUsed = classUsed.substr(9, classUsed.length-1)
10817 // Spacing between toasts
10818 var offset = 15;
10819
10820 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
10821
10822 // Show toast in center if screen with less than or equal to 360px
10823 if (width <= 360) {
10824 // Setting the position
10825 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
10826
10827 offsetSize[classUsed] += height + offset;
10828 } else {
10829 if (containsClass(allToasts[i], "toastify-left") === true) {
10830 // Setting the position
10831 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
10832
10833 topLeftOffsetSize[classUsed] += height + offset;
10834 } else {
10835 // Setting the position
10836 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
10837
10838 topRightOffsetSize[classUsed] += height + offset;
10839 }
10840 }
10841 }
10842
10843 // Supporting function chaining
10844 return this;
10845 };
10846
10847 // Helper function to get offset.
10848 function getAxisOffsetAValue(axis, options) {
10849
10850 if(options.offset[axis]) {
10851 if(isNaN(options.offset[axis])) {
10852 return options.offset[axis];
10853 }
10854 else {
10855 return options.offset[axis] + 'px';
10856 }
10857 }
10858
10859 return '0px';
10860
10861 }
10862
10863 function containsClass(elem, yourClass) {
10864 if (!elem || typeof yourClass !== "string") {
10865 return false;
10866 } else if (
10867 elem.className &&
10868 elem.className
10869 .trim()
10870 .split(/\s+/gi)
10871 .indexOf(yourClass) > -1
10872 ) {
10873 return true;
10874 } else {
10875 return false;
10876 }
10877 }
10878
10879 // Setting up the prototype for the init object
10880 Toastify.lib.init.prototype = Toastify.lib;
10881
10882 // Returning the Toastify function to be assigned to the window object/module
10883 return Toastify;
10884 });
10885
10886
10887 /***/ })
10888
10889 /******/ });
10890 /************************************************************************/
10891 /******/ // The module cache
10892 /******/ var __webpack_module_cache__ = {};
10893 /******/
10894 /******/ // The require function
10895 /******/ function __webpack_require__(moduleId) {
10896 /******/ // Check if module is in cache
10897 /******/ var cachedModule = __webpack_module_cache__[moduleId];
10898 /******/ if (cachedModule !== undefined) {
10899 /******/ return cachedModule.exports;
10900 /******/ }
10901 /******/ // Create a new module (and put it into the cache)
10902 /******/ var module = __webpack_module_cache__[moduleId] = {
10903 /******/ id: moduleId,
10904 /******/ // no module.loaded needed
10905 /******/ exports: {}
10906 /******/ };
10907 /******/
10908 /******/ // Execute the module function
10909 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
10910 /******/
10911 /******/ // Return the exports of the module
10912 /******/ return module.exports;
10913 /******/ }
10914 /******/
10915 /************************************************************************/
10916 /******/ /* webpack/runtime/compat get default export */
10917 /******/ (() => {
10918 /******/ // getDefaultExport function for compatibility with non-harmony modules
10919 /******/ __webpack_require__.n = (module) => {
10920 /******/ var getter = module && module.__esModule ?
10921 /******/ () => (module['default']) :
10922 /******/ () => (module);
10923 /******/ __webpack_require__.d(getter, { a: getter });
10924 /******/ return getter;
10925 /******/ };
10926 /******/ })();
10927 /******/
10928 /******/ /* webpack/runtime/define property getters */
10929 /******/ (() => {
10930 /******/ // define getter functions for harmony exports
10931 /******/ __webpack_require__.d = (exports, definition) => {
10932 /******/ for(var key in definition) {
10933 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
10934 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
10935 /******/ }
10936 /******/ }
10937 /******/ };
10938 /******/ })();
10939 /******/
10940 /******/ /* webpack/runtime/hasOwnProperty shorthand */
10941 /******/ (() => {
10942 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
10943 /******/ })();
10944 /******/
10945 /******/ /* webpack/runtime/make namespace object */
10946 /******/ (() => {
10947 /******/ // define __esModule on exports
10948 /******/ __webpack_require__.r = (exports) => {
10949 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
10950 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
10951 /******/ }
10952 /******/ Object.defineProperty(exports, '__esModule', { value: true });
10953 /******/ };
10954 /******/ })();
10955 /******/
10956 /******/ /* webpack/runtime/nonce */
10957 /******/ (() => {
10958 /******/ __webpack_require__.nc = undefined;
10959 /******/ })();
10960 /******/
10961 /************************************************************************/
10962 var __webpack_exports__ = {};
10963 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
10964 (() => {
10965 "use strict";
10966 /*!************************************************!*\
10967 !*** ./assets/src/js/admin/edit-curriculum.js ***!
10968 \************************************************/
10969 __webpack_require__.r(__webpack_exports__);
10970 /* harmony import */ var _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./edit-curriculum/share.js */ "./assets/src/js/admin/edit-curriculum/share.js");
10971 /* harmony import */ var _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./edit-curriculum/edit-section.js */ "./assets/src/js/admin/edit-curriculum/edit-section.js");
10972 /* harmony import */ var _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit-curriculum/edit-section-item.js */ "./assets/src/js/admin/edit-curriculum/edit-section-item.js");
10973 /**
10974 * Edit Curriculum JS handler.
10975 *
10976 * @since 4.2.8.6
10977 * @version 1.0.1
10978 */
10979
10980
10981
10982
10983 const {
10984 className
10985 } = _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__;
10986
10987 // Toggle all sections
10988 const toggleSectionAll = (e, target) => {
10989 const elToggleAllSections = target.closest(`${className.elToggleAllSections}`);
10990 if (!elToggleAllSections) {
10991 return;
10992 }
10993 const elSections = _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.elEditCurriculum.querySelectorAll(`${className.elSection}:not(.clone)`);
10994 elToggleAllSections.classList.toggle(`${className.elCollapse}`);
10995 elSections.forEach(el => {
10996 const shouldCollapse = elToggleAllSections.classList.contains(`${className.elCollapse}`);
10997 el.classList.toggle(`${className.elCollapse}`, shouldCollapse);
10998 });
10999 };
11000
11001 // Update count items in each section and all sections
11002 const updateCountItems = elSection => {
11003 const elEditCurriculum = _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.elEditCurriculum;
11004 const elCountItemsAll = elEditCurriculum.querySelector('.total-items');
11005 const elItemsAll = elEditCurriculum.querySelectorAll(`${className.elSectionItem}:not(.clone)`);
11006 const itemsAllCount = elItemsAll.length;
11007 elCountItemsAll.dataset.count = itemsAllCount;
11008 elCountItemsAll.querySelector('.count').textContent = itemsAllCount;
11009
11010 // Count items in section
11011 const elSectionItemsCount = elSection.querySelector('.section-items-counts');
11012 const elItems = elSection.querySelectorAll(`${className.elSectionItem}:not(.clone)`);
11013 const itemsCount = elItems.length;
11014 elSectionItemsCount.dataset.count = itemsCount;
11015 elSectionItemsCount.querySelector('.count').textContent = itemsCount;
11016 // End count items in section
11017 };
11018
11019 // Events
11020 document.addEventListener('click', e => {
11021 const target = e.target;
11022
11023 /*** Event of Section ***/
11024 // Click button add new section
11025 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.addSection(e, target);
11026 // Click icon edit to focus section title input
11027 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.setFocusTitleInput(e, target);
11028 // Click toggle section
11029 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.toggleSection(e, target);
11030 // Click button to update section description
11031 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.updateSectionDescription(e, target);
11032 // Click button to cancel update section description
11033 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.cancelSectionDescription(e, target);
11034 // Click button delete section
11035 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.deleteSection(e, target);
11036 // Click button update section title
11037 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.updateSectionTitle(e, target);
11038 // Click button cancel update section title
11039 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.cancelSectionTitle(e, target);
11040 /*** End Event of Section ***/
11041
11042 /*** Event of Section Item ***/
11043 // Click button for item type to add a new item by type
11044 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.addItemType(e, target);
11045 // Click button to cancel adding item type
11046 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.cancelAddItemType(e, target);
11047 // Click button add to add item to section
11048 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.addItemToSection(e, target);
11049 // Click to show popup list of items to choose and add to section
11050 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.showPopupItemsToSelect(e, target);
11051 // Click to show list of items selected
11052 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.showItemsSelected(e, target);
11053 // Load items by type
11054 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.chooseTabItemsType(e, target);
11055 // Click button update to update item title
11056 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.updateTitle(e, target);
11057 // Click button cancel update item title
11058 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.cancelUpdateTitle(e, target);
11059 // Click icon delete item from section
11060 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.deleteItem(e, target);
11061 // Choose item to add to the list of items selected before adding to section
11062 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.selectItemsFromList(e, target);
11063 // Add items selected to section
11064 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.addItemsSelectedToSection(e, target);
11065 // CClick button to go back to the list of items
11066 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.backToSelectItems(e, target);
11067 // Click li item to remove item from selected list
11068 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.removeItemSelected(e, target);
11069 // Click icon eye to toggle preview item
11070 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.updatePreviewItem(e, target);
11071 /*** End Event of Section Item ***/
11072
11073 // Collapse/Expand all sections
11074 toggleSectionAll(e, target);
11075 });
11076 document.addEventListener('keydown', e => {
11077 const target = e.target;
11078 // Event enter
11079 if (e.key === 'Enter') {
11080 // Add new section
11081 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.addSection(e, target);
11082 // Update section title
11083 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.updateSectionTitle(e, target);
11084 // Update section description
11085 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.updateSectionDescription(e, target);
11086 // Add item to section
11087 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.addItemToSection(e, target);
11088 // Update item title
11089 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.updateTitle(e, target);
11090 }
11091 });
11092 document.addEventListener('keyup', e => {
11093 const target = e.target;
11094 // Typing change section title
11095 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.changeTitleBeforeAdd(e, target);
11096 // Typing section title
11097 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.changeTitle(e, target);
11098 // Typing section description
11099 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.changeDescription(e, target);
11100 // Typing item title
11101 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.changeTitle(e, target);
11102 // Typing item title to add new item
11103 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.changeTitleAddNew(e, target);
11104 // Typing search title item to select
11105 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.searchTitleItemToSelect(e, target);
11106 });
11107 // Event focus in
11108 document.addEventListener('focusin', e => {
11109 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.focusTitleNewInput(e, e.target);
11110 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.focusTitleInput(e, e.target);
11111 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.focusTitleInput(e, e.target);
11112 });
11113 // Event focus out
11114 document.addEventListener('focusout', e => {
11115 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.focusTitleNewInput(e, e.target, false);
11116 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.focusTitleInput(e, e.target, false);
11117 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.focusTitleInput(e, e.target, false);
11118 });
11119 // Check if it has change when close tab or refresh page
11120 window.addEventListener('beforeunload', function (e) {
11121 if (Object.keys(_edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.hasChange).length === 0) {
11122 return;
11123 }
11124 e.preventDefault();
11125 e.returnValue = '';
11126 });
11127
11128 // Element root ready.
11129 _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.lpUtils.lpOnElementReady(`${className.idElEditCurriculum}`, elEditCurriculum => {
11130 const elCurriculumSections = elEditCurriculum.querySelector(`${className.elCurriculumSections}`);
11131 const elLPTarget = elEditCurriculum.closest(`${className.LPTarget}`);
11132 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
11133 _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.setVariables({
11134 courseId: dataSend.args.course_id,
11135 elEditCurriculum,
11136 elCurriculumSections,
11137 elLPTarget,
11138 updateCountItems,
11139 hasChange: {}
11140 });
11141
11142 // Set variables use for section edit
11143 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.init();
11144 _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_1__.sortAbleSection();
11145
11146 // Set variables use for edit section item
11147 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.init();
11148 _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.sortAbleItem();
11149 // Share sortAbleItem function, for when create new section, will call this function to sort items in section.
11150 _edit_curriculum_share_js__WEBPACK_IMPORTED_MODULE_0__.setVariable('sortAbleItem', _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_2__.sortAbleItem);
11151 });
11152 })();
11153
11154 /******/ })()
11155 ;
11156 //# sourceMappingURL=edit-curriculum.js.map