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

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

11,937 lines 429.2 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-question.js"
5 /*!**********************************************!*\
6 !*** ./assets/src/js/admin/edit-question.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 */ EditQuestion: () => (/* binding */ EditQuestion)
14 /* harmony export */ });
15 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
16 /* harmony import */ var lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify */ "./assets/src/js/lpToastify.js");
17 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
18 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
19 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
20 /**
21 * Edit question JS handler.
22 *
23 * @since 4.2.9
24 * @version 1.0.0
25 */
26
27
28
29
30
31 const idUrlHandle = 'edit-question';
32 let fibSelection;
33 let timeoutAutoUpdateAnswer, timeoutAutoUpdateFib, timeoutAutoUpdateQuestion;
34
35 // EditQuestion class
36 class EditQuestion {
37 static selectors = {
38 elEditQuestionWrap: '.lp-edit-question-wrap',
39 elQuestionEditMain: '.lp-question-edit-main',
40 elQuestionToggleAll: '.lp-question-toggle-all',
41 elEditListQuestions: '.lp-edit-list-questions',
42 elQuestionToggle: '.lp-question-toggle',
43 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
44 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
45 elBtnAddQuestion: '.lp-btn-add-question',
46 elBtnRemoveQuestion: '.lp-btn-remove-question',
47 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
48 elBtnUpdateQuestionDes: '.lp-btn-update-question-des',
49 elBtnUpdateQuestionHint: '.lp-btn-update-question-hint',
50 elBtnUpdateQuestionExplain: '.lp-btn-update-question-explanation',
51 elQuestionTitleNewInput: '.lp-question-title-new-input',
52 elQuestionTitleInput: '.lp-question-title-input',
53 elQuestionTypeLabel: '.lp-question-type-label',
54 elQuestionTypeNew: '.lp-question-type-new',
55 elAddNewQuestion: 'add-new-question',
56 elQuestionClone: '.lp-question-item.clone',
57 elAnswersConfig: '.lp-answers-config',
58 elBtnAddAnswer: '.lp-btn-add-question-answer',
59 elQuestionAnswerItemAddNew: '.lp-question-answer-item-add-new',
60 elQuestionAnswerTitleNewInput: '.lp-question-answer-title-new-input',
61 elQuestionAnswerTitleInput: '.lp-question-answer-title-input',
62 elBtnDeleteAnswer: '.lp-btn-delete-question-answer',
63 elQuestionByType: '.lp-question-by-type',
64 elInputAnswerSetTrue: '.lp-input-answer-set-true',
65 elQuestionAnswerItem: '.lp-question-answer-item',
66 elBtnUpdateQuestionAnswer: '.lp-btn-update-question-answer',
67 elBtnFibInsertBlank: '.lp-btn-fib-insert-blank',
68 elBtnFibDeleteAllBlanks: '.lp-btn-fib-delete-all-blanks',
69 elBtnFibSaveContent: '.lp-btn-fib-save-content',
70 elBtnFibClearAllContent: '.lp-btn-fib-clear-all-content',
71 elFibOptionTitleInput: '.lp-question-fib-option-title-input',
72 elFibBlankOptions: '.lp-question-fib-blank-options',
73 elFibBlankOptionItem: '.lp-question-fib-blank-option-item',
74 elFibBlankOptionItemClone: '.lp-question-fib-blank-option-item.clone',
75 elFibBlankOptionIndex: '.lp-question-fib-option-index',
76 elBtnFibOptionDelete: '.lp-btn-fib-option-delete',
77 elFibOptionMatchCaseWrap: '.lp-question-fib-option-match-case-wrap',
78 elFibOptionMatchCaseInput: '.lp-question-fib-option-match-case-input',
79 elQuestionFibOptionDetail: '.lp-question-fib-option-detail',
80 elFibOptionComparisonInput: '.lp-question-fib-option-comparison-input',
81 elAutoSaveFib: '.lp-auto-save-fib',
82 LPTarget: '.lp-target',
83 elCollapse: 'lp-collapse',
84 elSectionToggle: '.lp-section-toggle',
85 elTriggerToggle: '.lp-trigger-toggle',
86 elAutoSaveQuestion: '.lp-auto-save-question',
87 elAutoSaveAnswer: '.lp-auto-save-question-answer',
88 elQuestionFibInput: 'lp-question-fib-input',
89 elBtnQuestionCreateType: '.lp-btn-question-create-type'
90 };
91 constructor() {}
92 init() {
93 this.events();
94 this.initTinyMCE().then();
95 }
96 events() {
97 if (EditQuestion._loadedEvents) {
98 return;
99 }
100 EditQuestion._loadedEvents = true;
101
102 // Sortable answers's question
103 const elQuestionEditMains = document.querySelectorAll(`${EditQuestion.selectors.elQuestionEditMain}`);
104 elQuestionEditMains.forEach(elQuestionEditMain => {
105 this.sortAbleQuestionAnswer(elQuestionEditMain);
106 });
107 // End sortable
108
109 // Event click
110 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
111 selector: EditQuestion.selectors.elBtnQuestionCreateType,
112 callBack: this.createQuestionType.name,
113 class: this
114 }, {
115 selector: EditQuestion.selectors.elBtnAddAnswer,
116 callBack: this.addQuestionAnswer.name,
117 class: this
118 }, {
119 selector: EditQuestion.selectors.elBtnDeleteAnswer,
120 callBack: this.deleteQuestionAnswer.name,
121 class: this
122 }, {
123 selector: EditQuestion.selectors.elBtnFibInsertBlank,
124 callBack: this.fibInsertBlank.name,
125 class: this
126 }, {
127 selector: EditQuestion.selectors.elBtnFibDeleteAllBlanks,
128 callBack: this.fibDeleteAllBlanks.name,
129 class: this
130 }, {
131 selector: EditQuestion.selectors.elBtnFibSaveContent,
132 callBack: this.fibSaveContent.name,
133 class: this
134 }, {
135 selector: EditQuestion.selectors.elBtnFibClearAllContent,
136 callBack: this.fibClearContent.name,
137 class: this
138 }, {
139 selector: EditQuestion.selectors.elBtnFibOptionDelete,
140 callBack: this.fibDeleteBlank.name,
141 class: this
142 }, {
143 selector: EditQuestion.selectors.elFibOptionMatchCaseInput,
144 callBack: this.fibShowHideMatchCaseOption.name,
145 class: this
146 }, {
147 selector: EditQuestion.selectors.elFibOptionComparisonInput,
148 callBack: args => {
149 const {
150 e,
151 target
152 } = args;
153 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
154 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
155 elBtnFibSaveContent.click();
156 }
157 }]);
158
159 // Toggle collapse
160 document.addEventListener('click', e => {
161 const target = e.target;
162 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuestion.selectors.elTriggerToggle);
163 });
164
165 // Event keyup
166 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
167 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
168 callBack: this.checkCanAddAnswer.name,
169 class: this
170 }, {
171 selector: EditQuestion.selectors.elFibOptionTitleInput,
172 callBack: this.fibOptionTitleInputChange.name,
173 class: this
174 }, {
175 selector: EditQuestion.selectors.elAutoSaveQuestion,
176 callBack: this.autoUpdateQuestion.name,
177 class: this
178 }]);
179
180 // Event keydown
181 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
182 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
183 callBack: this.addQuestionAnswer.name,
184 class: this,
185 checkIsEventEnter: true
186 }]);
187
188 // Event change
189 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
190 selector: EditQuestion.selectors.elAutoSaveAnswer,
191 callBack: this.autoUpdateAnswer.name,
192 class: this
193 }]);
194
195 // TinyMCE events
196 this.eventEditorTinymce();
197 }
198
199 // Run async to re-init all TinyMCE editors, because it slow if have many editors
200 async initTinyMCE() {
201 const elTextareas = document.querySelectorAll('.lp-editor-tinymce');
202 elTextareas.forEach(elTextarea => {
203 const idTextarea = elTextarea.id;
204 this.reInitTinymce(idTextarea);
205 });
206 }
207 reInitTinymce(id) {
208 window.tinymce.execCommand('mceRemoveEditor', true, id);
209 window.tinymce.execCommand('mceAddEditor', true, id);
210 }
211 reInitQuickTags(id) {
212 const toolbar = document.getElementById(`qt_${id}_toolbar`);
213 if (!toolbar || toolbar.children.length || !window.quicktags) {
214 return;
215 }
216 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
217 id
218 };
219 window.quicktags(settings);
220 if (window.QTags?._buttonsInit) {
221 window.QTags._buttonsInit();
222 }
223 }
224 setDefaultEditorTab(id) {
225 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
226 if (!wrapEditor) {
227 return;
228 }
229 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
230 window.switchEditors.go(id, 'tmce');
231 const elTextarea = document.getElementById(id);
232 if (elTextarea) {
233 elTextarea.style.visibility = '';
234 }
235 }
236 wrapEditor.classList.add('tmce-active');
237 wrapEditor.classList.remove('html-active');
238 const visualTab = document.getElementById(`${id}-tmce`);
239 const codeTab = document.getElementById(`${id}-html`);
240 visualTab?.setAttribute('aria-pressed', 'true');
241 codeTab?.setAttribute('aria-pressed', 'false');
242 }
243
244 // Events for TinyMCE editor
245 eventEditorTinymce() {
246 window.tinymce.on('AddEditor', eEditor => {
247 const id = eEditor.editor.id;
248 const editor = window.tinymce.get(id);
249 if (!editor) {
250 return;
251 }
252 if (id === 'content') {
253 return;
254 }
255 const elTextarea = document.getElementById(id);
256 if (!elTextarea) {
257 return;
258 }
259 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
260
261 // Skip if not in question edit context
262 if (!elQuestionEditMain) {
263 return;
264 }
265 const questionId = elQuestionEditMain.dataset.questionId;
266 editor.settings.force_p_newlines = false;
267 editor.settings.forced_root_block = '';
268 editor.settings.force_br_newlines = true;
269
270 // Config use absolute url
271 editor.settings.relative_urls = false;
272 editor.settings.remove_script_host = false;
273 editor.settings.convert_urls = true;
274 editor.settings.document_base_url = lpData.site_url;
275 // End config use absolute url
276
277 // Add quick tags
278 this.reInitQuickTags(id);
279
280 // Events focus in TinyMCE editor
281 editor.on('change keyup', e => {
282 // Auto save if it has class lp-auto-save
283 elTextarea.value = editor.getContent();
284 this.autoUpdateQuestion({
285 e,
286 target: elTextarea
287 });
288 });
289 editor.on('blur', e => {
290 //console.log( 'Editor blurred:', e.target.id );
291 });
292 editor.on('focusin', e => {});
293 editor.on('init', () => {
294 // Add style
295 editor.dom.addStyle(`
296 body {
297 line-height: 2.2 !important;
298 }
299 .${EditQuestion.selectors.elQuestionFibInput} {
300 border: 1px dashed rebeccapurple;
301 padding: 5px;
302 }
303 `);
304
305 // Set default tab visual
306 this.setDefaultEditorTab(id);
307 });
308 editor.on('setcontent', e => {
309 const uniquid = this.randomString();
310 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
311 if (elementg[0]) {
312 elementg[0].focus();
313 }
314 editor.dom.bind(elementg[0], 'input', e => {
315 //console.log( 'Input changed:', e.target.value );
316 });
317 });
318 editor.on('selectionchange', e => {
319 fibSelection = editor.selection;
320
321 // Check selection is blank, check empty blank content
322 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
323 const blankId = fibSelection.getNode().dataset.id;
324 const textBlank = fibSelection.getNode().textContent.trim();
325 if (textBlank.length === 0) {
326 const editorId = editor.id;
327 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
328 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
329 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
330 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
331 if (elFibBlankOptionItem) {
332 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
333 }
334 } else {
335 const elTextarea = document.getElementById(id);
336 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
337 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
338 if (elFibBlankOptionItem) {
339 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
340 if (elFibOptionTitleInput) {
341 elFibOptionTitleInput.value = textBlank;
342 }
343 }
344 }
345 }
346 });
347 editor.on('Undo', e => {
348 const contentUndo = editor.getContent();
349 const selection = editor.selection;
350 const nodeUndo = selection.getNode();
351 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
352 const blankId = nodeUndo.dataset.id;
353 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
354 if (elFibBlankOptionItem) {
355 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
356 }
357 }
358 });
359 editor.on('Redo', e => {});
360 });
361 }
362 autoUpdateQuestion(args) {
363 let {
364 e,
365 target,
366 key,
367 value
368 } = args;
369 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
370 if (!elAutoSave) {
371 return;
372 }
373 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
374 const questionId = elQuestionEditMain.dataset.questionId;
375 clearTimeout(timeoutAutoUpdateQuestion);
376 timeoutAutoUpdateQuestion = setTimeout(() => {
377 // Call ajax to update question description
378 const callBack = {
379 success: response => {
380 const {
381 message,
382 status
383 } = response;
384 if (status === 'success') {
385 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
386 } else {
387 throw `Error: ${message}`;
388 }
389 },
390 error: error => {
391 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
392 },
393 completed: () => {}
394 };
395 const dataSend = {
396 action: 'update_question',
397 question_id: questionId,
398 args: {
399 id_url: idUrlHandle
400 }
401 };
402 if (undefined === key) {
403 key = elAutoSave.dataset.keyAutoSave;
404 if (!key) {
405 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
406 return;
407 }
408 const textAreaId = elAutoSave.id;
409 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
410 if (!key) {
411 return;
412 }
413 }
414 value = elAutoSave.value;
415 }
416 dataSend[key] = value;
417 window.lpAJAXG.fetchAJAX(dataSend, callBack);
418 }, 700);
419 }
420 // Create question type
421 createQuestionType(args) {
422 const {
423 e,
424 target
425 } = args;
426 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
427 if (!elBtnQuestionCreateType) {
428 return;
429 }
430 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
431 if (!elQuestionEditMain) {
432 return;
433 }
434 const questionId = elQuestionEditMain.dataset.questionId;
435 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
436 if (!elQuestionTypeNew) {
437 return;
438 }
439 const questionType = elQuestionTypeNew.value.trim();
440 if (!questionType) {
441 const message = elQuestionTypeNew.dataset.messEmptyType;
442 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
443 return;
444 }
445
446 // Call ajax to create new question type
447 const callBack = {
448 success: response => {
449 const {
450 message,
451 status,
452 data
453 } = response;
454 if (status === 'success') {
455 const {
456 html_option_answers
457 } = data;
458 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
459 elAnswersConfig.outerHTML = html_option_answers;
460 this.initTinyMCE();
461 this.sortAbleQuestionAnswer(elQuestionEditMain);
462 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
463 } else {
464 throw `Error: ${message}`;
465 }
466 },
467 error: error => {
468 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
469 },
470 completed: () => {}
471 };
472 const dataSend = {
473 action: 'update_question',
474 question_id: questionId,
475 question_type: questionType,
476 args: {
477 id_url: idUrlHandle
478 }
479 };
480 window.lpAJAXG.fetchAJAX(dataSend, callBack);
481 }
482 addQuestionAnswer(args) {
483 const {
484 e,
485 target
486 } = args;
487 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
488 if (!elQuestionAnswerItemAddNew) {
489 return;
490 }
491 e.preventDefault();
492 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
493 if (!elQuestionAnswerTitleNewInput.value.trim()) {
494 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
495 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
496 return;
497 }
498 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
499 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
500 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
501 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
502 elQuestionAnswerNew.classList.remove('clone');
503 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
504 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
505 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
506 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
507 elQuestionAnswerTitleInputNew.value = answerTitle;
508 elQuestionAnswerTitleNewInput.value = '';
509 const questionId = elQuestionEditMain.dataset.questionId;
510
511 // Call ajax to add new question answer
512 const callBack = {
513 success: response => {
514 const {
515 message,
516 status,
517 data
518 } = response;
519 if (status === 'success') {
520 const {
521 question_answer
522 } = data;
523 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
524 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
525
526 // Set data lp-answers-config
527 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
528 dataAnswers.push(question_answer);
529 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
530 } else {
531 throw `Error: ${message}`;
532 }
533 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
534 },
535 error: error => {
536 elQuestionAnswerNew.remove();
537 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
538 },
539 completed: () => {}
540 };
541 const dataSend = {
542 action: 'add_question_answer',
543 question_id: questionId,
544 answer_title: answerTitle,
545 args: {
546 id_url: idUrlHandle
547 }
548 };
549 window.lpAJAXG.fetchAJAX(dataSend, callBack);
550 }
551
552 // Check to enable or disable add new question button
553 checkCanAddAnswer(args) {
554 const {
555 e,
556 target
557 } = args;
558 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
559 if (!elTrigger) {
560 return;
561 }
562 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
563 if (!elQuestionAnswerItemAddNew) {
564 return;
565 }
566 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
567 if (!elBtnAddAnswer) {
568 return;
569 }
570 const titleValue = elTrigger.value.trim();
571 if (titleValue) {
572 elBtnAddAnswer.classList.add('active');
573 } else {
574 elBtnAddAnswer.classList.remove('active');
575 }
576 }
577
578 // Auto update question answer
579 autoUpdateAnswer(args) {
580 const {
581 e,
582 target
583 } = args;
584 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
585 if (!elAutoSaveAnswer) {
586 return;
587 }
588 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
589 clearTimeout(timeoutAutoUpdateAnswer);
590 timeoutAutoUpdateAnswer = setTimeout(() => {
591 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
592 const questionId = elQuestionEditMain.dataset.questionId;
593 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
594 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
595
596 // For both radio and checkbox.
597 const dataAnswersOld = structuredClone(dataAnswers);
598
599 // Get position of answers
600 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
601 const answersPosition = {};
602 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
603 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
604 });
605
606 //console.log( 'answersPosition', answersPosition );
607
608 dataAnswers.map((answer, k) => {
609 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
610 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
611 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
612
613 // Set title
614 if (elInputAnswerTitle) {
615 answer.title = elInputAnswerTitle.value.trim();
616 }
617
618 // Set true answer
619 if (elInputAnswerSetTrue) {
620 if (elInputAnswerSetTrue.checked) {
621 answer.is_true = 'yes';
622 } else {
623 answer.is_true = '';
624 }
625 }
626
627 // Set position
628 if (answersPosition[answer.question_answer_id]) {
629 answer.order = answersPosition[answer.question_answer_id];
630 }
631 return answer;
632 });
633
634 //console.log( dataAnswers );
635
636 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
637
638 // Call ajax to update answers config
639 const callBack = {
640 success: response => {
641 const {
642 message,
643 status
644 } = response;
645 if (status === 'success') {} else {
646 throw `Error: ${message}`;
647 }
648 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
649 },
650 error: error => {
651 // rollback changes to old data
652 dataAnswersOld.forEach(answer => {
653 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
654 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
655 if (answer.is_true === 'yes') {
656 inputAnswerSetTrue.checked = true;
657 }
658 return answer;
659 });
660 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
661 },
662 completed: () => {
663 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
664 }
665 };
666 const dataSend = {
667 action: 'update_question_answers_config',
668 question_id: questionId,
669 answers: dataAnswers,
670 args: {
671 id_url: idUrlHandle
672 }
673 };
674 window.lpAJAXG.fetchAJAX(dataSend, callBack);
675 }, 700);
676 }
677
678 // Sortable answers's question
679 sortAbleQuestionAnswer(elQuestionEditMain) {
680 let isUpdateSectionPosition = 0;
681 let timeout;
682 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
683 elQuestionAnswers.forEach(elAnswersConfig => {
684 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
685 handle: '.drag',
686 animation: 150,
687 onEnd: evt => {
688 const elQuestionAnswerItem = evt.item;
689 if (!isUpdateSectionPosition) {
690 // No change in section position, do nothing
691 return;
692 }
693 clearTimeout(timeout);
694 timeout = setTimeout(() => {
695 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
696 this.autoUpdateAnswer({
697 e: null,
698 target: elAutoSaveAnswer
699 });
700 }, 1000);
701 },
702 onMove: evt => {
703 clearTimeout(timeout);
704 },
705 onUpdate: evt => {
706 isUpdateSectionPosition = 1;
707 }
708 });
709 });
710 }
711
712 // Delete question answer
713 deleteQuestionAnswer(args) {
714 const {
715 e,
716 target
717 } = args;
718 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
719 if (!elBtnDeleteAnswer) {
720 return;
721 }
722 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
723 if (!elQuestionAnswerItem) {
724 return;
725 }
726 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
727 const questionId = elQuestionEditMain.dataset.questionId;
728 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
729 if (!questionId || !questionAnswerId) {
730 return;
731 }
732 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
733 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
734 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
735 icon: 'warning',
736 showCloseButton: true,
737 showCancelButton: true,
738 cancelButtonText: lpData.i18n.cancel,
739 confirmButtonText: lpData.i18n.yes,
740 reverseButtons: true
741 }).then(result => {
742 if (result.isConfirmed) {
743 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
744
745 // Call ajax to delete item from section
746 const callBack = {
747 success: response => {
748 const {
749 message,
750 status
751 } = response;
752 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
753 if (status === 'success') {
754 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
755 elQuestionAnswerItem.remove();
756 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
757 if (dataAnswers) {
758 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
759 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
760 }
761 }
762 },
763 error: error => {
764 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
765 },
766 completed: () => {
767 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
768 }
769 };
770 const dataSend = {
771 action: 'delete_question_answer',
772 question_id: questionId,
773 question_answer_id: questionAnswerId,
774 args: {
775 id_url: idUrlHandle
776 }
777 };
778 window.lpAJAXG.fetchAJAX(dataSend, callBack);
779 }
780 });
781 }
782
783 // Get data answers config
784 getDataAnswersConfig(elQuestionEditMain) {
785 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
786 if (!elAnswersConfig) {
787 return null;
788 }
789 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
790 try {
791 dataAnswers = JSON.parse(dataAnswers);
792 } catch (e) {
793 dataAnswers = [];
794 }
795 if (!dataAnswers.meta_data) {
796 dataAnswers.meta_data = {};
797 }
798 return dataAnswers;
799 }
800
801 // Set data answers config
802 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
803 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
804 if (!elAnswersConfig) {
805 return;
806 }
807 if (!dataAnswers || typeof dataAnswers !== 'object') {
808 dataAnswers = {};
809 }
810 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
811 }
812
813 /***** Fill in the blank question type *****/
814 // For FIB question type
815 fibInsertBlank = args => {
816 const {
817 e,
818 target
819 } = args;
820 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
821 if (!elBtnFibInsertBlank) {
822 return;
823 }
824 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
825 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
826 const questionId = elQuestionEditMain.dataset.questionId;
827 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
828 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
829 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
830 const uniquid = this.randomString();
831 let selectedText;
832 if (fibSelection) {
833 const elNode = fibSelection.getNode();
834 if (!elNode) {
835 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
836 return;
837 }
838 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
839 if (!findParent) {
840 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
841 return;
842 }
843 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
844 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
845 return;
846 }
847 selectedText = fibSelection.getContent();
848 if (selectedText.length === 0) {
849 selectedText = textPlaceholder;
850 }
851 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
852 fibSelection.setContent(elInputNew);
853 } else {
854 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
855 return;
856 }
857 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
858 dataAnswers.meta_data = dataAnswers.meta_data || {};
859 // Convert array to object
860 if (Object.keys(dataAnswers.meta_data).length === 0) {
861 dataAnswers.meta_data = {};
862 }
863 dataAnswers.meta_data[uniquid] = {
864 id: uniquid,
865 match_case: 0,
866 comparison: 'equal',
867 fill: selectedText,
868 index: 1,
869 open: false
870 };
871 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
872
873 // Clone blank options
874 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
875 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
876 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
877 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
878 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
879 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
880 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
881 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
882 elFibBlankOptionItemNew.dataset.id = uniquid;
883 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
884 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
885 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
886 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
887 elFibOptionComparisonInput.forEach(elInput => {
888 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
889 if (elInput.value === 'equal') {
890 elInput.checked = true;
891 }
892 });
893 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
894 elFibBlankOptionItemNew.classList.remove('clone');
895 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
896 // End clone blank options
897
898 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
899 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
900 this.fibSaveContent({
901 e: null,
902 target: elBtnFibSaveContent,
903 callBackCompleted: () => {
904 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
905 }
906 });
907 };
908
909 // Delete all blanks
910 fibDeleteAllBlanks(args) {
911 const {
912 e,
913 target
914 } = args;
915 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
916 if (!elBtnFibDeleteAllBlanks) {
917 return;
918 }
919 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
920 if (!elQuestionEditMain) {
921 return;
922 }
923 const questionId = elQuestionEditMain.dataset.questionId;
924 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
925 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
926 title: elBtnFibDeleteAllBlanks.dataset.title,
927 text: elBtnFibDeleteAllBlanks.dataset.content,
928 icon: 'warning',
929 showCloseButton: true,
930 showCancelButton: true,
931 cancelButtonText: lpData.i18n.cancel,
932 confirmButtonText: lpData.i18n.yes,
933 reverseButtons: true
934 }).then(result => {
935 if (result.isConfirmed) {
936 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
937 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
938 elBlanks.forEach(elBlank => {
939 editor.dom.remove(elBlank, true);
940 });
941 dataAnswers.meta_data = {};
942 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
943 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
944 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
945 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
946 elFibBlankOptionItem.remove();
947 });
948 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
949 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
950 this.fibSaveContent({
951 e: null,
952 target: elBtnFibSaveContent,
953 callBackCompleted: () => {
954 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
955 }
956 });
957 }
958 });
959 }
960 // Clear content FIB question
961 fibClearContent(args) {
962 const {
963 e,
964 target
965 } = args;
966 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
967 if (!elBtnFibClearAllContent) {
968 return;
969 }
970 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
971 if (!elQuestionEditMain) {
972 return;
973 }
974 const questionId = elQuestionEditMain.dataset.questionId;
975 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
976 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
977 title: elBtnFibClearAllContent.dataset.title,
978 text: elBtnFibClearAllContent.dataset.content,
979 icon: 'warning',
980 showCloseButton: true,
981 showCancelButton: true,
982 cancelButtonText: lpData.i18n.cancel,
983 confirmButtonText: lpData.i18n.yes,
984 reverseButtons: true
985 }).then(result => {
986 if (result.isConfirmed) {
987 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
988 editor.setContent('');
989 dataAnswers.meta_data = {};
990 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
991 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
992 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
993 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
994 elFibBlankOptionItem.remove();
995 });
996 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
997 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
998 this.fibSaveContent({
999 e: null,
1000 target: elBtnFibSaveContent,
1001 callBackCompleted: () => {
1002 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
1003 }
1004 });
1005 }
1006 });
1007 }
1008
1009 // Remove blank
1010 fibDeleteBlank(args) {
1011 const {
1012 e,
1013 target
1014 } = args;
1015 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
1016 if (!elBtnFibOptionDelete) {
1017 return;
1018 }
1019 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1020 if (!elQuestionEditMain) {
1021 return;
1022 }
1023 const questionId = elQuestionEditMain.dataset.questionId;
1024 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
1025 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1026 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1027 const blankId = elFibBlankOptionItem.dataset.id;
1028 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1029 title: elBtnFibOptionDelete.dataset.title,
1030 text: elBtnFibOptionDelete.dataset.content,
1031 icon: 'warning',
1032 showCloseButton: true,
1033 showCancelButton: true,
1034 cancelButtonText: lpData.i18n.cancel,
1035 confirmButtonText: lpData.i18n.yes,
1036 reverseButtons: true
1037 }).then(result => {
1038 if (result.isConfirmed) {
1039 // Find span with id on editor and remove it
1040 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1041 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
1042 if (elBlank[0]) {
1043 // Remove tag html but keep content
1044 editor.dom.remove(elBlank[0], true);
1045 }
1046 elFibBlankOptionItem.remove();
1047 dataAnswers.meta_data = dataAnswers.meta_data || {};
1048 if (dataAnswers.meta_data[blankId]) {
1049 delete dataAnswers.meta_data[blankId];
1050 }
1051 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1052 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1053 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
1054 this.fibSaveContent({
1055 e: null,
1056 target: elBtnFibSaveContent,
1057 callBackCompleted: () => {
1058 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
1059 }
1060 });
1061 }
1062 });
1063 }
1064
1065 // Change title of blank option
1066 fibOptionTitleInputChange(args) {
1067 const {
1068 e,
1069 target
1070 } = args;
1071 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
1072 if (!elFibOptionTitleInput) {
1073 return;
1074 }
1075 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1076 if (!elQuestionFibOptionItem) {
1077 return;
1078 }
1079 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1080 if (!elQuestionEditMain) {
1081 return;
1082 }
1083 const value = elFibOptionTitleInput.value.trim();
1084 const blankId = elQuestionFibOptionItem.dataset.id;
1085 const questionId = elQuestionEditMain.dataset.questionId;
1086 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
1087 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
1088 if (elBlank[0]) {
1089 // Update content of blank
1090 elBlank[0].textContent = value;
1091 }
1092 clearTimeout(timeoutAutoUpdateFib);
1093 timeoutAutoUpdateFib = setTimeout(() => {
1094 // Call ajax to update question description
1095 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1096 this.fibSaveContent({
1097 e: null,
1098 target: elBtnFibSaveContent
1099 });
1100 }, 700);
1101 }
1102
1103 // Save content FIB question
1104 fibSaveContent(args) {
1105 const {
1106 e,
1107 target,
1108 callBackCompleted = null
1109 } = args;
1110 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1111 if (!elBtnFibSaveContent) {
1112 return;
1113 }
1114 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1115 const questionId = elQuestionEditMain.dataset.questionId;
1116 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1117 if (!dataAnswers) {
1118 return;
1119 }
1120 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1121 dataAnswers.title = editor.getContent();
1122 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
1123 if (elFibBlankOptionItems) {
1124 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
1125 const blankId = elFibBlankOptionItem.dataset.id;
1126 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1127 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
1128 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
1129 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
1130 });
1131 }
1132
1133 //console.log( 'dataAnswers', dataAnswers );
1134
1135 if (!callBackCompleted) {
1136 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
1137 }
1138
1139 // Call ajax to update answers config
1140 const callBack = {
1141 success: response => {
1142 const {
1143 message,
1144 status
1145 } = response;
1146 if (status === 'success') {
1147 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1148 } else {
1149 throw `Error: ${message}`;
1150 }
1151 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
1152 },
1153 error: error => {
1154 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1155 },
1156 completed: () => {
1157 if (callBackCompleted && typeof callBackCompleted === 'function') {
1158 callBackCompleted();
1159 } else {
1160 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
1161 }
1162 }
1163 };
1164
1165 //console.log( 'dataAnswers', dataAnswers );
1166
1167 const dataSend = {
1168 action: 'update_question_answers_config',
1169 question_id: questionId,
1170 answers: dataAnswers,
1171 args: {
1172 id_url: idUrlHandle
1173 }
1174 };
1175 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1176 }
1177 // Show/hide match case option
1178 fibShowHideMatchCaseOption(args) {
1179 const {
1180 e,
1181 target
1182 } = args;
1183 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1184 if (!elFibOptionMatchCaseInput) {
1185 return;
1186 }
1187 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
1188 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
1189 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
1190 return;
1191 }
1192 if (elFibOptionMatchCaseInput.checked) {
1193 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
1194 } else {
1195 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
1196 }
1197 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1198 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1199 elBtnFibSaveContent.click();
1200 }
1201 /***** End Fill in the blank question type *****/
1202
1203 // Generate a random string of specified length, for set unique id
1204 randomString(length = 10) {
1205 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
1206 let result = '';
1207 for (let i = 0; i < length; i++) {
1208 result += chars.charAt(Math.floor(Math.random() * chars.length));
1209 }
1210 return result;
1211 }
1212 // Decode HTML entities
1213 decodeHtml(html) {
1214 const txt = document.createElement('textarea');
1215 txt.innerHTML = html;
1216 return txt.value;
1217 }
1218 }
1219 const editQuestion = new EditQuestion();
1220 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
1221 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
1222 if (!elEditQuestionWrap.classList.contains(findClass)) {
1223 return;
1224 }
1225 editQuestion.init();
1226 });
1227
1228 /***/ },
1229
1230 /***/ "./assets/src/js/lpPopupSelectItemToAdd.js"
1231 /*!*************************************************!*\
1232 !*** ./assets/src/js/lpPopupSelectItemToAdd.js ***!
1233 \*************************************************/
1234 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1235
1236 "use strict";
1237 __webpack_require__.r(__webpack_exports__);
1238 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1239 /* harmony export */ LpPopupSelectItemToAdd: () => (/* binding */ LpPopupSelectItemToAdd)
1240 /* harmony export */ });
1241 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
1242 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1243 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1244 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
1245 /**
1246 * LearnPress Popup Select Item
1247 *
1248 * Handles load(search) item from API, show in popup and select item.
1249 */
1250
1251
1252
1253
1254 let itemsSelectedData = [];
1255 let elPopup;
1256 let timeSearchTitleItem;
1257 class LpPopupSelectItemToAdd {
1258 constructor() {
1259 this.init();
1260 }
1261 static selectors = {
1262 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
1263 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
1264 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
1265 elHeaderCountItemSelected: '.header-count-items-selected',
1266 elSelectItem: '.lp-select-item',
1267 elListItems: '.list-items',
1268 elPopupItemsToSelect: '.lp-popup-items-to-select',
1269 elSearchTitleItem: '.lp-search-title-item',
1270 elBtnBackListItems: '.lp-btn-back-to-select-items',
1271 elListItemsWrap: '.list-items-wrap',
1272 elListItemsSelected: '.list-items-selected',
1273 elItemSelectedClone: '.li-item-selected.clone',
1274 elItemSelected: '.li-item-selected',
1275 LPTarget: '.lp-target'
1276 };
1277 init() {
1278 this.events();
1279 }
1280 events = () => {
1281 if (LpPopupSelectItemToAdd._loadedEvents) {
1282 return;
1283 }
1284 LpPopupSelectItemToAdd._loadedEvents = true;
1285 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
1286 selector: LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
1287 callBack: this.showPopupItemsToSelect.name,
1288 class: this
1289 }, {
1290 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
1291 callBack: this.selectItemsFromList.name,
1292 class: this
1293 }, {
1294 selector: LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
1295 callBack: this.showItemsSelected.name,
1296 class: this
1297 }, {
1298 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
1299 callBack: this.backToSelectItems.name,
1300 class: this
1301 }, {
1302 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
1303 callBack: this.removeItemSelected.name,
1304 class: this
1305 }, {
1306 selector: '.tabs .tab',
1307 callBack: this.chooseTabItemsType.name,
1308 class: this
1309 }]);
1310 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
1311 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
1312 callBack: this.searchTitleItemToSelect.name,
1313 class: this
1314 }]);
1315 };
1316
1317 // Show popup items to select
1318 showPopupItemsToSelect = args => {
1319 const {
1320 e,
1321 target = false,
1322 callBack
1323 } = args;
1324 const elBtnShowPopupItemsToSelect = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect}`);
1325 if (!elBtnShowPopupItemsToSelect) {
1326 return;
1327 }
1328
1329 // Reset items selected data when opening popup
1330 itemsSelectedData = [];
1331 const templateId = target.dataset.template || '';
1332 const modalTemplate = document.querySelector(templateId);
1333 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1334 html: modalTemplate.innerHTML,
1335 showConfirmButton: false,
1336 showCloseButton: true,
1337 width: '60%',
1338 customClass: {
1339 popup: 'lp-select-items-popup',
1340 htmlContainer: 'lp-select-items-html-container',
1341 container: 'lp-select-items-container'
1342 },
1343 willOpen: () => {
1344 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
1345 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1346 if (elLPTarget) {
1347 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1348 dataSend.args.paged = 1;
1349 dataSend.args.item_selecting = itemsSelectedData || [];
1350 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
1351 window.lpAJAXG.fetchAJAX(dataSend, {
1352 success: response => {
1353 const {
1354 data
1355 } = response;
1356 const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
1357 elSkeleton.remove();
1358 elLPTarget.innerHTML = data.content || '';
1359 this.watchItemsSelectedDataChange();
1360 }
1361 });
1362 }
1363 }
1364 }).then(result => {
1365 if (result.isDismissed) {}
1366 });
1367 };
1368
1369 // Choose tab items type
1370 chooseTabItemsType = args => {
1371 const {
1372 e,
1373 target,
1374 callBack
1375 } = args;
1376 const elTabType = target.closest('.tab');
1377 if (!elTabType) {
1378 return;
1379 }
1380 e.preventDefault();
1381 const elTabs = elTabType.closest('.tabs');
1382 if (!elTabs) {
1383 return;
1384 }
1385 const elSelectItemsToAdd = elTabs.closest(`${LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect}`);
1386 const elInputSearch = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.elSearchTitleItem}`);
1387 const itemType = elTabType.dataset.type;
1388 const elTabLis = elTabs.querySelectorAll('.tab');
1389 elTabLis.forEach(elTabLi => {
1390 if (elTabLi.classList.contains('active')) {
1391 elTabLi.classList.remove('active');
1392 }
1393 });
1394 elTabType.classList.add('active');
1395 // Reset search input
1396 elInputSearch.value = '';
1397 const elLPTarget = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1398 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1399 dataSend.args.item_type = itemType;
1400 dataSend.args.paged = 1;
1401 dataSend.args.item_selecting = itemsSelectedData || [];
1402 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
1403 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1404 window.lpAJAXG.fetchAJAX(dataSend, {
1405 success: response => {
1406 const {
1407 data
1408 } = response;
1409 elLPTarget.innerHTML = data.content || '';
1410 },
1411 error: error => {
1412 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1413 },
1414 completed: () => {
1415 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1416 this.watchItemsSelectedDataChange();
1417 }
1418 });
1419 };
1420
1421 // Choice items to add list items selected before adding to section
1422 selectItemsFromList = args => {
1423 const {
1424 e,
1425 target
1426 } = args;
1427 const elItemAttend = target.closest(`${LpPopupSelectItemToAdd.selectors.elSelectItem}`);
1428 if (!elItemAttend) {
1429 return;
1430 }
1431 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
1432 if (target.tagName !== 'INPUT') {
1433 elInput.click();
1434 return;
1435 }
1436 const elUl = elItemAttend.closest(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1437 if (!elUl) {
1438 return;
1439 }
1440 const itemSelected = {
1441 ...elInput.dataset
1442 };
1443 //console.log( 'itemSelected', itemSelected );
1444
1445 if (elInput.checked) {
1446 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1447 if (!exists) {
1448 itemsSelectedData.push(itemSelected);
1449 }
1450 } else {
1451 const index = itemsSelectedData.findIndex(item => item.id === itemSelected.id);
1452 if (index !== -1) {
1453 itemsSelectedData.splice(index, 1);
1454 }
1455 }
1456 this.watchItemsSelectedDataChange();
1457 };
1458
1459 // Search title item
1460 searchTitleItemToSelect = args => {
1461 const {
1462 e,
1463 target
1464 } = args;
1465 const elInputSearch = target.closest(LpPopupSelectItemToAdd.selectors.elSearchTitleItem);
1466 if (!elInputSearch) {
1467 return;
1468 }
1469 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1470 clearTimeout(timeSearchTitleItem);
1471 timeSearchTitleItem = setTimeout(() => {
1472 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1473 dataSet.args.search_title = elInputSearch.value.trim();
1474 dataSet.args.item_selecting = itemsSelectedData;
1475 dataSet.args.paged = 1;
1476 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSet);
1477
1478 // Show loading
1479 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1480 window.lpAJAXG.fetchAJAX(dataSet, {
1481 success: response => {
1482 const {
1483 data
1484 } = response;
1485 elLPTarget.innerHTML = data.content || '';
1486 },
1487 error: error => {
1488 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1489 },
1490 completed: () => {
1491 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1492 }
1493 });
1494 }, 800);
1495 };
1496
1497 // Show list of items, to choose items to add to section
1498 showItemsSelected = args => {
1499 const {
1500 e,
1501 target
1502 } = args;
1503 const elBtnCountItemsSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1504 if (!elBtnCountItemsSelected) {
1505 return;
1506 }
1507 const elBtnBack = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1508 const elTabs = elPopup.querySelector('.tabs');
1509 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1510 const elHeaderItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1511 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1512 const elItemClone = elListItemsSelected.querySelector(`${LpPopupSelectItemToAdd.selectors.elItemSelectedClone}`);
1513 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
1514 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 0);
1515 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 0);
1516 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 0);
1517 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 1);
1518 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderItemsSelected, 1);
1519 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 1);
1520 elListItemsSelected.querySelectorAll(`${LpPopupSelectItemToAdd.selectors.elItemSelected}:not(.clone)`).forEach(elItem => {
1521 elItem.remove();
1522 });
1523 itemsSelectedData.forEach(item => {
1524 const elItemSelected = elItemClone.cloneNode(true);
1525 elItemSelected.classList.remove('clone');
1526 Object.entries(item).forEach(([key, value]) => {
1527 elItemSelected.dataset[key] = value;
1528 });
1529 const elTitleDisplay = elItemSelected.querySelector('.title-display');
1530 elTitleDisplay.innerHTML = item.title;
1531 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elItemSelected, 1);
1532 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
1533 });
1534 };
1535
1536 // Back to list of items
1537 backToSelectItems = args => {
1538 const {
1539 e,
1540 target
1541 } = args;
1542 const elBtnBack = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1543 if (!elBtnBack) {
1544 return;
1545 }
1546 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1547 const elTabs = elPopup.querySelector('.tabs');
1548 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1549 const elHeaderCountItemSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1550 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1551 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 1);
1552 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 1);
1553 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 1);
1554 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 0);
1555 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderCountItemSelected, 0);
1556 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 0);
1557 };
1558
1559 // Remove item selected from list items selected
1560 removeItemSelected = args => {
1561 const {
1562 e,
1563 target
1564 } = args;
1565 const elRemoveItemSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elItemSelected}`);
1566 if (!elRemoveItemSelected) {
1567 return;
1568 }
1569 const itemRemove = elRemoveItemSelected.dataset;
1570 const index = itemsSelectedData.findIndex(item => item.id === itemRemove.id);
1571 if (index !== -1) {
1572 itemsSelectedData.splice(index, 1);
1573 }
1574 elRemoveItemSelected.remove();
1575 this.watchItemsSelectedDataChange();
1576 };
1577
1578 // Watch items selected when data change
1579 watchItemsSelectedDataChange = () => {
1580 // Update count items selected, disable/enable buttons
1581 const elBtnAddItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected}`);
1582 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1583 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
1584 const elHeaderCount = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1585 const elTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1586 if (itemsSelectedData.length !== 0) {
1587 elBtnCountItemsSelected.disabled = false;
1588 elBtnAddItemsSelected.disabled = false;
1589 elBtnAddItemsSelected.classList.add('active');
1590 elSpanCount.textContent = `(${itemsSelectedData.length})`;
1591 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
1592 } else {
1593 elBtnCountItemsSelected.disabled = true;
1594 elBtnAddItemsSelected.disabled = true;
1595 elBtnAddItemsSelected.classList.remove('active');
1596 elSpanCount.textContent = '';
1597 elHeaderCount.textContent = '';
1598 }
1599
1600 // Update list input checked, when items removed, or change tab type
1601 const elListItems = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1602 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
1603 elInputs.forEach(elInputItem => {
1604 const itemSelected = elInputItem.dataset;
1605 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1606 elInputItem.checked = exists;
1607 });
1608
1609 // Set item selecting data to dataset for query.
1610 const dataSet = window.lpAJAXG.getDataSetCurrent(elTarget);
1611 dataSet.args.item_selecting = itemsSelectedData;
1612 window.lpAJAXG.setDataSetCurrent(elTarget, dataSet);
1613 };
1614
1615 // Add items selected to section
1616 addItemsSelectedToSection = args => {
1617 const {
1618 e,
1619 target,
1620 callBackHandle
1621 } = args;
1622 if (!elPopup) {
1623 return;
1624 }
1625 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
1626 if (typeof callBackHandle === 'function') {
1627 callBackHandle(itemsSelectedData);
1628 itemsSelectedData = [];
1629 }
1630 };
1631 }
1632
1633 /***/ },
1634
1635 /***/ "./assets/src/js/lpToastify.js"
1636 /*!*************************************!*\
1637 !*** ./assets/src/js/lpToastify.js ***!
1638 \*************************************/
1639 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1640
1641 "use strict";
1642 __webpack_require__.r(__webpack_exports__);
1643 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1644 /* harmony export */ show: () => (/* binding */ show)
1645 /* harmony export */ });
1646 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1647 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
1648 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
1649 /**
1650 * Utils functions
1651 *
1652 * @param url
1653 * @param data
1654 * @param functions
1655 * @since 4.3.0
1656 * @version 1.0.0
1657 */
1658
1659
1660 const argsToastify = {
1661 text: '',
1662 gravity: lpData.toast.gravity,
1663 // `top` or `bottom`
1664 position: lpData.toast.position,
1665 // `left`, `center` or `right`
1666 className: `${lpData.toast.classPrefix}`,
1667 close: lpData.toast.close == 1,
1668 stopOnFocus: lpData.toast.stopOnFocus == 1,
1669 duration: lpData.toast.duration
1670 };
1671 const show = (message, status = 'success', argsCustom) => {
1672 let args = argsToastify;
1673 if (argsCustom) {
1674 args = {
1675 ...args,
1676 ...argsCustom
1677 };
1678 }
1679 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
1680 ...args,
1681 text: message,
1682 className: `${lpData.toast.classPrefix} ${status}`
1683 });
1684 toastify.showToast();
1685 };
1686
1687 /***/ },
1688
1689 /***/ "./assets/src/js/utils.js"
1690 /*!********************************!*\
1691 !*** ./assets/src/js/utils.js ***!
1692 \********************************/
1693 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1694
1695 "use strict";
1696 __webpack_require__.r(__webpack_exports__);
1697 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1698 /* harmony export */ debounce: () => (/* binding */ debounce),
1699 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
1700 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1701 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1702 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1703 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1704 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1705 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1706 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1707 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1708 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1709 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1710 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1711 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1712 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1713 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
1714 /* harmony export */ });
1715 /**
1716 * Utils functions
1717 *
1718 * @param url
1719 * @param data
1720 * @param functions
1721 * @since 4.2.5.1
1722 * @version 1.0.6
1723 */
1724 const lpClassName = {
1725 hidden: 'lp-hidden',
1726 loading: 'loading',
1727 elCollapse: 'lp-collapse',
1728 elSectionToggle: '.lp-section-toggle',
1729 elTriggerToggle: '.lp-trigger-toggle'
1730 };
1731 const lpFetchAPI = (url, data = {}, functions = {}) => {
1732 if ('function' === typeof functions.before) {
1733 functions.before();
1734 }
1735 fetch(url, {
1736 method: 'GET',
1737 ...data
1738 }).then(response => response.json()).then(response => {
1739 if ('function' === typeof functions.success) {
1740 functions.success(response);
1741 }
1742 }).catch(err => {
1743 if ('function' === typeof functions.error) {
1744 functions.error(err);
1745 }
1746 }).finally(() => {
1747 if ('function' === typeof functions.completed) {
1748 functions.completed();
1749 }
1750 });
1751 };
1752
1753 /**
1754 * Get current URL without params.
1755 *
1756 * @since 4.2.5.1
1757 */
1758 const lpGetCurrentURLNoParam = () => {
1759 let currentUrl = window.location.href;
1760 const hasParams = currentUrl.includes('?');
1761 if (hasParams) {
1762 currentUrl = currentUrl.split('?')[0];
1763 }
1764 return currentUrl;
1765 };
1766 const lpAddQueryArgs = (endpoint, args) => {
1767 const url = new URL(endpoint);
1768 Object.keys(args).forEach(arg => {
1769 url.searchParams.set(arg, args[arg]);
1770 });
1771 return url;
1772 };
1773
1774 /**
1775 * Listen element viewed.
1776 *
1777 * @param el
1778 * @param callback
1779 * @since 4.2.5.8
1780 */
1781 const listenElementViewed = (el, callback) => {
1782 const observerSeeItem = new IntersectionObserver(function (entries) {
1783 for (const entry of entries) {
1784 if (entry.isIntersecting) {
1785 callback(entry);
1786 }
1787 }
1788 });
1789 observerSeeItem.observe(el);
1790 };
1791
1792 /**
1793 * Listen element created.
1794 *
1795 * @param callback
1796 * @since 4.2.5.8
1797 */
1798 const listenElementCreated = callback => {
1799 const observerCreateItem = new MutationObserver(function (mutations) {
1800 mutations.forEach(function (mutation) {
1801 if (mutation.addedNodes) {
1802 mutation.addedNodes.forEach(function (node) {
1803 if (node.nodeType === 1) {
1804 callback(node);
1805 }
1806 });
1807 }
1808 });
1809 });
1810 observerCreateItem.observe(document, {
1811 childList: true,
1812 subtree: true
1813 });
1814 // End.
1815 };
1816
1817 /**
1818 * Listen element created.
1819 *
1820 * @param selector
1821 * @param callback
1822 * @since 4.2.7.1
1823 */
1824 const lpOnElementReady = (selector, callback) => {
1825 const element = document.querySelector(selector);
1826 if (element) {
1827 callback(element);
1828 return;
1829 }
1830 const observer = new MutationObserver((mutations, obs) => {
1831 const element = document.querySelector(selector);
1832 if (element) {
1833 obs.disconnect();
1834 callback(element);
1835 }
1836 });
1837 observer.observe(document.documentElement, {
1838 childList: true,
1839 subtree: true
1840 });
1841 };
1842
1843 // Parse JSON from string with content include LP_AJAX_START.
1844 const lpAjaxParseJsonOld = data => {
1845 if (typeof data !== 'string') {
1846 return data;
1847 }
1848 const m = String.raw({
1849 raw: data
1850 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1851 try {
1852 if (m) {
1853 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1854 } else {
1855 data = JSON.parse(data);
1856 }
1857 } catch (e) {
1858 data = {};
1859 }
1860 return data;
1861 };
1862
1863 // status 0: hide, 1: show
1864 const lpShowHideEl = (el, status = 0) => {
1865 if (!el) {
1866 return;
1867 }
1868 if (!status) {
1869 el.classList.add(lpClassName.hidden);
1870 } else {
1871 el.classList.remove(lpClassName.hidden);
1872 }
1873 };
1874
1875 // status 0: hide, 1: show
1876 const lpSetLoadingEl = (el, status) => {
1877 if (!el) {
1878 return;
1879 }
1880 if (!status) {
1881 el.classList.remove(lpClassName.loading);
1882 } else {
1883 el.classList.add(lpClassName.loading);
1884 }
1885 };
1886
1887 // Toggle collapse section
1888 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1889 if (!elTriggerClassName) {
1890 elTriggerClassName = lpClassName.elTriggerToggle;
1891 }
1892
1893 // Exclude elements, which should not trigger the collapse toggle
1894 if (elsExclude && elsExclude.length > 0) {
1895 for (const elExclude of elsExclude) {
1896 if (target.closest(elExclude)) {
1897 return;
1898 }
1899 }
1900 }
1901 const elTrigger = target.closest(elTriggerClassName);
1902 if (!elTrigger) {
1903 return;
1904 }
1905
1906 //console.log( 'elTrigger', elTrigger );
1907
1908 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1909 if (!elSectionToggle) {
1910 return;
1911 }
1912 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1913 if ('function' === typeof callback) {
1914 callback(elSectionToggle);
1915 }
1916 };
1917
1918 // Get data of form
1919 const getDataOfForm = form => {
1920 const dataSend = {};
1921 const formData = new FormData(form);
1922 for (const pair of formData.entries()) {
1923 const key = pair[0];
1924 const value = formData.getAll(key);
1925 if (!dataSend.hasOwnProperty(key)) {
1926 // Convert value array to string.
1927 dataSend[key] = value.join(',');
1928 }
1929 }
1930 return dataSend;
1931 };
1932
1933 // Get field keys of form
1934 const getFieldKeysOfForm = form => {
1935 const keys = [];
1936 const elements = form.elements;
1937 for (let i = 0; i < elements.length; i++) {
1938 const name = elements[i].name;
1939 if (name && !keys.includes(name)) {
1940 keys.push(name);
1941 }
1942 }
1943 return keys;
1944 };
1945
1946 // Merge data handle with data form.
1947 const mergeDataWithDatForm = (elForm, dataHandle) => {
1948 const dataForm = getDataOfForm(elForm);
1949 const keys = getFieldKeysOfForm(elForm);
1950 keys.forEach(key => {
1951 if (!dataForm.hasOwnProperty(key)) {
1952 delete dataHandle[key];
1953 } else if (dataForm[key][0] === '') {
1954 delete dataForm[key];
1955 delete dataHandle[key];
1956 }
1957 });
1958 dataHandle = {
1959 ...dataHandle,
1960 ...dataForm
1961 };
1962 return dataHandle;
1963 };
1964
1965 /**
1966 * Event trigger
1967 * For each list of event handlers, listen event on document.
1968 *
1969 * eventName: 'click', 'change', ...
1970 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
1971 *
1972 * @param eventName
1973 * @param eventHandlers
1974 */
1975 const eventHandlers = (eventName, eventHandlers) => {
1976 document.addEventListener(eventName, e => {
1977 const target = e.target;
1978 let args = {
1979 e,
1980 target
1981 };
1982 eventHandlers.forEach(eventHandler => {
1983 args = {
1984 ...args,
1985 ...eventHandler
1986 };
1987
1988 //console.log( args );
1989
1990 // Check condition before call back
1991 if (eventHandler.conditionBeforeCallBack) {
1992 if (eventHandler.conditionBeforeCallBack(args) !== true) {
1993 return;
1994 }
1995 }
1996
1997 // Special check for keydown event with checkIsEventEnter = true
1998 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
1999 if (e.key !== 'Enter') {
2000 return;
2001 }
2002 }
2003 if (target.closest(eventHandler.selector)) {
2004 if (eventHandler.class) {
2005 // Call method of class, function callBack will understand exactly {this} is class object.
2006 eventHandler.class[eventHandler.callBack](args);
2007 } else {
2008 // For send args is objected, {this} is eventHandler object, not class object.
2009 eventHandler.callBack(args);
2010 }
2011 }
2012 });
2013 });
2014 };
2015
2016 /**
2017 * Debounce - delays function execution until after `wait` ms of inactivity.
2018 *
2019 * Each call resets the timer. Only the last call in a burst executes.
2020 *
2021 * USE CASES:
2022 * - Search inputs, form validation, window resize
2023 * - Multiple elements need independent timers
2024 * - When you need to call with different arguments
2025 *
2026 * EXAMPLES:
2027 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
2028 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
2029 *
2030 * const debouncedResize = debounce( recalculateLayout, 250 );
2031 * window.addEventListener('resize', debouncedResize);
2032 *
2033 * ⚠️ Create ONCE outside event handlers, not inside.
2034 *
2035 * @param {Function} func - Function to debounce (can be anonymous)
2036 * @param {number} wait - Milliseconds to wait (default: 500)
2037 * @return {Function} Debounced wrapper function
2038 * @since 4.3.7
2039 * @version 1.0.0
2040 */
2041 const debounce = (func, wait = 500) => {
2042 let timer;
2043 return args => {
2044 clearTimeout(timer);
2045 timer = setTimeout(() => func(args), wait);
2046 };
2047 };
2048
2049 /***/ },
2050
2051 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
2052 /*!*****************************************************************************************!*\
2053 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
2054 \*****************************************************************************************/
2055 (module, __webpack_exports__, __webpack_require__) {
2056
2057 "use strict";
2058 __webpack_require__.r(__webpack_exports__);
2059 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2060 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2061 /* harmony export */ });
2062 /* 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");
2063 /* 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__);
2064 /* 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");
2065 /* 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__);
2066 // Imports
2067
2068
2069 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()));
2070 // Module
2071 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
2072 * Toastify js 1.12.0
2073 * https://github.com/apvarun/toastify-js
2074 * @license MIT licensed
2075 *
2076 * Copyright (C) 2018 Varun A P
2077 */
2078
2079 .toastify {
2080 padding: 12px 20px;
2081 color: #ffffff;
2082 display: inline-block;
2083 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
2084 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
2085 background: linear-gradient(135deg, #73a5ff, #5477f5);
2086 position: fixed;
2087 opacity: 0;
2088 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
2089 border-radius: 2px;
2090 cursor: pointer;
2091 text-decoration: none;
2092 max-width: calc(50% - 20px);
2093 z-index: 2147483647;
2094 }
2095
2096 .toastify.on {
2097 opacity: 1;
2098 }
2099
2100 .toast-close {
2101 background: transparent;
2102 border: 0;
2103 color: white;
2104 cursor: pointer;
2105 font-family: inherit;
2106 font-size: 1em;
2107 opacity: 0.4;
2108 padding: 0 5px;
2109 }
2110
2111 .toastify-right {
2112 right: 15px;
2113 }
2114
2115 .toastify-left {
2116 left: 15px;
2117 }
2118
2119 .toastify-top {
2120 top: -150px;
2121 }
2122
2123 .toastify-bottom {
2124 bottom: -150px;
2125 }
2126
2127 .toastify-rounded {
2128 border-radius: 25px;
2129 }
2130
2131 .toastify-avatar {
2132 width: 1.5em;
2133 height: 1.5em;
2134 margin: -7px 5px;
2135 border-radius: 2px;
2136 }
2137
2138 .toastify-center {
2139 margin-left: auto;
2140 margin-right: auto;
2141 left: 0;
2142 right: 0;
2143 max-width: fit-content;
2144 max-width: -moz-fit-content;
2145 }
2146
2147 @media only screen and (max-width: 360px) {
2148 .toastify-right, .toastify-left {
2149 margin-left: auto;
2150 margin-right: auto;
2151 left: 0;
2152 right: 0;
2153 max-width: fit-content;
2154 }
2155 }
2156 `, "",{"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":""}]);
2157 // Exports
2158 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
2159
2160
2161 /***/ },
2162
2163 /***/ "./node_modules/css-loader/dist/runtime/api.js"
2164 /*!*****************************************************!*\
2165 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
2166 \*****************************************************/
2167 (module) {
2168
2169 "use strict";
2170
2171
2172 /*
2173 MIT License http://www.opensource.org/licenses/mit-license.php
2174 Author Tobias Koppers @sokra
2175 */
2176 module.exports = function (cssWithMappingToString) {
2177 var list = [];
2178
2179 // return the list of modules as css string
2180 list.toString = function toString() {
2181 return this.map(function (item) {
2182 var content = "";
2183 var needLayer = typeof item[5] !== "undefined";
2184 if (item[4]) {
2185 content += "@supports (".concat(item[4], ") {");
2186 }
2187 if (item[2]) {
2188 content += "@media ".concat(item[2], " {");
2189 }
2190 if (needLayer) {
2191 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
2192 }
2193 content += cssWithMappingToString(item);
2194 if (needLayer) {
2195 content += "}";
2196 }
2197 if (item[2]) {
2198 content += "}";
2199 }
2200 if (item[4]) {
2201 content += "}";
2202 }
2203 return content;
2204 }).join("");
2205 };
2206
2207 // import a list of modules into the list
2208 list.i = function i(modules, media, dedupe, supports, layer) {
2209 if (typeof modules === "string") {
2210 modules = [[null, modules, undefined]];
2211 }
2212 var alreadyImportedModules = {};
2213 if (dedupe) {
2214 for (var k = 0; k < this.length; k++) {
2215 var id = this[k][0];
2216 if (id != null) {
2217 alreadyImportedModules[id] = true;
2218 }
2219 }
2220 }
2221 for (var _k = 0; _k < modules.length; _k++) {
2222 var item = [].concat(modules[_k]);
2223 if (dedupe && alreadyImportedModules[item[0]]) {
2224 continue;
2225 }
2226 if (typeof layer !== "undefined") {
2227 if (typeof item[5] === "undefined") {
2228 item[5] = layer;
2229 } else {
2230 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
2231 item[5] = layer;
2232 }
2233 }
2234 if (media) {
2235 if (!item[2]) {
2236 item[2] = media;
2237 } else {
2238 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
2239 item[2] = media;
2240 }
2241 }
2242 if (supports) {
2243 if (!item[4]) {
2244 item[4] = "".concat(supports);
2245 } else {
2246 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
2247 item[4] = supports;
2248 }
2249 }
2250 list.push(item);
2251 }
2252 };
2253 return list;
2254 };
2255
2256 /***/ },
2257
2258 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
2259 /*!************************************************************!*\
2260 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
2261 \************************************************************/
2262 (module) {
2263
2264 "use strict";
2265
2266
2267 module.exports = function (item) {
2268 var content = item[1];
2269 var cssMapping = item[3];
2270 if (!cssMapping) {
2271 return content;
2272 }
2273 if (typeof btoa === "function") {
2274 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
2275 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
2276 var sourceMapping = "/*# ".concat(data, " */");
2277 return [content].concat([sourceMapping]).join("\n");
2278 }
2279 return [content].join("\n");
2280 };
2281
2282 /***/ },
2283
2284 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
2285 /*!*********************************************************!*\
2286 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
2287 \*********************************************************/
2288 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2289
2290 "use strict";
2291 __webpack_require__.r(__webpack_exports__);
2292 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2293 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
2294 /* harmony export */ Sortable: () => (/* binding */ Sortable),
2295 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
2296 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2297 /* harmony export */ });
2298 /**!
2299 * Sortable 1.15.7
2300 * @author RubaXa <[email protected]>
2301 * @author owenm <[email protected]>
2302 * @license MIT
2303 */
2304 function _arrayLikeToArray(r, a) {
2305 (null == a || a > r.length) && (a = r.length);
2306 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
2307 return n;
2308 }
2309 function _arrayWithoutHoles(r) {
2310 if (Array.isArray(r)) return _arrayLikeToArray(r);
2311 }
2312 function _defineProperty(e, r, t) {
2313 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
2314 value: t,
2315 enumerable: !0,
2316 configurable: !0,
2317 writable: !0
2318 }) : e[r] = t, e;
2319 }
2320 function _extends() {
2321 return _extends = Object.assign ? Object.assign.bind() : function (n) {
2322 for (var e = 1; e < arguments.length; e++) {
2323 var t = arguments[e];
2324 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
2325 }
2326 return n;
2327 }, _extends.apply(null, arguments);
2328 }
2329 function _iterableToArray(r) {
2330 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
2331 }
2332 function _nonIterableSpread() {
2333 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2334 }
2335 function ownKeys(e, r) {
2336 var t = Object.keys(e);
2337 if (Object.getOwnPropertySymbols) {
2338 var o = Object.getOwnPropertySymbols(e);
2339 r && (o = o.filter(function (r) {
2340 return Object.getOwnPropertyDescriptor(e, r).enumerable;
2341 })), t.push.apply(t, o);
2342 }
2343 return t;
2344 }
2345 function _objectSpread2(e) {
2346 for (var r = 1; r < arguments.length; r++) {
2347 var t = null != arguments[r] ? arguments[r] : {};
2348 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
2349 _defineProperty(e, r, t[r]);
2350 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
2351 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
2352 });
2353 }
2354 return e;
2355 }
2356 function _objectWithoutProperties(e, t) {
2357 if (null == e) return {};
2358 var o,
2359 r,
2360 i = _objectWithoutPropertiesLoose(e, t);
2361 if (Object.getOwnPropertySymbols) {
2362 var n = Object.getOwnPropertySymbols(e);
2363 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
2364 }
2365 return i;
2366 }
2367 function _objectWithoutPropertiesLoose(r, e) {
2368 if (null == r) return {};
2369 var t = {};
2370 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
2371 if (-1 !== e.indexOf(n)) continue;
2372 t[n] = r[n];
2373 }
2374 return t;
2375 }
2376 function _toConsumableArray(r) {
2377 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
2378 }
2379 function _toPrimitive(t, r) {
2380 if ("object" != typeof t || !t) return t;
2381 var e = t[Symbol.toPrimitive];
2382 if (void 0 !== e) {
2383 var i = e.call(t, r || "default");
2384 if ("object" != typeof i) return i;
2385 throw new TypeError("@@toPrimitive must return a primitive value.");
2386 }
2387 return ("string" === r ? String : Number)(t);
2388 }
2389 function _toPropertyKey(t) {
2390 var i = _toPrimitive(t, "string");
2391 return "symbol" == typeof i ? i : i + "";
2392 }
2393 function _typeof(o) {
2394 "@babel/helpers - typeof";
2395
2396 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
2397 return typeof o;
2398 } : function (o) {
2399 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
2400 }, _typeof(o);
2401 }
2402 function _unsupportedIterableToArray(r, a) {
2403 if (r) {
2404 if ("string" == typeof r) return _arrayLikeToArray(r, a);
2405 var t = {}.toString.call(r).slice(8, -1);
2406 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
2407 }
2408 }
2409
2410 var version = "1.15.7";
2411
2412 function userAgent(pattern) {
2413 if (typeof window !== 'undefined' && window.navigator) {
2414 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
2415 }
2416 }
2417 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
2418 var Edge = userAgent(/Edge/i);
2419 var FireFox = userAgent(/firefox/i);
2420 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
2421 var IOS = userAgent(/iP(ad|od|hone)/i);
2422 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
2423
2424 var captureMode = {
2425 capture: false,
2426 passive: false
2427 };
2428 function on(el, event, fn) {
2429 el.addEventListener(event, fn, !IE11OrLess && captureMode);
2430 }
2431 function off(el, event, fn) {
2432 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
2433 }
2434 function matches( /**HTMLElement*/el, /**String*/selector) {
2435 if (!selector) return;
2436 selector[0] === '>' && (selector = selector.substring(1));
2437 if (el) {
2438 try {
2439 if (el.matches) {
2440 return el.matches(selector);
2441 } else if (el.msMatchesSelector) {
2442 return el.msMatchesSelector(selector);
2443 } else if (el.webkitMatchesSelector) {
2444 return el.webkitMatchesSelector(selector);
2445 }
2446 } catch (_) {
2447 return false;
2448 }
2449 }
2450 return false;
2451 }
2452 function getParentOrHost(el) {
2453 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
2454 }
2455 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
2456 if (el) {
2457 ctx = ctx || document;
2458 do {
2459 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
2460 return el;
2461 }
2462 if (el === ctx) break;
2463 /* jshint boss:true */
2464 } while (el = getParentOrHost(el));
2465 }
2466 return null;
2467 }
2468 var R_SPACE = /\s+/g;
2469 function toggleClass(el, name, state) {
2470 if (el && name) {
2471 if (el.classList) {
2472 el.classList[state ? 'add' : 'remove'](name);
2473 } else {
2474 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
2475 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
2476 }
2477 }
2478 }
2479 function css(el, prop, val) {
2480 var style = el && el.style;
2481 if (style) {
2482 if (val === void 0) {
2483 if (document.defaultView && document.defaultView.getComputedStyle) {
2484 val = document.defaultView.getComputedStyle(el, '');
2485 } else if (el.currentStyle) {
2486 val = el.currentStyle;
2487 }
2488 return prop === void 0 ? val : val[prop];
2489 } else {
2490 if (!(prop in style) && prop.indexOf('webkit') === -1) {
2491 prop = '-webkit-' + prop;
2492 }
2493 style[prop] = val + (typeof val === 'string' ? '' : 'px');
2494 }
2495 }
2496 }
2497 function matrix(el, selfOnly) {
2498 var appliedTransforms = '';
2499 if (typeof el === 'string') {
2500 appliedTransforms = el;
2501 } else {
2502 do {
2503 var transform = css(el, 'transform');
2504 if (transform && transform !== 'none') {
2505 appliedTransforms = transform + ' ' + appliedTransforms;
2506 }
2507 /* jshint boss:true */
2508 } while (!selfOnly && (el = el.parentNode));
2509 }
2510 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
2511 /*jshint -W056 */
2512 return matrixFn && new matrixFn(appliedTransforms);
2513 }
2514 function find(ctx, tagName, iterator) {
2515 if (ctx) {
2516 var list = ctx.getElementsByTagName(tagName),
2517 i = 0,
2518 n = list.length;
2519 if (iterator) {
2520 for (; i < n; i++) {
2521 iterator(list[i], i);
2522 }
2523 }
2524 return list;
2525 }
2526 return [];
2527 }
2528 function getWindowScrollingElement() {
2529 var scrollingElement = document.scrollingElement;
2530 if (scrollingElement) {
2531 return scrollingElement;
2532 } else {
2533 return document.documentElement;
2534 }
2535 }
2536
2537 /**
2538 * Returns the "bounding client rect" of given element
2539 * @param {HTMLElement} el The element whose boundingClientRect is wanted
2540 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
2541 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
2542 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
2543 * @param {[HTMLElement]} container The parent the element will be placed in
2544 * @return {Object} The boundingClientRect of el, with specified adjustments
2545 */
2546 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
2547 if (!el.getBoundingClientRect && el !== window) return;
2548 var elRect, top, left, bottom, right, height, width;
2549 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
2550 elRect = el.getBoundingClientRect();
2551 top = elRect.top;
2552 left = elRect.left;
2553 bottom = elRect.bottom;
2554 right = elRect.right;
2555 height = elRect.height;
2556 width = elRect.width;
2557 } else {
2558 top = 0;
2559 left = 0;
2560 bottom = window.innerHeight;
2561 right = window.innerWidth;
2562 height = window.innerHeight;
2563 width = window.innerWidth;
2564 }
2565 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
2566 // Adjust for translate()
2567 container = container || el.parentNode;
2568
2569 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
2570 // Not needed on <= IE11
2571 if (!IE11OrLess) {
2572 do {
2573 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
2574 var containerRect = container.getBoundingClientRect();
2575
2576 // Set relative to edges of padding box of container
2577 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
2578 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
2579 bottom = top + elRect.height;
2580 right = left + elRect.width;
2581 break;
2582 }
2583 /* jshint boss:true */
2584 } while (container = container.parentNode);
2585 }
2586 }
2587 if (undoScale && el !== window) {
2588 // Adjust for scale()
2589 var elMatrix = matrix(container || el),
2590 scaleX = elMatrix && elMatrix.a,
2591 scaleY = elMatrix && elMatrix.d;
2592 if (elMatrix) {
2593 top /= scaleY;
2594 left /= scaleX;
2595 width /= scaleX;
2596 height /= scaleY;
2597 bottom = top + height;
2598 right = left + width;
2599 }
2600 }
2601 return {
2602 top: top,
2603 left: left,
2604 bottom: bottom,
2605 right: right,
2606 width: width,
2607 height: height
2608 };
2609 }
2610
2611 /**
2612 * Checks if a side of an element is scrolled past a side of its parents
2613 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
2614 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
2615 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
2616 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
2617 */
2618 function isScrolledPast(el, elSide, parentSide) {
2619 var parent = getParentAutoScrollElement(el, true),
2620 elSideVal = getRect(el)[elSide];
2621
2622 /* jshint boss:true */
2623 while (parent) {
2624 var parentSideVal = getRect(parent)[parentSide],
2625 visible = void 0;
2626 if (parentSide === 'top' || parentSide === 'left') {
2627 visible = elSideVal >= parentSideVal;
2628 } else {
2629 visible = elSideVal <= parentSideVal;
2630 }
2631 if (!visible) return parent;
2632 if (parent === getWindowScrollingElement()) break;
2633 parent = getParentAutoScrollElement(parent, false);
2634 }
2635 return false;
2636 }
2637
2638 /**
2639 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
2640 * and non-draggable elements
2641 * @param {HTMLElement} el The parent element
2642 * @param {Number} childNum The index of the child
2643 * @param {Object} options Parent Sortable's options
2644 * @return {HTMLElement} The child at index childNum, or null if not found
2645 */
2646 function getChild(el, childNum, options, includeDragEl) {
2647 var currentChild = 0,
2648 i = 0,
2649 children = el.children;
2650 while (i < children.length) {
2651 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
2652 if (currentChild === childNum) {
2653 return children[i];
2654 }
2655 currentChild++;
2656 }
2657 i++;
2658 }
2659 return null;
2660 }
2661
2662 /**
2663 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
2664 * @param {HTMLElement} el Parent element
2665 * @param {selector} selector Any other elements that should be ignored
2666 * @return {HTMLElement} The last child, ignoring ghostEl
2667 */
2668 function lastChild(el, selector) {
2669 var last = el.lastElementChild;
2670 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
2671 last = last.previousElementSibling;
2672 }
2673 return last || null;
2674 }
2675
2676 /**
2677 * Returns the index of an element within its parent for a selected set of
2678 * elements
2679 * @param {HTMLElement} el
2680 * @param {selector} selector
2681 * @return {number}
2682 */
2683 function index(el, selector) {
2684 var index = 0;
2685 if (!el || !el.parentNode) {
2686 return -1;
2687 }
2688
2689 /* jshint boss:true */
2690 while (el = el.previousElementSibling) {
2691 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
2692 index++;
2693 }
2694 }
2695 return index;
2696 }
2697
2698 /**
2699 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
2700 * The value is returned in real pixels.
2701 * @param {HTMLElement} el
2702 * @return {Array} Offsets in the format of [left, top]
2703 */
2704 function getRelativeScrollOffset(el) {
2705 var offsetLeft = 0,
2706 offsetTop = 0,
2707 winScroller = getWindowScrollingElement();
2708 if (el) {
2709 do {
2710 var elMatrix = matrix(el),
2711 scaleX = elMatrix.a,
2712 scaleY = elMatrix.d;
2713 offsetLeft += el.scrollLeft * scaleX;
2714 offsetTop += el.scrollTop * scaleY;
2715 } while (el !== winScroller && (el = el.parentNode));
2716 }
2717 return [offsetLeft, offsetTop];
2718 }
2719
2720 /**
2721 * Returns the index of the object within the given array
2722 * @param {Array} arr Array that may or may not hold the object
2723 * @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
2724 * @return {Number} The index of the object in the array, or -1
2725 */
2726 function indexOfObject(arr, obj) {
2727 for (var i in arr) {
2728 if (!arr.hasOwnProperty(i)) continue;
2729 for (var key in obj) {
2730 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
2731 }
2732 }
2733 return -1;
2734 }
2735 function getParentAutoScrollElement(el, includeSelf) {
2736 // skip to window
2737 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
2738 var elem = el;
2739 var gotSelf = false;
2740 do {
2741 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
2742 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
2743 var elemCSS = css(elem);
2744 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
2745 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
2746 if (gotSelf || includeSelf) return elem;
2747 gotSelf = true;
2748 }
2749 }
2750 /* jshint boss:true */
2751 } while (elem = elem.parentNode);
2752 return getWindowScrollingElement();
2753 }
2754 function extend(dst, src) {
2755 if (dst && src) {
2756 for (var key in src) {
2757 if (src.hasOwnProperty(key)) {
2758 dst[key] = src[key];
2759 }
2760 }
2761 }
2762 return dst;
2763 }
2764 function isRectEqual(rect1, rect2) {
2765 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);
2766 }
2767 var _throttleTimeout;
2768 function throttle(callback, ms) {
2769 return function () {
2770 if (!_throttleTimeout) {
2771 var args = arguments,
2772 _this = this;
2773 if (args.length === 1) {
2774 callback.call(_this, args[0]);
2775 } else {
2776 callback.apply(_this, args);
2777 }
2778 _throttleTimeout = setTimeout(function () {
2779 _throttleTimeout = void 0;
2780 }, ms);
2781 }
2782 };
2783 }
2784 function cancelThrottle() {
2785 clearTimeout(_throttleTimeout);
2786 _throttleTimeout = void 0;
2787 }
2788 function scrollBy(el, x, y) {
2789 el.scrollLeft += x;
2790 el.scrollTop += y;
2791 }
2792 function clone(el) {
2793 var Polymer = window.Polymer;
2794 var $ = window.jQuery || window.Zepto;
2795 if (Polymer && Polymer.dom) {
2796 return Polymer.dom(el).cloneNode(true);
2797 } else if ($) {
2798 return $(el).clone(true)[0];
2799 } else {
2800 return el.cloneNode(true);
2801 }
2802 }
2803 function setRect(el, rect) {
2804 css(el, 'position', 'absolute');
2805 css(el, 'top', rect.top);
2806 css(el, 'left', rect.left);
2807 css(el, 'width', rect.width);
2808 css(el, 'height', rect.height);
2809 }
2810 function unsetRect(el) {
2811 css(el, 'position', '');
2812 css(el, 'top', '');
2813 css(el, 'left', '');
2814 css(el, 'width', '');
2815 css(el, 'height', '');
2816 }
2817 function getChildContainingRectFromElement(container, options, ghostEl) {
2818 var rect = {};
2819 Array.from(container.children).forEach(function (child) {
2820 var _rect$left, _rect$top, _rect$right, _rect$bottom;
2821 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
2822 var childRect = getRect(child);
2823 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
2824 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
2825 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
2826 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
2827 });
2828 rect.width = rect.right - rect.left;
2829 rect.height = rect.bottom - rect.top;
2830 rect.x = rect.left;
2831 rect.y = rect.top;
2832 return rect;
2833 }
2834 var expando = 'Sortable' + new Date().getTime();
2835
2836 function AnimationStateManager() {
2837 var animationStates = [],
2838 animationCallbackId;
2839 return {
2840 captureAnimationState: function captureAnimationState() {
2841 animationStates = [];
2842 if (!this.options.animation) return;
2843 var children = [].slice.call(this.el.children);
2844 children.forEach(function (child) {
2845 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
2846 animationStates.push({
2847 target: child,
2848 rect: getRect(child)
2849 });
2850 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
2851
2852 // If animating: compensate for current animation
2853 if (child.thisAnimationDuration) {
2854 var childMatrix = matrix(child, true);
2855 if (childMatrix) {
2856 fromRect.top -= childMatrix.f;
2857 fromRect.left -= childMatrix.e;
2858 }
2859 }
2860 child.fromRect = fromRect;
2861 });
2862 },
2863 addAnimationState: function addAnimationState(state) {
2864 animationStates.push(state);
2865 },
2866 removeAnimationState: function removeAnimationState(target) {
2867 animationStates.splice(indexOfObject(animationStates, {
2868 target: target
2869 }), 1);
2870 },
2871 animateAll: function animateAll(callback) {
2872 var _this = this;
2873 if (!this.options.animation) {
2874 clearTimeout(animationCallbackId);
2875 if (typeof callback === 'function') callback();
2876 return;
2877 }
2878 var animating = false,
2879 animationTime = 0;
2880 animationStates.forEach(function (state) {
2881 var time = 0,
2882 target = state.target,
2883 fromRect = target.fromRect,
2884 toRect = getRect(target),
2885 prevFromRect = target.prevFromRect,
2886 prevToRect = target.prevToRect,
2887 animatingRect = state.rect,
2888 targetMatrix = matrix(target, true);
2889 if (targetMatrix) {
2890 // Compensate for current animation
2891 toRect.top -= targetMatrix.f;
2892 toRect.left -= targetMatrix.e;
2893 }
2894 target.toRect = toRect;
2895 if (target.thisAnimationDuration) {
2896 // Could also check if animatingRect is between fromRect and toRect
2897 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
2898 // Make sure animatingRect is on line between toRect & fromRect
2899 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
2900 // If returning to same place as started from animation and on same axis
2901 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
2902 }
2903 }
2904
2905 // if fromRect != toRect: animate
2906 if (!isRectEqual(toRect, fromRect)) {
2907 target.prevFromRect = fromRect;
2908 target.prevToRect = toRect;
2909 if (!time) {
2910 time = _this.options.animation;
2911 }
2912 _this.animate(target, animatingRect, toRect, time);
2913 }
2914 if (time) {
2915 animating = true;
2916 animationTime = Math.max(animationTime, time);
2917 clearTimeout(target.animationResetTimer);
2918 target.animationResetTimer = setTimeout(function () {
2919 target.animationTime = 0;
2920 target.prevFromRect = null;
2921 target.fromRect = null;
2922 target.prevToRect = null;
2923 target.thisAnimationDuration = null;
2924 }, time);
2925 target.thisAnimationDuration = time;
2926 }
2927 });
2928 clearTimeout(animationCallbackId);
2929 if (!animating) {
2930 if (typeof callback === 'function') callback();
2931 } else {
2932 animationCallbackId = setTimeout(function () {
2933 if (typeof callback === 'function') callback();
2934 }, animationTime);
2935 }
2936 animationStates = [];
2937 },
2938 animate: function animate(target, currentRect, toRect, duration) {
2939 if (duration) {
2940 css(target, 'transition', '');
2941 css(target, 'transform', '');
2942 var elMatrix = matrix(this.el),
2943 scaleX = elMatrix && elMatrix.a,
2944 scaleY = elMatrix && elMatrix.d,
2945 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
2946 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
2947 target.animatingX = !!translateX;
2948 target.animatingY = !!translateY;
2949 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
2950 this.forRepaintDummy = repaint(target); // repaint
2951
2952 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
2953 css(target, 'transform', 'translate3d(0,0,0)');
2954 typeof target.animated === 'number' && clearTimeout(target.animated);
2955 target.animated = setTimeout(function () {
2956 css(target, 'transition', '');
2957 css(target, 'transform', '');
2958 target.animated = false;
2959 target.animatingX = false;
2960 target.animatingY = false;
2961 }, duration);
2962 }
2963 }
2964 };
2965 }
2966 function repaint(target) {
2967 return target.offsetWidth;
2968 }
2969 function calculateRealTime(animatingRect, fromRect, toRect, options) {
2970 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;
2971 }
2972
2973 var plugins = [];
2974 var defaults = {
2975 initializeByDefault: true
2976 };
2977 var PluginManager = {
2978 mount: function mount(plugin) {
2979 // Set default static properties
2980 for (var option in defaults) {
2981 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
2982 plugin[option] = defaults[option];
2983 }
2984 }
2985 plugins.forEach(function (p) {
2986 if (p.pluginName === plugin.pluginName) {
2987 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
2988 }
2989 });
2990 plugins.push(plugin);
2991 },
2992 pluginEvent: function pluginEvent(eventName, sortable, evt) {
2993 var _this = this;
2994 this.eventCanceled = false;
2995 evt.cancel = function () {
2996 _this.eventCanceled = true;
2997 };
2998 var eventNameGlobal = eventName + 'Global';
2999 plugins.forEach(function (plugin) {
3000 if (!sortable[plugin.pluginName]) return;
3001 // Fire global events if it exists in this sortable
3002 if (sortable[plugin.pluginName][eventNameGlobal]) {
3003 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
3004 sortable: sortable
3005 }, evt));
3006 }
3007
3008 // Only fire plugin event if plugin is enabled in this sortable,
3009 // and plugin has event defined
3010 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
3011 sortable[plugin.pluginName][eventName](_objectSpread2({
3012 sortable: sortable
3013 }, evt));
3014 }
3015 });
3016 },
3017 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
3018 plugins.forEach(function (plugin) {
3019 var pluginName = plugin.pluginName;
3020 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
3021 var initialized = new plugin(sortable, el, sortable.options);
3022 initialized.sortable = sortable;
3023 initialized.options = sortable.options;
3024 sortable[pluginName] = initialized;
3025
3026 // Add default options from plugin
3027 _extends(defaults, initialized.defaults);
3028 });
3029 for (var option in sortable.options) {
3030 if (!sortable.options.hasOwnProperty(option)) continue;
3031 var modified = this.modifyOption(sortable, option, sortable.options[option]);
3032 if (typeof modified !== 'undefined') {
3033 sortable.options[option] = modified;
3034 }
3035 }
3036 },
3037 getEventProperties: function getEventProperties(name, sortable) {
3038 var eventProperties = {};
3039 plugins.forEach(function (plugin) {
3040 if (typeof plugin.eventProperties !== 'function') return;
3041 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
3042 });
3043 return eventProperties;
3044 },
3045 modifyOption: function modifyOption(sortable, name, value) {
3046 var modifiedValue;
3047 plugins.forEach(function (plugin) {
3048 // Plugin must exist on the Sortable
3049 if (!sortable[plugin.pluginName]) return;
3050
3051 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
3052 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
3053 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
3054 }
3055 });
3056 return modifiedValue;
3057 }
3058 };
3059
3060 function dispatchEvent(_ref) {
3061 var sortable = _ref.sortable,
3062 rootEl = _ref.rootEl,
3063 name = _ref.name,
3064 targetEl = _ref.targetEl,
3065 cloneEl = _ref.cloneEl,
3066 toEl = _ref.toEl,
3067 fromEl = _ref.fromEl,
3068 oldIndex = _ref.oldIndex,
3069 newIndex = _ref.newIndex,
3070 oldDraggableIndex = _ref.oldDraggableIndex,
3071 newDraggableIndex = _ref.newDraggableIndex,
3072 originalEvent = _ref.originalEvent,
3073 putSortable = _ref.putSortable,
3074 extraEventProperties = _ref.extraEventProperties;
3075 sortable = sortable || rootEl && rootEl[expando];
3076 if (!sortable) return;
3077 var evt,
3078 options = sortable.options,
3079 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
3080 // Support for new CustomEvent feature
3081 if (window.CustomEvent && !IE11OrLess && !Edge) {
3082 evt = new CustomEvent(name, {
3083 bubbles: true,
3084 cancelable: true
3085 });
3086 } else {
3087 evt = document.createEvent('Event');
3088 evt.initEvent(name, true, true);
3089 }
3090 evt.to = toEl || rootEl;
3091 evt.from = fromEl || rootEl;
3092 evt.item = targetEl || rootEl;
3093 evt.clone = cloneEl;
3094 evt.oldIndex = oldIndex;
3095 evt.newIndex = newIndex;
3096 evt.oldDraggableIndex = oldDraggableIndex;
3097 evt.newDraggableIndex = newDraggableIndex;
3098 evt.originalEvent = originalEvent;
3099 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
3100 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
3101 for (var option in allEventProperties) {
3102 evt[option] = allEventProperties[option];
3103 }
3104 if (rootEl) {
3105 rootEl.dispatchEvent(evt);
3106 }
3107 if (options[onName]) {
3108 options[onName].call(sortable, evt);
3109 }
3110 }
3111
3112 var _excluded = ["evt"];
3113 var pluginEvent = function pluginEvent(eventName, sortable) {
3114 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
3115 originalEvent = _ref.evt,
3116 data = _objectWithoutProperties(_ref, _excluded);
3117 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
3118 dragEl: dragEl,
3119 parentEl: parentEl,
3120 ghostEl: ghostEl,
3121 rootEl: rootEl,
3122 nextEl: nextEl,
3123 lastDownEl: lastDownEl,
3124 cloneEl: cloneEl,
3125 cloneHidden: cloneHidden,
3126 dragStarted: moved,
3127 putSortable: putSortable,
3128 activeSortable: Sortable.active,
3129 originalEvent: originalEvent,
3130 oldIndex: oldIndex,
3131 oldDraggableIndex: oldDraggableIndex,
3132 newIndex: newIndex,
3133 newDraggableIndex: newDraggableIndex,
3134 hideGhostForTarget: _hideGhostForTarget,
3135 unhideGhostForTarget: _unhideGhostForTarget,
3136 cloneNowHidden: function cloneNowHidden() {
3137 cloneHidden = true;
3138 },
3139 cloneNowShown: function cloneNowShown() {
3140 cloneHidden = false;
3141 },
3142 dispatchSortableEvent: function dispatchSortableEvent(name) {
3143 _dispatchEvent({
3144 sortable: sortable,
3145 name: name,
3146 originalEvent: originalEvent
3147 });
3148 }
3149 }, data));
3150 };
3151 function _dispatchEvent(info) {
3152 dispatchEvent(_objectSpread2({
3153 putSortable: putSortable,
3154 cloneEl: cloneEl,
3155 targetEl: dragEl,
3156 rootEl: rootEl,
3157 oldIndex: oldIndex,
3158 oldDraggableIndex: oldDraggableIndex,
3159 newIndex: newIndex,
3160 newDraggableIndex: newDraggableIndex
3161 }, info));
3162 }
3163 var dragEl,
3164 parentEl,
3165 ghostEl,
3166 rootEl,
3167 nextEl,
3168 lastDownEl,
3169 cloneEl,
3170 cloneHidden,
3171 oldIndex,
3172 newIndex,
3173 oldDraggableIndex,
3174 newDraggableIndex,
3175 activeGroup,
3176 putSortable,
3177 awaitingDragStarted = false,
3178 ignoreNextClick = false,
3179 sortables = [],
3180 tapEvt,
3181 touchEvt,
3182 lastDx,
3183 lastDy,
3184 tapDistanceLeft,
3185 tapDistanceTop,
3186 moved,
3187 lastTarget,
3188 lastDirection,
3189 pastFirstInvertThresh = false,
3190 isCircumstantialInvert = false,
3191 targetMoveDistance,
3192 // For positioning ghost absolutely
3193 ghostRelativeParent,
3194 ghostRelativeParentInitialScroll = [],
3195 // (left, top)
3196
3197 _silent = false,
3198 savedInputChecked = [];
3199
3200 /** @const */
3201 var documentExists = typeof document !== 'undefined',
3202 PositionGhostAbsolutely = IOS,
3203 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
3204 // This will not pass for IE9, because IE9 DnD only works on anchors
3205 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
3206 supportCssPointerEvents = function () {
3207 if (!documentExists) return;
3208 // false when <= IE11
3209 if (IE11OrLess) {
3210 return false;
3211 }
3212 var el = document.createElement('x');
3213 el.style.cssText = 'pointer-events:auto';
3214 return el.style.pointerEvents === 'auto';
3215 }(),
3216 _detectDirection = function _detectDirection(el, options) {
3217 var elCSS = css(el),
3218 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
3219 child1 = getChild(el, 0, options),
3220 child2 = getChild(el, 1, options),
3221 firstChildCSS = child1 && css(child1),
3222 secondChildCSS = child2 && css(child2),
3223 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
3224 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
3225 if (elCSS.display === 'flex') {
3226 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
3227 }
3228 if (elCSS.display === 'grid') {
3229 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
3230 }
3231 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
3232 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
3233 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
3234 }
3235 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';
3236 },
3237 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
3238 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
3239 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
3240 dragElOppLength = vertical ? dragRect.width : dragRect.height,
3241 targetS1Opp = vertical ? targetRect.left : targetRect.top,
3242 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
3243 targetOppLength = vertical ? targetRect.width : targetRect.height;
3244 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
3245 },
3246 /**
3247 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
3248 * @param {Number} x X position
3249 * @param {Number} y Y position
3250 * @return {HTMLElement} Element of the first found nearest Sortable
3251 */
3252 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
3253 var ret;
3254 sortables.some(function (sortable) {
3255 var threshold = sortable[expando].options.emptyInsertThreshold;
3256 if (!threshold || lastChild(sortable)) return;
3257 var rect = getRect(sortable),
3258 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
3259 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
3260 if (insideHorizontally && insideVertically) {
3261 return ret = sortable;
3262 }
3263 });
3264 return ret;
3265 },
3266 _prepareGroup = function _prepareGroup(options) {
3267 function toFn(value, pull) {
3268 return function (to, from, dragEl, evt) {
3269 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
3270 if (value == null && (pull || sameGroup)) {
3271 // Default pull value
3272 // Default pull and put value if same group
3273 return true;
3274 } else if (value == null || value === false) {
3275 return false;
3276 } else if (pull && value === 'clone') {
3277 return value;
3278 } else if (typeof value === 'function') {
3279 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
3280 } else {
3281 var otherGroup = (pull ? to : from).options.group.name;
3282 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
3283 }
3284 };
3285 }
3286 var group = {};
3287 var originalGroup = options.group;
3288 if (!originalGroup || _typeof(originalGroup) != 'object') {
3289 originalGroup = {
3290 name: originalGroup
3291 };
3292 }
3293 group.name = originalGroup.name;
3294 group.checkPull = toFn(originalGroup.pull, true);
3295 group.checkPut = toFn(originalGroup.put);
3296 group.revertClone = originalGroup.revertClone;
3297 options.group = group;
3298 },
3299 _hideGhostForTarget = function _hideGhostForTarget() {
3300 if (!supportCssPointerEvents && ghostEl) {
3301 css(ghostEl, 'display', 'none');
3302 }
3303 },
3304 _unhideGhostForTarget = function _unhideGhostForTarget() {
3305 if (!supportCssPointerEvents && ghostEl) {
3306 css(ghostEl, 'display', '');
3307 }
3308 };
3309
3310 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
3311 if (documentExists && !ChromeForAndroid) {
3312 document.addEventListener('click', function (evt) {
3313 if (ignoreNextClick) {
3314 evt.preventDefault();
3315 evt.stopPropagation && evt.stopPropagation();
3316 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
3317 ignoreNextClick = false;
3318 return false;
3319 }
3320 }, true);
3321 }
3322 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
3323 if (dragEl) {
3324 evt = evt.touches ? evt.touches[0] : evt;
3325 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
3326 if (nearest) {
3327 // Create imitation event
3328 var event = {};
3329 for (var i in evt) {
3330 if (evt.hasOwnProperty(i)) {
3331 event[i] = evt[i];
3332 }
3333 }
3334 event.target = event.rootEl = nearest;
3335 event.preventDefault = void 0;
3336 event.stopPropagation = void 0;
3337 nearest[expando]._onDragOver(event);
3338 }
3339 }
3340 };
3341 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
3342 if (dragEl) {
3343 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
3344 }
3345 };
3346
3347 /**
3348 * @class Sortable
3349 * @param {HTMLElement} el
3350 * @param {Object} [options]
3351 */
3352 function Sortable(el, options) {
3353 if (!(el && el.nodeType && el.nodeType === 1)) {
3354 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
3355 }
3356 this.el = el; // root element
3357 this.options = options = _extends({}, options);
3358
3359 // Export instance
3360 el[expando] = this;
3361 var defaults = {
3362 group: null,
3363 sort: true,
3364 disabled: false,
3365 store: null,
3366 handle: null,
3367 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
3368 swapThreshold: 1,
3369 // percentage; 0 <= x <= 1
3370 invertSwap: false,
3371 // invert always
3372 invertedSwapThreshold: null,
3373 // will be set to same as swapThreshold if default
3374 removeCloneOnHide: true,
3375 direction: function direction() {
3376 return _detectDirection(el, this.options);
3377 },
3378 ghostClass: 'sortable-ghost',
3379 chosenClass: 'sortable-chosen',
3380 dragClass: 'sortable-drag',
3381 ignore: 'a, img',
3382 filter: null,
3383 preventOnFilter: true,
3384 animation: 0,
3385 easing: null,
3386 setData: function setData(dataTransfer, dragEl) {
3387 dataTransfer.setData('Text', dragEl.textContent);
3388 },
3389 dropBubble: false,
3390 dragoverBubble: false,
3391 dataIdAttr: 'data-id',
3392 delay: 0,
3393 delayOnTouchOnly: false,
3394 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
3395 forceFallback: false,
3396 fallbackClass: 'sortable-fallback',
3397 fallbackOnBody: false,
3398 fallbackTolerance: 0,
3399 fallbackOffset: {
3400 x: 0,
3401 y: 0
3402 },
3403 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
3404 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
3405 emptyInsertThreshold: 5
3406 };
3407 PluginManager.initializePlugins(this, el, defaults);
3408
3409 // Set default options
3410 for (var name in defaults) {
3411 !(name in options) && (options[name] = defaults[name]);
3412 }
3413 _prepareGroup(options);
3414
3415 // Bind all private methods
3416 for (var fn in this) {
3417 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3418 this[fn] = this[fn].bind(this);
3419 }
3420 }
3421
3422 // Setup drag mode
3423 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
3424 if (this.nativeDraggable) {
3425 // Touch start threshold cannot be greater than the native dragstart threshold
3426 this.options.touchStartThreshold = 1;
3427 }
3428
3429 // Bind events
3430 if (options.supportPointer) {
3431 on(el, 'pointerdown', this._onTapStart);
3432 } else {
3433 on(el, 'mousedown', this._onTapStart);
3434 on(el, 'touchstart', this._onTapStart);
3435 }
3436 if (this.nativeDraggable) {
3437 on(el, 'dragover', this);
3438 on(el, 'dragenter', this);
3439 }
3440 sortables.push(this.el);
3441
3442 // Restore sorting
3443 options.store && options.store.get && this.sort(options.store.get(this) || []);
3444
3445 // Add animation state manager
3446 _extends(this, AnimationStateManager());
3447 }
3448 Sortable.prototype = /** @lends Sortable.prototype */{
3449 constructor: Sortable,
3450 _isOutsideThisEl: function _isOutsideThisEl(target) {
3451 if (!this.el.contains(target) && target !== this.el) {
3452 lastTarget = null;
3453 }
3454 },
3455 _getDirection: function _getDirection(evt, target) {
3456 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
3457 },
3458 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
3459 if (!evt.cancelable) return;
3460 var _this = this,
3461 el = this.el,
3462 options = this.options,
3463 preventOnFilter = options.preventOnFilter,
3464 type = evt.type,
3465 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
3466 target = (touch || evt).target,
3467 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
3468 filter = options.filter;
3469 _saveInputCheckedState(el);
3470
3471 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
3472 if (dragEl) {
3473 return;
3474 }
3475 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
3476 return; // only left button and enabled
3477 }
3478
3479 // cancel dnd if original target is content editable
3480 if (originalTarget.isContentEditable) {
3481 return;
3482 }
3483
3484 // Safari ignores further event handling after mousedown
3485 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
3486 return;
3487 }
3488 target = closest(target, options.draggable, el, false);
3489 if (target && target.animated) {
3490 return;
3491 }
3492 if (lastDownEl === target) {
3493 // Ignoring duplicate `down`
3494 return;
3495 }
3496
3497 // Get the index of the dragged element within its parent
3498 oldIndex = index(target);
3499 oldDraggableIndex = index(target, options.draggable);
3500
3501 // Check filter
3502 if (typeof filter === 'function') {
3503 if (filter.call(this, evt, target, this)) {
3504 _dispatchEvent({
3505 sortable: _this,
3506 rootEl: originalTarget,
3507 name: 'filter',
3508 targetEl: target,
3509 toEl: el,
3510 fromEl: el
3511 });
3512 pluginEvent('filter', _this, {
3513 evt: evt
3514 });
3515 preventOnFilter && evt.preventDefault();
3516 return; // cancel dnd
3517 }
3518 } else if (filter) {
3519 filter = filter.split(',').some(function (criteria) {
3520 criteria = closest(originalTarget, criteria.trim(), el, false);
3521 if (criteria) {
3522 _dispatchEvent({
3523 sortable: _this,
3524 rootEl: criteria,
3525 name: 'filter',
3526 targetEl: target,
3527 fromEl: el,
3528 toEl: el
3529 });
3530 pluginEvent('filter', _this, {
3531 evt: evt
3532 });
3533 return true;
3534 }
3535 });
3536 if (filter) {
3537 preventOnFilter && evt.preventDefault();
3538 return; // cancel dnd
3539 }
3540 }
3541 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
3542 return;
3543 }
3544
3545 // Prepare `dragstart`
3546 this._prepareDragStart(evt, touch, target);
3547 },
3548 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
3549 var _this = this,
3550 el = _this.el,
3551 options = _this.options,
3552 ownerDocument = el.ownerDocument,
3553 dragStartFn;
3554 if (target && !dragEl && target.parentNode === el) {
3555 var dragRect = getRect(target);
3556 rootEl = el;
3557 dragEl = target;
3558 parentEl = dragEl.parentNode;
3559 nextEl = dragEl.nextSibling;
3560 lastDownEl = target;
3561 activeGroup = options.group;
3562 Sortable.dragged = dragEl;
3563 tapEvt = {
3564 target: dragEl,
3565 clientX: (touch || evt).clientX,
3566 clientY: (touch || evt).clientY
3567 };
3568 tapDistanceLeft = tapEvt.clientX - dragRect.left;
3569 tapDistanceTop = tapEvt.clientY - dragRect.top;
3570 this._lastX = (touch || evt).clientX;
3571 this._lastY = (touch || evt).clientY;
3572 dragEl.style['will-change'] = 'all';
3573 dragStartFn = function dragStartFn() {
3574 pluginEvent('delayEnded', _this, {
3575 evt: evt
3576 });
3577 if (Sortable.eventCanceled) {
3578 _this._onDrop();
3579 return;
3580 }
3581 // Delayed drag has been triggered
3582 // we can re-enable the events: touchmove/mousemove
3583 _this._disableDelayedDragEvents();
3584 if (!FireFox && _this.nativeDraggable) {
3585 dragEl.draggable = true;
3586 }
3587
3588 // Bind the events: dragstart/dragend
3589 _this._triggerDragStart(evt, touch);
3590
3591 // Drag start event
3592 _dispatchEvent({
3593 sortable: _this,
3594 name: 'choose',
3595 originalEvent: evt
3596 });
3597
3598 // Chosen item
3599 toggleClass(dragEl, options.chosenClass, true);
3600 };
3601
3602 // Disable "draggable"
3603 options.ignore.split(',').forEach(function (criteria) {
3604 find(dragEl, criteria.trim(), _disableDraggable);
3605 });
3606 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
3607 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
3608 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
3609 if (options.supportPointer) {
3610 on(ownerDocument, 'pointerup', _this._onDrop);
3611 // Native D&D triggers pointercancel
3612 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
3613 } else {
3614 on(ownerDocument, 'mouseup', _this._onDrop);
3615 on(ownerDocument, 'touchend', _this._onDrop);
3616 on(ownerDocument, 'touchcancel', _this._onDrop);
3617 }
3618
3619 // Make dragEl draggable (must be before delay for FireFox)
3620 if (FireFox && this.nativeDraggable) {
3621 this.options.touchStartThreshold = 4;
3622 dragEl.draggable = true;
3623 }
3624 pluginEvent('delayStart', this, {
3625 evt: evt
3626 });
3627
3628 // Delay is impossible for native DnD in Edge or IE
3629 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
3630 if (Sortable.eventCanceled) {
3631 this._onDrop();
3632 return;
3633 }
3634 // If the user moves the pointer or let go the click or touch
3635 // before the delay has been reached:
3636 // disable the delayed drag
3637 if (options.supportPointer) {
3638 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
3639 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
3640 } else {
3641 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
3642 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
3643 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
3644 }
3645 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
3646 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
3647 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
3648 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
3649 } else {
3650 dragStartFn();
3651 }
3652 }
3653 },
3654 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
3655 var touch = e.touches ? e.touches[0] : e;
3656 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))) {
3657 this._disableDelayedDrag();
3658 }
3659 },
3660 _disableDelayedDrag: function _disableDelayedDrag() {
3661 dragEl && _disableDraggable(dragEl);
3662 clearTimeout(this._dragStartTimer);
3663 this._disableDelayedDragEvents();
3664 },
3665 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
3666 var ownerDocument = this.el.ownerDocument;
3667 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
3668 off(ownerDocument, 'touchend', this._disableDelayedDrag);
3669 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
3670 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
3671 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
3672 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
3673 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
3674 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
3675 },
3676 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
3677 touch = touch || evt.pointerType == 'touch' && evt;
3678 if (!this.nativeDraggable || touch) {
3679 if (this.options.supportPointer) {
3680 on(document, 'pointermove', this._onTouchMove);
3681 } else if (touch) {
3682 on(document, 'touchmove', this._onTouchMove);
3683 } else {
3684 on(document, 'mousemove', this._onTouchMove);
3685 }
3686 } else {
3687 on(dragEl, 'dragend', this);
3688 on(rootEl, 'dragstart', this._onDragStart);
3689 }
3690 try {
3691 if (document.selection) {
3692 _nextTick(function () {
3693 document.selection.empty();
3694 });
3695 } else {
3696 window.getSelection().removeAllRanges();
3697 }
3698 } catch (err) {}
3699 },
3700 _dragStarted: function _dragStarted(fallback, evt) {
3701 awaitingDragStarted = false;
3702 if (rootEl && dragEl) {
3703 pluginEvent('dragStarted', this, {
3704 evt: evt
3705 });
3706 if (this.nativeDraggable) {
3707 on(document, 'dragover', _checkOutsideTargetEl);
3708 }
3709 var options = this.options;
3710
3711 // Apply effect
3712 !fallback && toggleClass(dragEl, options.dragClass, false);
3713 toggleClass(dragEl, options.ghostClass, true);
3714 Sortable.active = this;
3715 fallback && this._appendGhost();
3716
3717 // Drag start event
3718 _dispatchEvent({
3719 sortable: this,
3720 name: 'start',
3721 originalEvent: evt
3722 });
3723 } else {
3724 this._nulling();
3725 }
3726 },
3727 _emulateDragOver: function _emulateDragOver() {
3728 if (touchEvt) {
3729 this._lastX = touchEvt.clientX;
3730 this._lastY = touchEvt.clientY;
3731 _hideGhostForTarget();
3732 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3733 var parent = target;
3734 while (target && target.shadowRoot) {
3735 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3736 if (target === parent) break;
3737 parent = target;
3738 }
3739 dragEl.parentNode[expando]._isOutsideThisEl(target);
3740 if (parent) {
3741 do {
3742 if (parent[expando]) {
3743 var inserted = void 0;
3744 inserted = parent[expando]._onDragOver({
3745 clientX: touchEvt.clientX,
3746 clientY: touchEvt.clientY,
3747 target: target,
3748 rootEl: parent
3749 });
3750 if (inserted && !this.options.dragoverBubble) {
3751 break;
3752 }
3753 }
3754 target = parent; // store last element
3755 }
3756 /* jshint boss:true */ while (parent = getParentOrHost(parent));
3757 }
3758 _unhideGhostForTarget();
3759 }
3760 },
3761 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
3762 if (tapEvt) {
3763 var options = this.options,
3764 fallbackTolerance = options.fallbackTolerance,
3765 fallbackOffset = options.fallbackOffset,
3766 touch = evt.touches ? evt.touches[0] : evt,
3767 ghostMatrix = ghostEl && matrix(ghostEl, true),
3768 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
3769 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
3770 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
3771 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
3772 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
3773
3774 // only set the status to dragging, when we are actually dragging
3775 if (!Sortable.active && !awaitingDragStarted) {
3776 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
3777 return;
3778 }
3779 this._onDragStart(evt, true);
3780 }
3781 if (ghostEl) {
3782 if (ghostMatrix) {
3783 ghostMatrix.e += dx - (lastDx || 0);
3784 ghostMatrix.f += dy - (lastDy || 0);
3785 } else {
3786 ghostMatrix = {
3787 a: 1,
3788 b: 0,
3789 c: 0,
3790 d: 1,
3791 e: dx,
3792 f: dy
3793 };
3794 }
3795 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
3796 css(ghostEl, 'webkitTransform', cssMatrix);
3797 css(ghostEl, 'mozTransform', cssMatrix);
3798 css(ghostEl, 'msTransform', cssMatrix);
3799 css(ghostEl, 'transform', cssMatrix);
3800 lastDx = dx;
3801 lastDy = dy;
3802 touchEvt = touch;
3803 }
3804 evt.cancelable && evt.preventDefault();
3805 }
3806 },
3807 _appendGhost: function _appendGhost() {
3808 // Bug if using scale(): https://stackoverflow.com/questions/2637058
3809 // Not being adjusted for
3810 if (!ghostEl) {
3811 var container = this.options.fallbackOnBody ? document.body : rootEl,
3812 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
3813 options = this.options;
3814
3815 // Position absolutely
3816 if (PositionGhostAbsolutely) {
3817 // Get relatively positioned parent
3818 ghostRelativeParent = container;
3819 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
3820 ghostRelativeParent = ghostRelativeParent.parentNode;
3821 }
3822 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
3823 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
3824 rect.top += ghostRelativeParent.scrollTop;
3825 rect.left += ghostRelativeParent.scrollLeft;
3826 } else {
3827 ghostRelativeParent = getWindowScrollingElement();
3828 }
3829 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
3830 }
3831 ghostEl = dragEl.cloneNode(true);
3832 toggleClass(ghostEl, options.ghostClass, false);
3833 toggleClass(ghostEl, options.fallbackClass, true);
3834 toggleClass(ghostEl, options.dragClass, true);
3835 css(ghostEl, 'transition', '');
3836 css(ghostEl, 'transform', '');
3837 css(ghostEl, 'box-sizing', 'border-box');
3838 css(ghostEl, 'margin', 0);
3839 css(ghostEl, 'top', rect.top);
3840 css(ghostEl, 'left', rect.left);
3841 css(ghostEl, 'width', rect.width);
3842 css(ghostEl, 'height', rect.height);
3843 css(ghostEl, 'opacity', '0.8');
3844 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
3845 css(ghostEl, 'zIndex', '100000');
3846 css(ghostEl, 'pointerEvents', 'none');
3847 Sortable.ghost = ghostEl;
3848 container.appendChild(ghostEl);
3849
3850 // Set transform-origin
3851 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
3852 }
3853 },
3854 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
3855 var _this = this;
3856 var dataTransfer = evt.dataTransfer;
3857 var options = _this.options;
3858 pluginEvent('dragStart', this, {
3859 evt: evt
3860 });
3861 if (Sortable.eventCanceled) {
3862 this._onDrop();
3863 return;
3864 }
3865 pluginEvent('setupClone', this);
3866 if (!Sortable.eventCanceled) {
3867 cloneEl = clone(dragEl);
3868 cloneEl.removeAttribute("id");
3869 cloneEl.draggable = false;
3870 cloneEl.style['will-change'] = '';
3871 this._hideClone();
3872 toggleClass(cloneEl, this.options.chosenClass, false);
3873 Sortable.clone = cloneEl;
3874 }
3875
3876 // #1143: IFrame support workaround
3877 _this.cloneId = _nextTick(function () {
3878 pluginEvent('clone', _this);
3879 if (Sortable.eventCanceled) return;
3880 if (!_this.options.removeCloneOnHide) {
3881 rootEl.insertBefore(cloneEl, dragEl);
3882 }
3883 _this._hideClone();
3884 _dispatchEvent({
3885 sortable: _this,
3886 name: 'clone'
3887 });
3888 });
3889 !fallback && toggleClass(dragEl, options.dragClass, true);
3890
3891 // Set proper drop events
3892 if (fallback) {
3893 ignoreNextClick = true;
3894 _this._loopId = setInterval(_this._emulateDragOver, 50);
3895 } else {
3896 // Undo what was set in _prepareDragStart before drag started
3897 off(document, 'mouseup', _this._onDrop);
3898 off(document, 'touchend', _this._onDrop);
3899 off(document, 'touchcancel', _this._onDrop);
3900 if (dataTransfer) {
3901 dataTransfer.effectAllowed = 'move';
3902 options.setData && options.setData.call(_this, dataTransfer, dragEl);
3903 }
3904 on(document, 'drop', _this);
3905
3906 // #1276 fix:
3907 css(dragEl, 'transform', 'translateZ(0)');
3908 }
3909 awaitingDragStarted = true;
3910 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
3911 on(document, 'selectstart', _this);
3912 moved = true;
3913 window.getSelection().removeAllRanges();
3914 if (Safari) {
3915 css(document.body, 'user-select', 'none');
3916 }
3917 },
3918 // Returns true - if no further action is needed (either inserted or another condition)
3919 _onDragOver: function _onDragOver( /**Event*/evt) {
3920 var el = this.el,
3921 target = evt.target,
3922 dragRect,
3923 targetRect,
3924 revert,
3925 options = this.options,
3926 group = options.group,
3927 activeSortable = Sortable.active,
3928 isOwner = activeGroup === group,
3929 canSort = options.sort,
3930 fromSortable = putSortable || activeSortable,
3931 vertical,
3932 _this = this,
3933 completedFired = false;
3934 if (_silent) return;
3935 function dragOverEvent(name, extra) {
3936 pluginEvent(name, _this, _objectSpread2({
3937 evt: evt,
3938 isOwner: isOwner,
3939 axis: vertical ? 'vertical' : 'horizontal',
3940 revert: revert,
3941 dragRect: dragRect,
3942 targetRect: targetRect,
3943 canSort: canSort,
3944 fromSortable: fromSortable,
3945 target: target,
3946 completed: completed,
3947 onMove: function onMove(target, after) {
3948 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
3949 },
3950 changed: changed
3951 }, extra));
3952 }
3953
3954 // Capture animation state
3955 function capture() {
3956 dragOverEvent('dragOverAnimationCapture');
3957 _this.captureAnimationState();
3958 if (_this !== fromSortable) {
3959 fromSortable.captureAnimationState();
3960 }
3961 }
3962
3963 // Return invocation when dragEl is inserted (or completed)
3964 function completed(insertion) {
3965 dragOverEvent('dragOverCompleted', {
3966 insertion: insertion
3967 });
3968 if (insertion) {
3969 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3970 if (isOwner) {
3971 activeSortable._hideClone();
3972 } else {
3973 activeSortable._showClone(_this);
3974 }
3975 if (_this !== fromSortable) {
3976 // Set ghost class to new sortable's ghost class
3977 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
3978 toggleClass(dragEl, options.ghostClass, true);
3979 }
3980 if (putSortable !== _this && _this !== Sortable.active) {
3981 putSortable = _this;
3982 } else if (_this === Sortable.active && putSortable) {
3983 putSortable = null;
3984 }
3985
3986 // Animation
3987 if (fromSortable === _this) {
3988 _this._ignoreWhileAnimating = target;
3989 }
3990 _this.animateAll(function () {
3991 dragOverEvent('dragOverAnimationComplete');
3992 _this._ignoreWhileAnimating = null;
3993 });
3994 if (_this !== fromSortable) {
3995 fromSortable.animateAll();
3996 fromSortable._ignoreWhileAnimating = null;
3997 }
3998 }
3999
4000 // Null lastTarget if it is not inside a previously swapped element
4001 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
4002 lastTarget = null;
4003 }
4004
4005 // no bubbling and not fallback
4006 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
4007 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
4008
4009 // Do not detect for empty insert if already inserted
4010 !insertion && nearestEmptyInsertDetectEvent(evt);
4011 }
4012 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
4013 return completedFired = true;
4014 }
4015
4016 // Call when dragEl has been inserted
4017 function changed() {
4018 newIndex = index(dragEl);
4019 newDraggableIndex = index(dragEl, options.draggable);
4020 _dispatchEvent({
4021 sortable: _this,
4022 name: 'change',
4023 toEl: el,
4024 newIndex: newIndex,
4025 newDraggableIndex: newDraggableIndex,
4026 originalEvent: evt
4027 });
4028 }
4029 if (evt.preventDefault !== void 0) {
4030 evt.cancelable && evt.preventDefault();
4031 }
4032 target = closest(target, options.draggable, el, true);
4033 dragOverEvent('dragOver');
4034 if (Sortable.eventCanceled) return completedFired;
4035 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
4036 return completed(false);
4037 }
4038 ignoreNextClick = false;
4039 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
4040 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
4041 vertical = this._getDirection(evt, target) === 'vertical';
4042 dragRect = getRect(dragEl);
4043 dragOverEvent('dragOverValid');
4044 if (Sortable.eventCanceled) return completedFired;
4045 if (revert) {
4046 parentEl = rootEl; // actualization
4047 capture();
4048 this._hideClone();
4049 dragOverEvent('revert');
4050 if (!Sortable.eventCanceled) {
4051 if (nextEl) {
4052 rootEl.insertBefore(dragEl, nextEl);
4053 } else {
4054 rootEl.appendChild(dragEl);
4055 }
4056 }
4057 return completed(true);
4058 }
4059 var elLastChild = lastChild(el, options.draggable);
4060 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
4061 // Insert to end of list
4062
4063 // If already at end of list: Do not insert
4064 if (elLastChild === dragEl) {
4065 return completed(false);
4066 }
4067
4068 // if there is a last element, it is the target
4069 if (elLastChild && el === evt.target) {
4070 target = elLastChild;
4071 }
4072 if (target) {
4073 targetRect = getRect(target);
4074 }
4075 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
4076 capture();
4077 if (elLastChild && elLastChild.nextSibling) {
4078 // the last draggable element is not the last node
4079 el.insertBefore(dragEl, elLastChild.nextSibling);
4080 } else {
4081 el.appendChild(dragEl);
4082 }
4083 parentEl = el; // actualization
4084
4085 changed();
4086 return completed(true);
4087 }
4088 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
4089 // Insert to start of list
4090 var firstChild = getChild(el, 0, options, true);
4091 if (firstChild === dragEl) {
4092 return completed(false);
4093 }
4094 target = firstChild;
4095 targetRect = getRect(target);
4096 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
4097 capture();
4098 el.insertBefore(dragEl, firstChild);
4099 parentEl = el; // actualization
4100
4101 changed();
4102 return completed(true);
4103 }
4104 } else if (target.parentNode === el) {
4105 targetRect = getRect(target);
4106 var direction = 0,
4107 targetBeforeFirstSwap,
4108 differentLevel = dragEl.parentNode !== el,
4109 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
4110 side1 = vertical ? 'top' : 'left',
4111 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
4112 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
4113 if (lastTarget !== target) {
4114 targetBeforeFirstSwap = targetRect[side1];
4115 pastFirstInvertThresh = false;
4116 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
4117 }
4118 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
4119 var sibling;
4120 if (direction !== 0) {
4121 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
4122 var dragIndex = index(dragEl);
4123 do {
4124 dragIndex -= direction;
4125 sibling = parentEl.children[dragIndex];
4126 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
4127 }
4128 // If dragEl is already beside target: Do not insert
4129 if (direction === 0 || sibling === target) {
4130 return completed(false);
4131 }
4132 lastTarget = target;
4133 lastDirection = direction;
4134 var nextSibling = target.nextElementSibling,
4135 after = false;
4136 after = direction === 1;
4137 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
4138 if (moveVector !== false) {
4139 if (moveVector === 1 || moveVector === -1) {
4140 after = moveVector === 1;
4141 }
4142 _silent = true;
4143 setTimeout(_unsilent, 30);
4144 capture();
4145 if (after && !nextSibling) {
4146 el.appendChild(dragEl);
4147 } else {
4148 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
4149 }
4150
4151 // Undo chrome's scroll adjustment (has no effect on other browsers)
4152 if (scrolledPastTop) {
4153 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
4154 }
4155 parentEl = dragEl.parentNode; // actualization
4156
4157 // must be done before animation
4158 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
4159 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
4160 }
4161 changed();
4162 return completed(true);
4163 }
4164 }
4165 if (el.contains(dragEl)) {
4166 return completed(false);
4167 }
4168 }
4169 return false;
4170 },
4171 _ignoreWhileAnimating: null,
4172 _offMoveEvents: function _offMoveEvents() {
4173 off(document, 'mousemove', this._onTouchMove);
4174 off(document, 'touchmove', this._onTouchMove);
4175 off(document, 'pointermove', this._onTouchMove);
4176 off(document, 'dragover', nearestEmptyInsertDetectEvent);
4177 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
4178 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
4179 },
4180 _offUpEvents: function _offUpEvents() {
4181 var ownerDocument = this.el.ownerDocument;
4182 off(ownerDocument, 'mouseup', this._onDrop);
4183 off(ownerDocument, 'touchend', this._onDrop);
4184 off(ownerDocument, 'pointerup', this._onDrop);
4185 off(ownerDocument, 'pointercancel', this._onDrop);
4186 off(ownerDocument, 'touchcancel', this._onDrop);
4187 off(document, 'selectstart', this);
4188 },
4189 _onDrop: function _onDrop( /**Event*/evt) {
4190 var el = this.el,
4191 options = this.options;
4192
4193 // Get the index of the dragged element within its parent
4194 newIndex = index(dragEl);
4195 newDraggableIndex = index(dragEl, options.draggable);
4196 pluginEvent('drop', this, {
4197 evt: evt
4198 });
4199 parentEl = dragEl && dragEl.parentNode;
4200
4201 // Get again after plugin event
4202 newIndex = index(dragEl);
4203 newDraggableIndex = index(dragEl, options.draggable);
4204 if (Sortable.eventCanceled) {
4205 this._nulling();
4206 return;
4207 }
4208 awaitingDragStarted = false;
4209 isCircumstantialInvert = false;
4210 pastFirstInvertThresh = false;
4211 clearInterval(this._loopId);
4212 clearTimeout(this._dragStartTimer);
4213 _cancelNextTick(this.cloneId);
4214 _cancelNextTick(this._dragStartId);
4215
4216 // Unbind events
4217 if (this.nativeDraggable) {
4218 off(document, 'drop', this);
4219 off(el, 'dragstart', this._onDragStart);
4220 }
4221 this._offMoveEvents();
4222 this._offUpEvents();
4223 if (Safari) {
4224 css(document.body, 'user-select', '');
4225 }
4226 css(dragEl, 'transform', '');
4227 if (evt) {
4228 if (moved) {
4229 evt.cancelable && evt.preventDefault();
4230 !options.dropBubble && evt.stopPropagation();
4231 }
4232 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
4233 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
4234 // Remove clone(s)
4235 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
4236 }
4237 if (dragEl) {
4238 if (this.nativeDraggable) {
4239 off(dragEl, 'dragend', this);
4240 }
4241 _disableDraggable(dragEl);
4242 dragEl.style['will-change'] = '';
4243
4244 // Remove classes
4245 // ghostClass is added in dragStarted
4246 if (moved && !awaitingDragStarted) {
4247 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
4248 }
4249 toggleClass(dragEl, this.options.chosenClass, false);
4250
4251 // Drag stop event
4252 _dispatchEvent({
4253 sortable: this,
4254 name: 'unchoose',
4255 toEl: parentEl,
4256 newIndex: null,
4257 newDraggableIndex: null,
4258 originalEvent: evt
4259 });
4260 if (rootEl !== parentEl) {
4261 if (newIndex >= 0) {
4262 // Add event
4263 _dispatchEvent({
4264 rootEl: parentEl,
4265 name: 'add',
4266 toEl: parentEl,
4267 fromEl: rootEl,
4268 originalEvent: evt
4269 });
4270
4271 // Remove event
4272 _dispatchEvent({
4273 sortable: this,
4274 name: 'remove',
4275 toEl: parentEl,
4276 originalEvent: evt
4277 });
4278
4279 // drag from one list and drop into another
4280 _dispatchEvent({
4281 rootEl: parentEl,
4282 name: 'sort',
4283 toEl: parentEl,
4284 fromEl: rootEl,
4285 originalEvent: evt
4286 });
4287 _dispatchEvent({
4288 sortable: this,
4289 name: 'sort',
4290 toEl: parentEl,
4291 originalEvent: evt
4292 });
4293 }
4294 putSortable && putSortable.save();
4295 } else {
4296 if (newIndex !== oldIndex) {
4297 if (newIndex >= 0) {
4298 // drag & drop within the same list
4299 _dispatchEvent({
4300 sortable: this,
4301 name: 'update',
4302 toEl: parentEl,
4303 originalEvent: evt
4304 });
4305 _dispatchEvent({
4306 sortable: this,
4307 name: 'sort',
4308 toEl: parentEl,
4309 originalEvent: evt
4310 });
4311 }
4312 }
4313 }
4314 if (Sortable.active) {
4315 /* jshint eqnull:true */
4316 if (newIndex == null || newIndex === -1) {
4317 newIndex = oldIndex;
4318 newDraggableIndex = oldDraggableIndex;
4319 }
4320 _dispatchEvent({
4321 sortable: this,
4322 name: 'end',
4323 toEl: parentEl,
4324 originalEvent: evt
4325 });
4326
4327 // Save sorting
4328 this.save();
4329 }
4330 }
4331 }
4332 this._nulling();
4333 },
4334 _nulling: function _nulling() {
4335 pluginEvent('nulling', this);
4336 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;
4337 var el = this.el;
4338 savedInputChecked.forEach(function (checkEl) {
4339 if (el.contains(checkEl)) {
4340 checkEl.checked = true;
4341 }
4342 });
4343 savedInputChecked.length = lastDx = lastDy = 0;
4344 },
4345 handleEvent: function handleEvent( /**Event*/evt) {
4346 switch (evt.type) {
4347 case 'drop':
4348 case 'dragend':
4349 this._onDrop(evt);
4350 break;
4351 case 'dragenter':
4352 case 'dragover':
4353 if (dragEl) {
4354 this._onDragOver(evt);
4355 _globalDragOver(evt);
4356 }
4357 break;
4358 case 'selectstart':
4359 evt.preventDefault();
4360 break;
4361 }
4362 },
4363 /**
4364 * Serializes the item into an array of string.
4365 * @returns {String[]}
4366 */
4367 toArray: function toArray() {
4368 var order = [],
4369 el,
4370 children = this.el.children,
4371 i = 0,
4372 n = children.length,
4373 options = this.options;
4374 for (; i < n; i++) {
4375 el = children[i];
4376 if (closest(el, options.draggable, this.el, false)) {
4377 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
4378 }
4379 }
4380 return order;
4381 },
4382 /**
4383 * Sorts the elements according to the array.
4384 * @param {String[]} order order of the items
4385 */
4386 sort: function sort(order, useAnimation) {
4387 var items = {},
4388 rootEl = this.el;
4389 this.toArray().forEach(function (id, i) {
4390 var el = rootEl.children[i];
4391 if (closest(el, this.options.draggable, rootEl, false)) {
4392 items[id] = el;
4393 }
4394 }, this);
4395 useAnimation && this.captureAnimationState();
4396 order.forEach(function (id) {
4397 if (items[id]) {
4398 rootEl.removeChild(items[id]);
4399 rootEl.appendChild(items[id]);
4400 }
4401 });
4402 useAnimation && this.animateAll();
4403 },
4404 /**
4405 * Save the current sorting
4406 */
4407 save: function save() {
4408 var store = this.options.store;
4409 store && store.set && store.set(this);
4410 },
4411 /**
4412 * 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.
4413 * @param {HTMLElement} el
4414 * @param {String} [selector] default: `options.draggable`
4415 * @returns {HTMLElement|null}
4416 */
4417 closest: function closest$1(el, selector) {
4418 return closest(el, selector || this.options.draggable, this.el, false);
4419 },
4420 /**
4421 * Set/get option
4422 * @param {string} name
4423 * @param {*} [value]
4424 * @returns {*}
4425 */
4426 option: function option(name, value) {
4427 var options = this.options;
4428 if (value === void 0) {
4429 return options[name];
4430 } else {
4431 var modifiedValue = PluginManager.modifyOption(this, name, value);
4432 if (typeof modifiedValue !== 'undefined') {
4433 options[name] = modifiedValue;
4434 } else {
4435 options[name] = value;
4436 }
4437 if (name === 'group') {
4438 _prepareGroup(options);
4439 }
4440 }
4441 },
4442 /**
4443 * Destroy
4444 */
4445 destroy: function destroy() {
4446 pluginEvent('destroy', this);
4447 var el = this.el;
4448 el[expando] = null;
4449 off(el, 'mousedown', this._onTapStart);
4450 off(el, 'touchstart', this._onTapStart);
4451 off(el, 'pointerdown', this._onTapStart);
4452 if (this.nativeDraggable) {
4453 off(el, 'dragover', this);
4454 off(el, 'dragenter', this);
4455 }
4456 // Remove draggable attributes
4457 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
4458 el.removeAttribute('draggable');
4459 });
4460 this._onDrop();
4461 this._disableDelayedDragEvents();
4462 sortables.splice(sortables.indexOf(this.el), 1);
4463 this.el = el = null;
4464 },
4465 _hideClone: function _hideClone() {
4466 if (!cloneHidden) {
4467 pluginEvent('hideClone', this);
4468 if (Sortable.eventCanceled) return;
4469 css(cloneEl, 'display', 'none');
4470 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
4471 cloneEl.parentNode.removeChild(cloneEl);
4472 }
4473 cloneHidden = true;
4474 }
4475 },
4476 _showClone: function _showClone(putSortable) {
4477 if (putSortable.lastPutMode !== 'clone') {
4478 this._hideClone();
4479 return;
4480 }
4481 if (cloneHidden) {
4482 pluginEvent('showClone', this);
4483 if (Sortable.eventCanceled) return;
4484
4485 // show clone at dragEl or original position
4486 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
4487 rootEl.insertBefore(cloneEl, dragEl);
4488 } else if (nextEl) {
4489 rootEl.insertBefore(cloneEl, nextEl);
4490 } else {
4491 rootEl.appendChild(cloneEl);
4492 }
4493 if (this.options.group.revertClone) {
4494 this.animate(dragEl, cloneEl);
4495 }
4496 css(cloneEl, 'display', '');
4497 cloneHidden = false;
4498 }
4499 }
4500 };
4501 function _globalDragOver( /**Event*/evt) {
4502 if (evt.dataTransfer) {
4503 evt.dataTransfer.dropEffect = 'move';
4504 }
4505 evt.cancelable && evt.preventDefault();
4506 }
4507 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
4508 var evt,
4509 sortable = fromEl[expando],
4510 onMoveFn = sortable.options.onMove,
4511 retVal;
4512 // Support for new CustomEvent feature
4513 if (window.CustomEvent && !IE11OrLess && !Edge) {
4514 evt = new CustomEvent('move', {
4515 bubbles: true,
4516 cancelable: true
4517 });
4518 } else {
4519 evt = document.createEvent('Event');
4520 evt.initEvent('move', true, true);
4521 }
4522 evt.to = toEl;
4523 evt.from = fromEl;
4524 evt.dragged = dragEl;
4525 evt.draggedRect = dragRect;
4526 evt.related = targetEl || toEl;
4527 evt.relatedRect = targetRect || getRect(toEl);
4528 evt.willInsertAfter = willInsertAfter;
4529 evt.originalEvent = originalEvent;
4530 fromEl.dispatchEvent(evt);
4531 if (onMoveFn) {
4532 retVal = onMoveFn.call(sortable, evt, originalEvent);
4533 }
4534 return retVal;
4535 }
4536 function _disableDraggable(el) {
4537 el.draggable = false;
4538 }
4539 function _unsilent() {
4540 _silent = false;
4541 }
4542 function _ghostIsFirst(evt, vertical, sortable) {
4543 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
4544 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4545 var spacer = 10;
4546 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;
4547 }
4548 function _ghostIsLast(evt, vertical, sortable) {
4549 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
4550 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4551 var spacer = 10;
4552 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;
4553 }
4554 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
4555 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
4556 targetLength = vertical ? targetRect.height : targetRect.width,
4557 targetS1 = vertical ? targetRect.top : targetRect.left,
4558 targetS2 = vertical ? targetRect.bottom : targetRect.right,
4559 invert = false;
4560 if (!invertSwap) {
4561 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
4562 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
4563 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
4564 // check if past first invert threshold on side opposite of lastDirection
4565 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
4566 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
4567 pastFirstInvertThresh = true;
4568 }
4569 if (!pastFirstInvertThresh) {
4570 // dragEl shadow (target move distance shadow)
4571 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
4572 : mouseOnAxis > targetS2 - targetMoveDistance) {
4573 return -lastDirection;
4574 }
4575 } else {
4576 invert = true;
4577 }
4578 } else {
4579 // Regular
4580 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
4581 return _getInsertDirection(target);
4582 }
4583 }
4584 }
4585 invert = invert || invertSwap;
4586 if (invert) {
4587 // Invert of regular
4588 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
4589 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
4590 }
4591 }
4592 return 0;
4593 }
4594
4595 /**
4596 * Gets the direction dragEl must be swapped relative to target in order to make it
4597 * seem that dragEl has been "inserted" into that element's position
4598 * @param {HTMLElement} target The target whose position dragEl is being inserted at
4599 * @return {Number} Direction dragEl must be swapped
4600 */
4601 function _getInsertDirection(target) {
4602 if (index(dragEl) < index(target)) {
4603 return 1;
4604 } else {
4605 return -1;
4606 }
4607 }
4608
4609 /**
4610 * Generate id
4611 * @param {HTMLElement} el
4612 * @returns {String}
4613 * @private
4614 */
4615 function _generateId(el) {
4616 var str = el.tagName + el.className + el.src + el.href + el.textContent,
4617 i = str.length,
4618 sum = 0;
4619 while (i--) {
4620 sum += str.charCodeAt(i);
4621 }
4622 return sum.toString(36);
4623 }
4624 function _saveInputCheckedState(root) {
4625 savedInputChecked.length = 0;
4626 var inputs = root.getElementsByTagName('input');
4627 var idx = inputs.length;
4628 while (idx--) {
4629 var el = inputs[idx];
4630 el.checked && savedInputChecked.push(el);
4631 }
4632 }
4633 function _nextTick(fn) {
4634 return setTimeout(fn, 0);
4635 }
4636 function _cancelNextTick(id) {
4637 return clearTimeout(id);
4638 }
4639
4640 // Fixed #973:
4641 if (documentExists) {
4642 on(document, 'touchmove', function (evt) {
4643 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
4644 evt.preventDefault();
4645 }
4646 });
4647 }
4648
4649 // Export utils
4650 Sortable.utils = {
4651 on: on,
4652 off: off,
4653 css: css,
4654 find: find,
4655 is: function is(el, selector) {
4656 return !!closest(el, selector, el, false);
4657 },
4658 extend: extend,
4659 throttle: throttle,
4660 closest: closest,
4661 toggleClass: toggleClass,
4662 clone: clone,
4663 index: index,
4664 nextTick: _nextTick,
4665 cancelNextTick: _cancelNextTick,
4666 detectDirection: _detectDirection,
4667 getChild: getChild,
4668 expando: expando
4669 };
4670
4671 /**
4672 * Get the Sortable instance of an element
4673 * @param {HTMLElement} element The element
4674 * @return {Sortable|undefined} The instance of Sortable
4675 */
4676 Sortable.get = function (element) {
4677 return element[expando];
4678 };
4679
4680 /**
4681 * Mount a plugin to Sortable
4682 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
4683 */
4684 Sortable.mount = function () {
4685 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
4686 plugins[_key] = arguments[_key];
4687 }
4688 if (plugins[0].constructor === Array) plugins = plugins[0];
4689 plugins.forEach(function (plugin) {
4690 if (!plugin.prototype || !plugin.prototype.constructor) {
4691 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
4692 }
4693 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
4694 PluginManager.mount(plugin);
4695 });
4696 };
4697
4698 /**
4699 * Create sortable instance
4700 * @param {HTMLElement} el
4701 * @param {Object} [options]
4702 */
4703 Sortable.create = function (el, options) {
4704 return new Sortable(el, options);
4705 };
4706
4707 // Export
4708 Sortable.version = version;
4709
4710 var autoScrolls = [],
4711 scrollEl,
4712 scrollRootEl,
4713 scrolling = false,
4714 lastAutoScrollX,
4715 lastAutoScrollY,
4716 touchEvt$1,
4717 pointerElemChangedInterval;
4718 function AutoScrollPlugin() {
4719 function AutoScroll() {
4720 this.defaults = {
4721 scroll: true,
4722 forceAutoScrollFallback: false,
4723 scrollSensitivity: 30,
4724 scrollSpeed: 10,
4725 bubbleScroll: true
4726 };
4727
4728 // Bind all private methods
4729 for (var fn in this) {
4730 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4731 this[fn] = this[fn].bind(this);
4732 }
4733 }
4734 }
4735 AutoScroll.prototype = {
4736 dragStarted: function dragStarted(_ref) {
4737 var originalEvent = _ref.originalEvent;
4738 if (this.sortable.nativeDraggable) {
4739 on(document, 'dragover', this._handleAutoScroll);
4740 } else {
4741 if (this.options.supportPointer) {
4742 on(document, 'pointermove', this._handleFallbackAutoScroll);
4743 } else if (originalEvent.touches) {
4744 on(document, 'touchmove', this._handleFallbackAutoScroll);
4745 } else {
4746 on(document, 'mousemove', this._handleFallbackAutoScroll);
4747 }
4748 }
4749 },
4750 dragOverCompleted: function dragOverCompleted(_ref2) {
4751 var originalEvent = _ref2.originalEvent;
4752 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
4753 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
4754 this._handleAutoScroll(originalEvent);
4755 }
4756 },
4757 drop: function drop() {
4758 if (this.sortable.nativeDraggable) {
4759 off(document, 'dragover', this._handleAutoScroll);
4760 } else {
4761 off(document, 'pointermove', this._handleFallbackAutoScroll);
4762 off(document, 'touchmove', this._handleFallbackAutoScroll);
4763 off(document, 'mousemove', this._handleFallbackAutoScroll);
4764 }
4765 clearPointerElemChangedInterval();
4766 clearAutoScrolls();
4767 cancelThrottle();
4768 },
4769 nulling: function nulling() {
4770 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
4771 autoScrolls.length = 0;
4772 },
4773 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
4774 this._handleAutoScroll(evt, true);
4775 },
4776 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
4777 var _this = this;
4778 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4779 y = (evt.touches ? evt.touches[0] : evt).clientY,
4780 elem = document.elementFromPoint(x, y);
4781 touchEvt$1 = evt;
4782
4783 // IE does not seem to have native autoscroll,
4784 // Edge's autoscroll seems too conditional,
4785 // MACOS Safari does not have autoscroll,
4786 // Firefox and Chrome are good
4787 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
4788 autoScroll(evt, this.options, elem, fallback);
4789
4790 // Listener for pointer element change
4791 var ogElemScroller = getParentAutoScrollElement(elem, true);
4792 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
4793 pointerElemChangedInterval && clearPointerElemChangedInterval();
4794 // Detect for pointer elem change, emulating native DnD behaviour
4795 pointerElemChangedInterval = setInterval(function () {
4796 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
4797 if (newElem !== ogElemScroller) {
4798 ogElemScroller = newElem;
4799 clearAutoScrolls();
4800 }
4801 autoScroll(evt, _this.options, newElem, fallback);
4802 }, 10);
4803 lastAutoScrollX = x;
4804 lastAutoScrollY = y;
4805 }
4806 } else {
4807 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
4808 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
4809 clearAutoScrolls();
4810 return;
4811 }
4812 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
4813 }
4814 }
4815 };
4816 return _extends(AutoScroll, {
4817 pluginName: 'scroll',
4818 initializeByDefault: true
4819 });
4820 }
4821 function clearAutoScrolls() {
4822 autoScrolls.forEach(function (autoScroll) {
4823 clearInterval(autoScroll.pid);
4824 });
4825 autoScrolls = [];
4826 }
4827 function clearPointerElemChangedInterval() {
4828 clearInterval(pointerElemChangedInterval);
4829 }
4830 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
4831 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
4832 if (!options.scroll) return;
4833 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4834 y = (evt.touches ? evt.touches[0] : evt).clientY,
4835 sens = options.scrollSensitivity,
4836 speed = options.scrollSpeed,
4837 winScroller = getWindowScrollingElement();
4838 var scrollThisInstance = false,
4839 scrollCustomFn;
4840
4841 // New scroll root, set scrollEl
4842 if (scrollRootEl !== rootEl) {
4843 scrollRootEl = rootEl;
4844 clearAutoScrolls();
4845 scrollEl = options.scroll;
4846 scrollCustomFn = options.scrollFn;
4847 if (scrollEl === true) {
4848 scrollEl = getParentAutoScrollElement(rootEl, true);
4849 }
4850 }
4851 var layersOut = 0;
4852 var currentParent = scrollEl;
4853 do {
4854 var el = currentParent,
4855 rect = getRect(el),
4856 top = rect.top,
4857 bottom = rect.bottom,
4858 left = rect.left,
4859 right = rect.right,
4860 width = rect.width,
4861 height = rect.height,
4862 canScrollX = void 0,
4863 canScrollY = void 0,
4864 scrollWidth = el.scrollWidth,
4865 scrollHeight = el.scrollHeight,
4866 elCSS = css(el),
4867 scrollPosX = el.scrollLeft,
4868 scrollPosY = el.scrollTop;
4869 if (el === winScroller) {
4870 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
4871 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
4872 } else {
4873 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
4874 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
4875 }
4876 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
4877 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
4878 if (!autoScrolls[layersOut]) {
4879 for (var i = 0; i <= layersOut; i++) {
4880 if (!autoScrolls[i]) {
4881 autoScrolls[i] = {};
4882 }
4883 }
4884 }
4885 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
4886 autoScrolls[layersOut].el = el;
4887 autoScrolls[layersOut].vx = vx;
4888 autoScrolls[layersOut].vy = vy;
4889 clearInterval(autoScrolls[layersOut].pid);
4890 if (vx != 0 || vy != 0) {
4891 scrollThisInstance = true;
4892 /* jshint loopfunc:true */
4893 autoScrolls[layersOut].pid = setInterval(function () {
4894 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
4895 if (isFallback && this.layer === 0) {
4896 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
4897 }
4898 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
4899 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
4900 if (typeof scrollCustomFn === 'function') {
4901 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
4902 return;
4903 }
4904 }
4905 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
4906 }.bind({
4907 layer: layersOut
4908 }), 24);
4909 }
4910 }
4911 layersOut++;
4912 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
4913 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
4914 }, 30);
4915
4916 var drop = function drop(_ref) {
4917 var originalEvent = _ref.originalEvent,
4918 putSortable = _ref.putSortable,
4919 dragEl = _ref.dragEl,
4920 activeSortable = _ref.activeSortable,
4921 dispatchSortableEvent = _ref.dispatchSortableEvent,
4922 hideGhostForTarget = _ref.hideGhostForTarget,
4923 unhideGhostForTarget = _ref.unhideGhostForTarget;
4924 if (!originalEvent) return;
4925 var toSortable = putSortable || activeSortable;
4926 hideGhostForTarget();
4927 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
4928 var target = document.elementFromPoint(touch.clientX, touch.clientY);
4929 unhideGhostForTarget();
4930 if (toSortable && !toSortable.el.contains(target)) {
4931 dispatchSortableEvent('spill');
4932 this.onSpill({
4933 dragEl: dragEl,
4934 putSortable: putSortable
4935 });
4936 }
4937 };
4938 function Revert() {}
4939 Revert.prototype = {
4940 startIndex: null,
4941 dragStart: function dragStart(_ref2) {
4942 var oldDraggableIndex = _ref2.oldDraggableIndex;
4943 this.startIndex = oldDraggableIndex;
4944 },
4945 onSpill: function onSpill(_ref3) {
4946 var dragEl = _ref3.dragEl,
4947 putSortable = _ref3.putSortable;
4948 this.sortable.captureAnimationState();
4949 if (putSortable) {
4950 putSortable.captureAnimationState();
4951 }
4952 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
4953 if (nextSibling) {
4954 this.sortable.el.insertBefore(dragEl, nextSibling);
4955 } else {
4956 this.sortable.el.appendChild(dragEl);
4957 }
4958 this.sortable.animateAll();
4959 if (putSortable) {
4960 putSortable.animateAll();
4961 }
4962 },
4963 drop: drop
4964 };
4965 _extends(Revert, {
4966 pluginName: 'revertOnSpill'
4967 });
4968 function Remove() {}
4969 Remove.prototype = {
4970 onSpill: function onSpill(_ref4) {
4971 var dragEl = _ref4.dragEl,
4972 putSortable = _ref4.putSortable;
4973 var parentSortable = putSortable || this.sortable;
4974 parentSortable.captureAnimationState();
4975 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
4976 parentSortable.animateAll();
4977 },
4978 drop: drop
4979 };
4980 _extends(Remove, {
4981 pluginName: 'removeOnSpill'
4982 });
4983
4984 var lastSwapEl;
4985 function SwapPlugin() {
4986 function Swap() {
4987 this.defaults = {
4988 swapClass: 'sortable-swap-highlight'
4989 };
4990 }
4991 Swap.prototype = {
4992 dragStart: function dragStart(_ref) {
4993 var dragEl = _ref.dragEl;
4994 lastSwapEl = dragEl;
4995 },
4996 dragOverValid: function dragOverValid(_ref2) {
4997 var completed = _ref2.completed,
4998 target = _ref2.target,
4999 onMove = _ref2.onMove,
5000 activeSortable = _ref2.activeSortable,
5001 changed = _ref2.changed,
5002 cancel = _ref2.cancel;
5003 if (!activeSortable.options.swap) return;
5004 var el = this.sortable.el,
5005 options = this.options;
5006 if (target && target !== el) {
5007 var prevSwapEl = lastSwapEl;
5008 if (onMove(target) !== false) {
5009 toggleClass(target, options.swapClass, true);
5010 lastSwapEl = target;
5011 } else {
5012 lastSwapEl = null;
5013 }
5014 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
5015 toggleClass(prevSwapEl, options.swapClass, false);
5016 }
5017 }
5018 changed();
5019 completed(true);
5020 cancel();
5021 },
5022 drop: function drop(_ref3) {
5023 var activeSortable = _ref3.activeSortable,
5024 putSortable = _ref3.putSortable,
5025 dragEl = _ref3.dragEl;
5026 var toSortable = putSortable || this.sortable;
5027 var options = this.options;
5028 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
5029 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
5030 if (dragEl !== lastSwapEl) {
5031 toSortable.captureAnimationState();
5032 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
5033 swapNodes(dragEl, lastSwapEl);
5034 toSortable.animateAll();
5035 if (toSortable !== activeSortable) activeSortable.animateAll();
5036 }
5037 }
5038 },
5039 nulling: function nulling() {
5040 lastSwapEl = null;
5041 }
5042 };
5043 return _extends(Swap, {
5044 pluginName: 'swap',
5045 eventProperties: function eventProperties() {
5046 return {
5047 swapItem: lastSwapEl
5048 };
5049 }
5050 });
5051 }
5052 function swapNodes(n1, n2) {
5053 var p1 = n1.parentNode,
5054 p2 = n2.parentNode,
5055 i1,
5056 i2;
5057 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
5058 i1 = index(n1);
5059 i2 = index(n2);
5060 if (p1.isEqualNode(p2) && i1 < i2) {
5061 i2++;
5062 }
5063 p1.insertBefore(n2, p1.children[i1]);
5064 p2.insertBefore(n1, p2.children[i2]);
5065 }
5066
5067 var multiDragElements = [],
5068 multiDragClones = [],
5069 lastMultiDragSelect,
5070 // for selection with modifier key down (SHIFT)
5071 multiDragSortable,
5072 initialFolding = false,
5073 // Initial multi-drag fold when drag started
5074 folding = false,
5075 // Folding any other time
5076 dragStarted = false,
5077 dragEl$1,
5078 clonesFromRect,
5079 clonesHidden;
5080 function MultiDragPlugin() {
5081 function MultiDrag(sortable) {
5082 // Bind all private methods
5083 for (var fn in this) {
5084 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
5085 this[fn] = this[fn].bind(this);
5086 }
5087 }
5088 if (!sortable.options.avoidImplicitDeselect) {
5089 if (sortable.options.supportPointer) {
5090 on(document, 'pointerup', this._deselectMultiDrag);
5091 } else {
5092 on(document, 'mouseup', this._deselectMultiDrag);
5093 on(document, 'touchend', this._deselectMultiDrag);
5094 }
5095 }
5096 on(document, 'keydown', this._checkKeyDown);
5097 on(document, 'keyup', this._checkKeyUp);
5098 this.defaults = {
5099 selectedClass: 'sortable-selected',
5100 multiDragKey: null,
5101 avoidImplicitDeselect: false,
5102 setData: function setData(dataTransfer, dragEl) {
5103 var data = '';
5104 if (multiDragElements.length && multiDragSortable === sortable) {
5105 multiDragElements.forEach(function (multiDragElement, i) {
5106 data += (!i ? '' : ', ') + multiDragElement.textContent;
5107 });
5108 } else {
5109 data = dragEl.textContent;
5110 }
5111 dataTransfer.setData('Text', data);
5112 }
5113 };
5114 }
5115 MultiDrag.prototype = {
5116 multiDragKeyDown: false,
5117 isMultiDrag: false,
5118 delayStartGlobal: function delayStartGlobal(_ref) {
5119 var dragged = _ref.dragEl;
5120 dragEl$1 = dragged;
5121 },
5122 delayEnded: function delayEnded() {
5123 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
5124 },
5125 setupClone: function setupClone(_ref2) {
5126 var sortable = _ref2.sortable,
5127 cancel = _ref2.cancel;
5128 if (!this.isMultiDrag) return;
5129 for (var i = 0; i < multiDragElements.length; i++) {
5130 multiDragClones.push(clone(multiDragElements[i]));
5131 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
5132 multiDragClones[i].draggable = false;
5133 multiDragClones[i].style['will-change'] = '';
5134 toggleClass(multiDragClones[i], this.options.selectedClass, false);
5135 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
5136 }
5137 sortable._hideClone();
5138 cancel();
5139 },
5140 clone: function clone(_ref3) {
5141 var sortable = _ref3.sortable,
5142 rootEl = _ref3.rootEl,
5143 dispatchSortableEvent = _ref3.dispatchSortableEvent,
5144 cancel = _ref3.cancel;
5145 if (!this.isMultiDrag) return;
5146 if (!this.options.removeCloneOnHide) {
5147 if (multiDragElements.length && multiDragSortable === sortable) {
5148 insertMultiDragClones(true, rootEl);
5149 dispatchSortableEvent('clone');
5150 cancel();
5151 }
5152 }
5153 },
5154 showClone: function showClone(_ref4) {
5155 var cloneNowShown = _ref4.cloneNowShown,
5156 rootEl = _ref4.rootEl,
5157 cancel = _ref4.cancel;
5158 if (!this.isMultiDrag) return;
5159 insertMultiDragClones(false, rootEl);
5160 multiDragClones.forEach(function (clone) {
5161 css(clone, 'display', '');
5162 });
5163 cloneNowShown();
5164 clonesHidden = false;
5165 cancel();
5166 },
5167 hideClone: function hideClone(_ref5) {
5168 var _this = this;
5169 var sortable = _ref5.sortable,
5170 cloneNowHidden = _ref5.cloneNowHidden,
5171 cancel = _ref5.cancel;
5172 if (!this.isMultiDrag) return;
5173 multiDragClones.forEach(function (clone) {
5174 css(clone, 'display', 'none');
5175 if (_this.options.removeCloneOnHide && clone.parentNode) {
5176 clone.parentNode.removeChild(clone);
5177 }
5178 });
5179 cloneNowHidden();
5180 clonesHidden = true;
5181 cancel();
5182 },
5183 dragStartGlobal: function dragStartGlobal(_ref6) {
5184 var sortable = _ref6.sortable;
5185 if (!this.isMultiDrag && multiDragSortable) {
5186 multiDragSortable.multiDrag._deselectMultiDrag();
5187 }
5188 multiDragElements.forEach(function (multiDragElement) {
5189 multiDragElement.sortableIndex = index(multiDragElement);
5190 });
5191
5192 // Sort multi-drag elements
5193 multiDragElements = multiDragElements.sort(function (a, b) {
5194 return a.sortableIndex - b.sortableIndex;
5195 });
5196 dragStarted = true;
5197 },
5198 dragStarted: function dragStarted(_ref7) {
5199 var _this2 = this;
5200 var sortable = _ref7.sortable;
5201 if (!this.isMultiDrag) return;
5202 if (this.options.sort) {
5203 // Capture rects,
5204 // hide multi drag elements (by positioning them absolute),
5205 // set multi drag elements rects to dragRect,
5206 // show multi drag elements,
5207 // animate to rects,
5208 // unset rects & remove from DOM
5209
5210 sortable.captureAnimationState();
5211 if (this.options.animation) {
5212 multiDragElements.forEach(function (multiDragElement) {
5213 if (multiDragElement === dragEl$1) return;
5214 css(multiDragElement, 'position', 'absolute');
5215 });
5216 var dragRect = getRect(dragEl$1, false, true, true);
5217 multiDragElements.forEach(function (multiDragElement) {
5218 if (multiDragElement === dragEl$1) return;
5219 setRect(multiDragElement, dragRect);
5220 });
5221 folding = true;
5222 initialFolding = true;
5223 }
5224 }
5225 sortable.animateAll(function () {
5226 folding = false;
5227 initialFolding = false;
5228 if (_this2.options.animation) {
5229 multiDragElements.forEach(function (multiDragElement) {
5230 unsetRect(multiDragElement);
5231 });
5232 }
5233
5234 // Remove all auxiliary multidrag items from el, if sorting enabled
5235 if (_this2.options.sort) {
5236 removeMultiDragElements();
5237 }
5238 });
5239 },
5240 dragOver: function dragOver(_ref8) {
5241 var target = _ref8.target,
5242 completed = _ref8.completed,
5243 cancel = _ref8.cancel;
5244 if (folding && ~multiDragElements.indexOf(target)) {
5245 completed(false);
5246 cancel();
5247 }
5248 },
5249 revert: function revert(_ref9) {
5250 var fromSortable = _ref9.fromSortable,
5251 rootEl = _ref9.rootEl,
5252 sortable = _ref9.sortable,
5253 dragRect = _ref9.dragRect;
5254 if (multiDragElements.length > 1) {
5255 // Setup unfold animation
5256 multiDragElements.forEach(function (multiDragElement) {
5257 sortable.addAnimationState({
5258 target: multiDragElement,
5259 rect: folding ? getRect(multiDragElement) : dragRect
5260 });
5261 unsetRect(multiDragElement);
5262 multiDragElement.fromRect = dragRect;
5263 fromSortable.removeAnimationState(multiDragElement);
5264 });
5265 folding = false;
5266 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
5267 }
5268 },
5269 dragOverCompleted: function dragOverCompleted(_ref10) {
5270 var sortable = _ref10.sortable,
5271 isOwner = _ref10.isOwner,
5272 insertion = _ref10.insertion,
5273 activeSortable = _ref10.activeSortable,
5274 parentEl = _ref10.parentEl,
5275 putSortable = _ref10.putSortable;
5276 var options = this.options;
5277 if (insertion) {
5278 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5279 if (isOwner) {
5280 activeSortable._hideClone();
5281 }
5282 initialFolding = false;
5283 // If leaving sort:false root, or already folding - Fold to new location
5284 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
5285 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
5286 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
5287 multiDragElements.forEach(function (multiDragElement) {
5288 if (multiDragElement === dragEl$1) return;
5289 setRect(multiDragElement, dragRectAbsolute);
5290
5291 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
5292 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
5293 parentEl.appendChild(multiDragElement);
5294 });
5295 folding = true;
5296 }
5297
5298 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
5299 if (!isOwner) {
5300 // Only remove if not folding (folding will remove them anyways)
5301 if (!folding) {
5302 removeMultiDragElements();
5303 }
5304 if (multiDragElements.length > 1) {
5305 var clonesHiddenBefore = clonesHidden;
5306 activeSortable._showClone(sortable);
5307
5308 // Unfold animation for clones if showing from hidden
5309 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
5310 multiDragClones.forEach(function (clone) {
5311 activeSortable.addAnimationState({
5312 target: clone,
5313 rect: clonesFromRect
5314 });
5315 clone.fromRect = clonesFromRect;
5316 clone.thisAnimationDuration = null;
5317 });
5318 }
5319 } else {
5320 activeSortable._showClone(sortable);
5321 }
5322 }
5323 }
5324 },
5325 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
5326 var dragRect = _ref11.dragRect,
5327 isOwner = _ref11.isOwner,
5328 activeSortable = _ref11.activeSortable;
5329 multiDragElements.forEach(function (multiDragElement) {
5330 multiDragElement.thisAnimationDuration = null;
5331 });
5332 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
5333 clonesFromRect = _extends({}, dragRect);
5334 var dragMatrix = matrix(dragEl$1, true);
5335 clonesFromRect.top -= dragMatrix.f;
5336 clonesFromRect.left -= dragMatrix.e;
5337 }
5338 },
5339 dragOverAnimationComplete: function dragOverAnimationComplete() {
5340 if (folding) {
5341 folding = false;
5342 removeMultiDragElements();
5343 }
5344 },
5345 drop: function drop(_ref12) {
5346 var evt = _ref12.originalEvent,
5347 rootEl = _ref12.rootEl,
5348 parentEl = _ref12.parentEl,
5349 sortable = _ref12.sortable,
5350 dispatchSortableEvent = _ref12.dispatchSortableEvent,
5351 oldIndex = _ref12.oldIndex,
5352 putSortable = _ref12.putSortable;
5353 var toSortable = putSortable || this.sortable;
5354 if (!evt) return;
5355 var options = this.options,
5356 children = parentEl.children;
5357
5358 // Multi-drag selection
5359 if (!dragStarted) {
5360 if (options.multiDragKey && !this.multiDragKeyDown) {
5361 this._deselectMultiDrag();
5362 }
5363 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
5364 if (!~multiDragElements.indexOf(dragEl$1)) {
5365 multiDragElements.push(dragEl$1);
5366 dispatchEvent({
5367 sortable: sortable,
5368 rootEl: rootEl,
5369 name: 'select',
5370 targetEl: dragEl$1,
5371 originalEvent: evt
5372 });
5373
5374 // Modifier activated, select from last to dragEl
5375 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
5376 var lastIndex = index(lastMultiDragSelect),
5377 currentIndex = index(dragEl$1);
5378 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
5379 (function () {
5380 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
5381 // (but previous selection existed)
5382 var n, i;
5383 if (currentIndex > lastIndex) {
5384 i = lastIndex;
5385 n = currentIndex;
5386 } else {
5387 i = currentIndex;
5388 n = lastIndex + 1;
5389 }
5390 var filter = options.filter;
5391 for (; i < n; i++) {
5392 if (~multiDragElements.indexOf(children[i])) continue;
5393 // Check if element is draggable
5394 if (!closest(children[i], options.draggable, parentEl, false)) continue;
5395 // Check if element is filtered
5396 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
5397 return closest(children[i], criteria.trim(), parentEl, false);
5398 }));
5399 if (filtered) continue;
5400 toggleClass(children[i], options.selectedClass, true);
5401 multiDragElements.push(children[i]);
5402 dispatchEvent({
5403 sortable: sortable,
5404 rootEl: rootEl,
5405 name: 'select',
5406 targetEl: children[i],
5407 originalEvent: evt
5408 });
5409 }
5410 })();
5411 }
5412 } else {
5413 lastMultiDragSelect = dragEl$1;
5414 }
5415 multiDragSortable = toSortable;
5416 } else {
5417 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
5418 lastMultiDragSelect = null;
5419 dispatchEvent({
5420 sortable: sortable,
5421 rootEl: rootEl,
5422 name: 'deselect',
5423 targetEl: dragEl$1,
5424 originalEvent: evt
5425 });
5426 }
5427 }
5428
5429 // Multi-drag drop
5430 if (dragStarted && this.isMultiDrag) {
5431 folding = false;
5432 // Do not "unfold" after around dragEl if reverted
5433 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
5434 var dragRect = getRect(dragEl$1),
5435 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
5436 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
5437 toSortable.captureAnimationState();
5438 if (!initialFolding) {
5439 if (options.animation) {
5440 dragEl$1.fromRect = dragRect;
5441 multiDragElements.forEach(function (multiDragElement) {
5442 multiDragElement.thisAnimationDuration = null;
5443 if (multiDragElement !== dragEl$1) {
5444 var rect = folding ? getRect(multiDragElement) : dragRect;
5445 multiDragElement.fromRect = rect;
5446
5447 // Prepare unfold animation
5448 toSortable.addAnimationState({
5449 target: multiDragElement,
5450 rect: rect
5451 });
5452 }
5453 });
5454 }
5455
5456 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
5457 // properly they must all be removed
5458 removeMultiDragElements();
5459 multiDragElements.forEach(function (multiDragElement) {
5460 if (children[multiDragIndex]) {
5461 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
5462 } else {
5463 parentEl.appendChild(multiDragElement);
5464 }
5465 multiDragIndex++;
5466 });
5467
5468 // If initial folding is done, the elements may have changed position because they are now
5469 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
5470 // must be fired here as Sortable will not.
5471 if (oldIndex === index(dragEl$1)) {
5472 var update = false;
5473 multiDragElements.forEach(function (multiDragElement) {
5474 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
5475 update = true;
5476 return;
5477 }
5478 });
5479 if (update) {
5480 dispatchSortableEvent('update');
5481 dispatchSortableEvent('sort');
5482 }
5483 }
5484 }
5485
5486 // Must be done after capturing individual rects (scroll bar)
5487 multiDragElements.forEach(function (multiDragElement) {
5488 unsetRect(multiDragElement);
5489 });
5490 toSortable.animateAll();
5491 }
5492 multiDragSortable = toSortable;
5493 }
5494
5495 // Remove clones if necessary
5496 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5497 multiDragClones.forEach(function (clone) {
5498 clone.parentNode && clone.parentNode.removeChild(clone);
5499 });
5500 }
5501 },
5502 nullingGlobal: function nullingGlobal() {
5503 this.isMultiDrag = dragStarted = false;
5504 multiDragClones.length = 0;
5505 },
5506 destroyGlobal: function destroyGlobal() {
5507 this._deselectMultiDrag();
5508 off(document, 'pointerup', this._deselectMultiDrag);
5509 off(document, 'mouseup', this._deselectMultiDrag);
5510 off(document, 'touchend', this._deselectMultiDrag);
5511 off(document, 'keydown', this._checkKeyDown);
5512 off(document, 'keyup', this._checkKeyUp);
5513 },
5514 _deselectMultiDrag: function _deselectMultiDrag(evt) {
5515 if (typeof dragStarted !== "undefined" && dragStarted) return;
5516
5517 // Only deselect if selection is in this sortable
5518 if (multiDragSortable !== this.sortable) return;
5519
5520 // Only deselect if target is not item in this sortable
5521 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
5522
5523 // Only deselect if left click
5524 if (evt && evt.button !== 0) return;
5525 while (multiDragElements.length) {
5526 var el = multiDragElements[0];
5527 toggleClass(el, this.options.selectedClass, false);
5528 multiDragElements.shift();
5529 dispatchEvent({
5530 sortable: this.sortable,
5531 rootEl: this.sortable.el,
5532 name: 'deselect',
5533 targetEl: el,
5534 originalEvent: evt
5535 });
5536 }
5537 },
5538 _checkKeyDown: function _checkKeyDown(evt) {
5539 if (evt.key === this.options.multiDragKey) {
5540 this.multiDragKeyDown = true;
5541 }
5542 },
5543 _checkKeyUp: function _checkKeyUp(evt) {
5544 if (evt.key === this.options.multiDragKey) {
5545 this.multiDragKeyDown = false;
5546 }
5547 }
5548 };
5549 return _extends(MultiDrag, {
5550 // Static methods & properties
5551 pluginName: 'multiDrag',
5552 utils: {
5553 /**
5554 * Selects the provided multi-drag item
5555 * @param {HTMLElement} el The element to be selected
5556 */
5557 select: function select(el) {
5558 var sortable = el.parentNode[expando];
5559 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
5560 if (multiDragSortable && multiDragSortable !== sortable) {
5561 multiDragSortable.multiDrag._deselectMultiDrag();
5562 multiDragSortable = sortable;
5563 }
5564 toggleClass(el, sortable.options.selectedClass, true);
5565 multiDragElements.push(el);
5566 },
5567 /**
5568 * Deselects the provided multi-drag item
5569 * @param {HTMLElement} el The element to be deselected
5570 */
5571 deselect: function deselect(el) {
5572 var sortable = el.parentNode[expando],
5573 index = multiDragElements.indexOf(el);
5574 if (!sortable || !sortable.options.multiDrag || !~index) return;
5575 toggleClass(el, sortable.options.selectedClass, false);
5576 multiDragElements.splice(index, 1);
5577 }
5578 },
5579 eventProperties: function eventProperties() {
5580 var _this3 = this;
5581 var oldIndicies = [],
5582 newIndicies = [];
5583 multiDragElements.forEach(function (multiDragElement) {
5584 oldIndicies.push({
5585 multiDragElement: multiDragElement,
5586 index: multiDragElement.sortableIndex
5587 });
5588
5589 // multiDragElements will already be sorted if folding
5590 var newIndex;
5591 if (folding && multiDragElement !== dragEl$1) {
5592 newIndex = -1;
5593 } else if (folding) {
5594 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
5595 } else {
5596 newIndex = index(multiDragElement);
5597 }
5598 newIndicies.push({
5599 multiDragElement: multiDragElement,
5600 index: newIndex
5601 });
5602 });
5603 return {
5604 items: _toConsumableArray(multiDragElements),
5605 clones: [].concat(multiDragClones),
5606 oldIndicies: oldIndicies,
5607 newIndicies: newIndicies
5608 };
5609 },
5610 optionListeners: {
5611 multiDragKey: function multiDragKey(key) {
5612 key = key.toLowerCase();
5613 if (key === 'ctrl') {
5614 key = 'Control';
5615 } else if (key.length > 1) {
5616 key = key.charAt(0).toUpperCase() + key.substr(1);
5617 }
5618 return key;
5619 }
5620 }
5621 });
5622 }
5623 function insertMultiDragElements(clonesInserted, rootEl) {
5624 multiDragElements.forEach(function (multiDragElement, i) {
5625 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
5626 if (target) {
5627 rootEl.insertBefore(multiDragElement, target);
5628 } else {
5629 rootEl.appendChild(multiDragElement);
5630 }
5631 });
5632 }
5633
5634 /**
5635 * Insert multi-drag clones
5636 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
5637 * @param {HTMLElement} rootEl
5638 */
5639 function insertMultiDragClones(elementsInserted, rootEl) {
5640 multiDragClones.forEach(function (clone, i) {
5641 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
5642 if (target) {
5643 rootEl.insertBefore(clone, target);
5644 } else {
5645 rootEl.appendChild(clone);
5646 }
5647 });
5648 }
5649 function removeMultiDragElements() {
5650 multiDragElements.forEach(function (multiDragElement) {
5651 if (multiDragElement === dragEl$1) return;
5652 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
5653 });
5654 }
5655
5656 Sortable.mount(new AutoScrollPlugin());
5657 Sortable.mount(Remove, Revert);
5658
5659 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
5660
5661
5662
5663 /***/ },
5664
5665 /***/ "./node_modules/toastify-js/src/toastify.css"
5666 /*!***************************************************!*\
5667 !*** ./node_modules/toastify-js/src/toastify.css ***!
5668 \***************************************************/
5669 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5670
5671 "use strict";
5672 __webpack_require__.r(__webpack_exports__);
5673 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5674 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5675 /* harmony export */ });
5676 /* 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");
5677 /* 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__);
5678 /* 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");
5679 /* 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__);
5680 /* 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");
5681 /* 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__);
5682 /* 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");
5683 /* 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__);
5684 /* 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");
5685 /* 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__);
5686 /* 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");
5687 /* 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__);
5688 /* 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");
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700 var options = {};
5701
5702 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5703 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5704
5705 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5706
5707 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5708 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5709
5710 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);
5711
5712
5713
5714
5715 /* 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);
5716
5717
5718 /***/ },
5719
5720 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
5721 /*!****************************************************************************!*\
5722 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5723 \****************************************************************************/
5724 (module) {
5725
5726 "use strict";
5727
5728
5729 var stylesInDOM = [];
5730 function getIndexByIdentifier(identifier) {
5731 var result = -1;
5732 for (var i = 0; i < stylesInDOM.length; i++) {
5733 if (stylesInDOM[i].identifier === identifier) {
5734 result = i;
5735 break;
5736 }
5737 }
5738 return result;
5739 }
5740 function modulesToDom(list, options) {
5741 var idCountMap = {};
5742 var identifiers = [];
5743 for (var i = 0; i < list.length; i++) {
5744 var item = list[i];
5745 var id = options.base ? item[0] + options.base : item[0];
5746 var count = idCountMap[id] || 0;
5747 var identifier = "".concat(id, " ").concat(count);
5748 idCountMap[id] = count + 1;
5749 var indexByIdentifier = getIndexByIdentifier(identifier);
5750 var obj = {
5751 css: item[1],
5752 media: item[2],
5753 sourceMap: item[3],
5754 supports: item[4],
5755 layer: item[5]
5756 };
5757 if (indexByIdentifier !== -1) {
5758 stylesInDOM[indexByIdentifier].references++;
5759 stylesInDOM[indexByIdentifier].updater(obj);
5760 } else {
5761 var updater = addElementStyle(obj, options);
5762 options.byIndex = i;
5763 stylesInDOM.splice(i, 0, {
5764 identifier: identifier,
5765 updater: updater,
5766 references: 1
5767 });
5768 }
5769 identifiers.push(identifier);
5770 }
5771 return identifiers;
5772 }
5773 function addElementStyle(obj, options) {
5774 var api = options.domAPI(options);
5775 api.update(obj);
5776 var updater = function updater(newObj) {
5777 if (newObj) {
5778 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5779 return;
5780 }
5781 api.update(obj = newObj);
5782 } else {
5783 api.remove();
5784 }
5785 };
5786 return updater;
5787 }
5788 module.exports = function (list, options) {
5789 options = options || {};
5790 list = list || [];
5791 var lastIdentifiers = modulesToDom(list, options);
5792 return function update(newList) {
5793 newList = newList || [];
5794 for (var i = 0; i < lastIdentifiers.length; i++) {
5795 var identifier = lastIdentifiers[i];
5796 var index = getIndexByIdentifier(identifier);
5797 stylesInDOM[index].references--;
5798 }
5799 var newLastIdentifiers = modulesToDom(newList, options);
5800 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5801 var _identifier = lastIdentifiers[_i];
5802 var _index = getIndexByIdentifier(_identifier);
5803 if (stylesInDOM[_index].references === 0) {
5804 stylesInDOM[_index].updater();
5805 stylesInDOM.splice(_index, 1);
5806 }
5807 }
5808 lastIdentifiers = newLastIdentifiers;
5809 };
5810 };
5811
5812 /***/ },
5813
5814 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
5815 /*!********************************************************************!*\
5816 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5817 \********************************************************************/
5818 (module) {
5819
5820 "use strict";
5821
5822
5823 var memo = {};
5824
5825 /* istanbul ignore next */
5826 function getTarget(target) {
5827 if (typeof memo[target] === "undefined") {
5828 var styleTarget = document.querySelector(target);
5829
5830 // Special case to return head of iframe instead of iframe itself
5831 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5832 try {
5833 // This will throw an exception if access to iframe is blocked
5834 // due to cross-origin restrictions
5835 styleTarget = styleTarget.contentDocument.head;
5836 } catch (e) {
5837 // istanbul ignore next
5838 styleTarget = null;
5839 }
5840 }
5841 memo[target] = styleTarget;
5842 }
5843 return memo[target];
5844 }
5845
5846 /* istanbul ignore next */
5847 function insertBySelector(insert, style) {
5848 var target = getTarget(insert);
5849 if (!target) {
5850 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
5851 }
5852 target.appendChild(style);
5853 }
5854 module.exports = insertBySelector;
5855
5856 /***/ },
5857
5858 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
5859 /*!**********************************************************************!*\
5860 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
5861 \**********************************************************************/
5862 (module) {
5863
5864 "use strict";
5865
5866
5867 /* istanbul ignore next */
5868 function insertStyleElement(options) {
5869 var element = document.createElement("style");
5870 options.setAttributes(element, options.attributes);
5871 options.insert(element, options.options);
5872 return element;
5873 }
5874 module.exports = insertStyleElement;
5875
5876 /***/ },
5877
5878 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
5879 /*!**********************************************************************************!*\
5880 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
5881 \**********************************************************************************/
5882 (module, __unused_webpack_exports, __webpack_require__) {
5883
5884 "use strict";
5885
5886
5887 /* istanbul ignore next */
5888 function setAttributesWithoutAttributes(styleElement) {
5889 var nonce = true ? __webpack_require__.nc : 0;
5890 if (nonce) {
5891 styleElement.setAttribute("nonce", nonce);
5892 }
5893 }
5894 module.exports = setAttributesWithoutAttributes;
5895
5896 /***/ },
5897
5898 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
5899 /*!***************************************************************!*\
5900 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
5901 \***************************************************************/
5902 (module) {
5903
5904 "use strict";
5905
5906
5907 /* istanbul ignore next */
5908 function apply(styleElement, options, obj) {
5909 var css = "";
5910 if (obj.supports) {
5911 css += "@supports (".concat(obj.supports, ") {");
5912 }
5913 if (obj.media) {
5914 css += "@media ".concat(obj.media, " {");
5915 }
5916 var needLayer = typeof obj.layer !== "undefined";
5917 if (needLayer) {
5918 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
5919 }
5920 css += obj.css;
5921 if (needLayer) {
5922 css += "}";
5923 }
5924 if (obj.media) {
5925 css += "}";
5926 }
5927 if (obj.supports) {
5928 css += "}";
5929 }
5930 var sourceMap = obj.sourceMap;
5931 if (sourceMap && typeof btoa !== "undefined") {
5932 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
5933 }
5934
5935 // For old IE
5936 /* istanbul ignore if */
5937 options.styleTagTransform(css, styleElement, options.options);
5938 }
5939 function removeStyleElement(styleElement) {
5940 // istanbul ignore if
5941 if (styleElement.parentNode === null) {
5942 return false;
5943 }
5944 styleElement.parentNode.removeChild(styleElement);
5945 }
5946
5947 /* istanbul ignore next */
5948 function domAPI(options) {
5949 if (typeof document === "undefined") {
5950 return {
5951 update: function update() {},
5952 remove: function remove() {}
5953 };
5954 }
5955 var styleElement = options.insertStyleElement(options);
5956 return {
5957 update: function update(obj) {
5958 apply(styleElement, options, obj);
5959 },
5960 remove: function remove() {
5961 removeStyleElement(styleElement);
5962 }
5963 };
5964 }
5965 module.exports = domAPI;
5966
5967 /***/ },
5968
5969 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
5970 /*!*********************************************************************!*\
5971 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
5972 \*********************************************************************/
5973 (module) {
5974
5975 "use strict";
5976
5977
5978 /* istanbul ignore next */
5979 function styleTagTransform(css, styleElement) {
5980 if (styleElement.styleSheet) {
5981 styleElement.styleSheet.cssText = css;
5982 } else {
5983 while (styleElement.firstChild) {
5984 styleElement.removeChild(styleElement.firstChild);
5985 }
5986 styleElement.appendChild(document.createTextNode(css));
5987 }
5988 }
5989 module.exports = styleTagTransform;
5990
5991 /***/ },
5992
5993 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
5994 /*!**********************************************************!*\
5995 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
5996 \**********************************************************/
5997 (module) {
5998
5999 /*!
6000 * sweetalert2 v11.26.25
6001 * Released under the MIT License.
6002 */
6003 (function (global, factory) {
6004 true ? module.exports = factory() :
6005 0;
6006 })(this, (function () { 'use strict';
6007
6008 function _assertClassBrand(e, t, n) {
6009 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6010 throw new TypeError("Private element is not present on this object");
6011 }
6012 function _checkPrivateRedeclaration(e, t) {
6013 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6014 }
6015 function _classPrivateFieldGet2(s, a) {
6016 return s.get(_assertClassBrand(s, a));
6017 }
6018 function _classPrivateFieldInitSpec(e, t, a) {
6019 _checkPrivateRedeclaration(e, t), t.set(e, a);
6020 }
6021 function _classPrivateFieldSet2(s, a, r) {
6022 return s.set(_assertClassBrand(s, a), r), r;
6023 }
6024
6025 const RESTORE_FOCUS_TIMEOUT = 100;
6026
6027 /** @type {GlobalState} */
6028 const globalState = {};
6029 const focusPreviousActiveElement = () => {
6030 if (globalState.previousActiveElement instanceof HTMLElement) {
6031 globalState.previousActiveElement.focus();
6032 globalState.previousActiveElement = null;
6033 } else if (document.body) {
6034 document.body.focus();
6035 }
6036 };
6037
6038 /**
6039 * Restore previous active (focused) element
6040 *
6041 * @param {boolean} returnFocus
6042 * @returns {Promise<void>}
6043 */
6044 const restoreActiveElement = returnFocus => {
6045 return new Promise(resolve => {
6046 if (!returnFocus) {
6047 return resolve();
6048 }
6049 const x = window.scrollX;
6050 const y = window.scrollY;
6051 globalState.restoreFocusTimeout = setTimeout(() => {
6052 focusPreviousActiveElement();
6053 resolve();
6054 }, RESTORE_FOCUS_TIMEOUT); // issues/900
6055
6056 window.scrollTo(x, y);
6057 });
6058 };
6059
6060 const swalPrefix = 'swal2-';
6061
6062 /**
6063 * @typedef {Record<SwalClass, string>} SwalClasses
6064 */
6065
6066 /**
6067 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
6068 * @typedef {Record<SwalIcon, string>} SwalIcons
6069 */
6070
6071 /** @type {SwalClass[]} */
6072 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'];
6073 const swalClasses = classNames.reduce((acc, className) => {
6074 acc[className] = swalPrefix + className;
6075 return acc;
6076 }, /** @type {SwalClasses} */{});
6077
6078 /** @type {SwalIcon[]} */
6079 const icons = ['success', 'warning', 'info', 'question', 'error'];
6080 const iconTypes = icons.reduce((acc, icon) => {
6081 acc[icon] = swalPrefix + icon;
6082 return acc;
6083 }, /** @type {SwalIcons} */{});
6084
6085 const consolePrefix = 'SweetAlert2:';
6086
6087 /**
6088 * Capitalize the first letter of a string
6089 *
6090 * @param {string} str
6091 * @returns {string}
6092 */
6093 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
6094
6095 /**
6096 * Standardize console warnings
6097 *
6098 * @param {string | string[]} message
6099 */
6100 const warn = message => {
6101 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
6102 };
6103
6104 /**
6105 * Standardize console errors
6106 *
6107 * @param {string} message
6108 */
6109 const error = message => {
6110 console.error(`${consolePrefix} ${message}`);
6111 };
6112
6113 /**
6114 * Private global state for `warnOnce`
6115 *
6116 * @type {string[]}
6117 * @private
6118 */
6119 const previousWarnOnceMessages = [];
6120
6121 /**
6122 * Show a console warning, but only if it hasn't already been shown
6123 *
6124 * @param {string} message
6125 */
6126 const warnOnce = message => {
6127 if (!previousWarnOnceMessages.includes(message)) {
6128 previousWarnOnceMessages.push(message);
6129 warn(message);
6130 }
6131 };
6132
6133 /**
6134 * Show a one-time console warning about deprecated params/methods
6135 *
6136 * @param {string} deprecatedParam
6137 * @param {string?} useInstead
6138 */
6139 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
6140 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
6141 };
6142
6143 /**
6144 * If `arg` is a function, call it (with no arguments or context) and return the result.
6145 * Otherwise, just pass the value through
6146 *
6147 * @param {(() => *) | *} arg
6148 * @returns {*}
6149 */
6150 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
6151
6152 /**
6153 * @param {*} arg
6154 * @returns {boolean}
6155 */
6156 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
6157
6158 /**
6159 * @param {*} arg
6160 * @returns {Promise<*>}
6161 */
6162 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
6163
6164 /**
6165 * @param {*} arg
6166 * @returns {boolean}
6167 */
6168 const isPromise = arg => arg && Promise.resolve(arg) === arg;
6169
6170 /**
6171 * @returns {boolean}
6172 */
6173 const isFirefox = () => navigator.userAgent.includes('Firefox');
6174
6175 /**
6176 * Gets the popup container which contains the backdrop and the popup itself.
6177 *
6178 * @returns {HTMLElement | null}
6179 */
6180 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6181
6182 /**
6183 * @param {string} selectorString
6184 * @returns {HTMLElement | null}
6185 */
6186 const elementBySelector = selectorString => {
6187 const container = getContainer();
6188 return container ? container.querySelector(selectorString) : null;
6189 };
6190
6191 /**
6192 * @param {string} className
6193 * @returns {HTMLElement | null}
6194 */
6195 const elementByClass = className => {
6196 return elementBySelector(`.${className}`);
6197 };
6198
6199 /**
6200 * @returns {HTMLElement | null}
6201 */
6202 const getPopup = () => elementByClass(swalClasses.popup);
6203
6204 /**
6205 * @returns {HTMLElement | null}
6206 */
6207 const getIcon = () => elementByClass(swalClasses.icon);
6208
6209 /**
6210 * @returns {HTMLElement | null}
6211 */
6212 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6213
6214 /**
6215 * @returns {HTMLElement | null}
6216 */
6217 const getTitle = () => elementByClass(swalClasses.title);
6218
6219 /**
6220 * @returns {HTMLElement | null}
6221 */
6222 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6223
6224 /**
6225 * @returns {HTMLElement | null}
6226 */
6227 const getImage = () => elementByClass(swalClasses.image);
6228
6229 /**
6230 * @returns {HTMLElement | null}
6231 */
6232 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6233
6234 /**
6235 * @returns {HTMLElement | null}
6236 */
6237 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6238
6239 /**
6240 * @returns {HTMLButtonElement | null}
6241 */
6242 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6243
6244 /**
6245 * @returns {HTMLButtonElement | null}
6246 */
6247 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6248
6249 /**
6250 * @returns {HTMLButtonElement | null}
6251 */
6252 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6253
6254 /**
6255 * @returns {HTMLElement | null}
6256 */
6257 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6258
6259 /**
6260 * @returns {HTMLElement | null}
6261 */
6262 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6263
6264 /**
6265 * @returns {HTMLElement | null}
6266 */
6267 const getActions = () => elementByClass(swalClasses.actions);
6268
6269 /**
6270 * @returns {HTMLElement | null}
6271 */
6272 const getFooter = () => elementByClass(swalClasses.footer);
6273
6274 /**
6275 * @returns {HTMLElement | null}
6276 */
6277 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6278
6279 /**
6280 * @returns {HTMLElement | null}
6281 */
6282 const getCloseButton = () => elementByClass(swalClasses.close);
6283
6284 // https://github.com/jkup/focusable/blob/master/index.js
6285 const focusable = `
6286 a[href],
6287 area[href],
6288 input:not([disabled]),
6289 select:not([disabled]),
6290 textarea:not([disabled]),
6291 button:not([disabled]),
6292 iframe,
6293 object,
6294 embed,
6295 [tabindex="0"],
6296 [contenteditable],
6297 audio[controls],
6298 video[controls],
6299 summary
6300 `;
6301 /**
6302 * @returns {HTMLElement[]}
6303 */
6304 const getFocusableElements = () => {
6305 const popup = getPopup();
6306 if (!popup) {
6307 return [];
6308 }
6309 /** @type {NodeListOf<HTMLElement>} */
6310 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6311 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6312 // sort according to tabindex
6313 .sort((a, b) => {
6314 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6315 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6316 if (tabindexA > tabindexB) {
6317 return 1;
6318 } else if (tabindexA < tabindexB) {
6319 return -1;
6320 }
6321 return 0;
6322 });
6323
6324 /** @type {NodeListOf<HTMLElement>} */
6325 const otherFocusableElements = popup.querySelectorAll(focusable);
6326 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6327 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6328 };
6329
6330 /**
6331 * @returns {boolean}
6332 */
6333 const isModal = () => {
6334 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6335 };
6336
6337 /**
6338 * @returns {boolean}
6339 */
6340 const isToast = () => {
6341 const popup = getPopup();
6342 if (!popup) {
6343 return false;
6344 }
6345 return hasClass(popup, swalClasses.toast);
6346 };
6347
6348 /**
6349 * @returns {boolean}
6350 */
6351 const isLoading = () => {
6352 const popup = getPopup();
6353 if (!popup) {
6354 return false;
6355 }
6356 return popup.hasAttribute('data-loading');
6357 };
6358
6359 /**
6360 * Securely set innerHTML of an element
6361 * https://github.com/sweetalert2/sweetalert2/issues/1926
6362 *
6363 * @param {HTMLElement} elem
6364 * @param {string} html
6365 */
6366 const setInnerHtml = (elem, html) => {
6367 elem.textContent = '';
6368 if (html) {
6369 const parser = new DOMParser();
6370 const parsed = parser.parseFromString(html, `text/html`);
6371 const head = parsed.querySelector('head');
6372 if (head) {
6373 Array.from(head.childNodes).forEach(child => {
6374 elem.appendChild(child);
6375 });
6376 }
6377 const body = parsed.querySelector('body');
6378 if (body) {
6379 Array.from(body.childNodes).forEach(child => {
6380 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6381 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6382 } else {
6383 elem.appendChild(child);
6384 }
6385 });
6386 }
6387 }
6388 };
6389
6390 /**
6391 * @param {HTMLElement} elem
6392 * @param {string} className
6393 * @returns {boolean}
6394 */
6395 const hasClass = (elem, className) => {
6396 if (!className) {
6397 return false;
6398 }
6399 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
6400 };
6401
6402 /**
6403 * @param {HTMLElement} elem
6404 * @param {SweetAlertOptions} params
6405 */
6406 const removeCustomClasses = (elem, params) => {
6407 Array.from(elem.classList).forEach(className => {
6408 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6409 elem.classList.remove(className);
6410 }
6411 });
6412 };
6413
6414 /**
6415 * @param {HTMLElement} elem
6416 * @param {SweetAlertOptions} params
6417 * @param {string} className
6418 */
6419 const applyCustomClass = (elem, params, className) => {
6420 removeCustomClasses(elem, params);
6421 if (!params.customClass) {
6422 return;
6423 }
6424 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6425 if (!customClass) {
6426 return;
6427 }
6428 if (typeof customClass !== 'string' && !customClass.forEach) {
6429 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6430 return;
6431 }
6432 addClass(elem, customClass);
6433 };
6434
6435 /**
6436 * @param {HTMLElement} popup
6437 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6438 * @returns {HTMLInputElement | null}
6439 */
6440 const getInput$1 = (popup, inputClass) => {
6441 if (!inputClass) {
6442 return null;
6443 }
6444 switch (inputClass) {
6445 case 'select':
6446 case 'textarea':
6447 case 'file':
6448 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6449 case 'checkbox':
6450 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6451 case 'radio':
6452 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6453 case 'range':
6454 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6455 default:
6456 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6457 }
6458 };
6459
6460 /**
6461 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6462 */
6463 const focusInput = input => {
6464 input.focus();
6465
6466 // place cursor at end of text in text input
6467 if (input.type !== 'file') {
6468 // http://stackoverflow.com/a/2345915
6469 const val = input.value;
6470 input.value = '';
6471 input.value = val;
6472 }
6473 };
6474
6475 /**
6476 * @param {HTMLElement | HTMLElement[] | null} target
6477 * @param {string | string[] | readonly string[] | undefined} classList
6478 * @param {boolean} condition
6479 */
6480 const toggleClass = (target, classList, condition) => {
6481 if (!target || !classList) {
6482 return;
6483 }
6484 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
6485 const targets = Array.isArray(target) ? target : [target];
6486 targets.forEach(elem => {
6487 classes.forEach(className => {
6488 if (condition) {
6489 elem.classList.add(className);
6490 } else {
6491 elem.classList.remove(className);
6492 }
6493 });
6494 });
6495 };
6496
6497 /**
6498 * @param {HTMLElement | HTMLElement[] | null} target
6499 * @param {string | string[] | readonly string[] | undefined} classList
6500 */
6501 const addClass = (target, classList) => {
6502 toggleClass(target, classList, true);
6503 };
6504
6505 /**
6506 * @param {HTMLElement | HTMLElement[] | null} target
6507 * @param {string | string[] | readonly string[] | undefined} classList
6508 */
6509 const removeClass = (target, classList) => {
6510 toggleClass(target, classList, false);
6511 };
6512
6513 /**
6514 * Get direct child of an element by class name
6515 *
6516 * @param {HTMLElement} elem
6517 * @param {string} className
6518 * @returns {HTMLElement | undefined}
6519 */
6520 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
6521 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
6522
6523 /**
6524 * @param {HTMLElement} elem
6525 * @param {string} property
6526 * @param {string | number | null | undefined} value
6527 */
6528 const applyNumericalStyle = (elem, property, value) => {
6529 if (value === `${parseInt(`${value}`)}`) {
6530 value = parseInt(value);
6531 }
6532 if (value || value === 0) {
6533 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6534 } else {
6535 elem.style.removeProperty(property);
6536 }
6537 };
6538
6539 /**
6540 * @param {HTMLElement | null} elem
6541 * @param {string} display
6542 */
6543 const show = (elem, display = 'flex') => {
6544 if (!elem) {
6545 return;
6546 }
6547 elem.style.display = display;
6548 };
6549
6550 /**
6551 * @param {HTMLElement | null} elem
6552 */
6553 const hide = elem => {
6554 if (!elem) {
6555 return;
6556 }
6557 elem.style.display = 'none';
6558 };
6559
6560 /**
6561 * @param {HTMLElement | null} elem
6562 * @param {string} display
6563 */
6564 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6565 if (!elem) {
6566 return;
6567 }
6568 new MutationObserver(() => {
6569 toggle(elem, elem.innerHTML, display);
6570 }).observe(elem, {
6571 childList: true,
6572 subtree: true
6573 });
6574 };
6575
6576 /**
6577 * @param {HTMLElement} parent
6578 * @param {string} selector
6579 * @param {string} property
6580 * @param {string} value
6581 */
6582 const setStyle = (parent, selector, property, value) => {
6583 /** @type {HTMLElement | null} */
6584 const el = parent.querySelector(selector);
6585 if (el) {
6586 el.style.setProperty(property, value);
6587 }
6588 };
6589
6590 /**
6591 * @param {HTMLElement} elem
6592 * @param {boolean | string | null | undefined} condition
6593 * @param {string} display
6594 */
6595 const toggle = (elem, condition, display = 'flex') => {
6596 if (condition) {
6597 show(elem, display);
6598 } else {
6599 hide(elem);
6600 }
6601 };
6602
6603 /**
6604 * borrowed from jquery $(elem).is(':visible') implementation
6605 *
6606 * @param {HTMLElement | null} elem
6607 * @returns {boolean}
6608 */
6609 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6610
6611 /**
6612 * @returns {boolean}
6613 */
6614 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6615
6616 /**
6617 * @param {HTMLElement} elem
6618 * @returns {boolean}
6619 */
6620 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6621
6622 /**
6623 * @param {HTMLElement} element
6624 * @param {HTMLElement} stopElement
6625 * @returns {boolean}
6626 */
6627 const selfOrParentIsScrollable = (element, stopElement) => {
6628 let parent = /** @type {HTMLElement | null} */element;
6629 while (parent && parent !== stopElement) {
6630 if (isScrollable(parent)) {
6631 return true;
6632 }
6633 parent = parent.parentElement;
6634 }
6635 return false;
6636 };
6637
6638 /**
6639 * borrowed from https://stackoverflow.com/a/46352119
6640 *
6641 * @param {HTMLElement} elem
6642 * @returns {boolean}
6643 */
6644 const hasCssAnimation = elem => {
6645 const style = window.getComputedStyle(elem);
6646 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6647 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6648 return animDuration > 0 || transDuration > 0;
6649 };
6650
6651 /**
6652 * @param {number} timer
6653 * @param {boolean} reset
6654 */
6655 const animateTimerProgressBar = (timer, reset = false) => {
6656 const timerProgressBar = getTimerProgressBar();
6657 if (!timerProgressBar) {
6658 return;
6659 }
6660 if (isVisible$1(timerProgressBar)) {
6661 if (reset) {
6662 timerProgressBar.style.transition = 'none';
6663 timerProgressBar.style.width = '100%';
6664 }
6665 setTimeout(() => {
6666 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6667 timerProgressBar.style.width = '0%';
6668 }, 10);
6669 }
6670 };
6671 const stopTimerProgressBar = () => {
6672 const timerProgressBar = getTimerProgressBar();
6673 if (!timerProgressBar) {
6674 return;
6675 }
6676 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6677 timerProgressBar.style.removeProperty('transition');
6678 timerProgressBar.style.width = '100%';
6679 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6680 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6681 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6682 };
6683
6684 /**
6685 * Detect Node env
6686 *
6687 * @returns {boolean}
6688 */
6689 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6690
6691 const sweetHTML = `
6692 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6693 <button type="button" class="${swalClasses.close}"></button>
6694 <ul class="${swalClasses['progress-steps']}"></ul>
6695 <div class="${swalClasses.icon}"></div>
6696 <img class="${swalClasses.image}" />
6697 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6698 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6699 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6700 <input type="file" class="${swalClasses.file}" />
6701 <div class="${swalClasses.range}">
6702 <input type="range" />
6703 <output></output>
6704 </div>
6705 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6706 <div class="${swalClasses.radio}"></div>
6707 <label class="${swalClasses.checkbox}">
6708 <input type="checkbox" id="${swalClasses.checkbox}" />
6709 <span class="${swalClasses.label}"></span>
6710 </label>
6711 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6712 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6713 <div class="${swalClasses.actions}">
6714 <div class="${swalClasses.loader}"></div>
6715 <button type="button" class="${swalClasses.confirm}"></button>
6716 <button type="button" class="${swalClasses.deny}"></button>
6717 <button type="button" class="${swalClasses.cancel}"></button>
6718 </div>
6719 <div class="${swalClasses.footer}"></div>
6720 <div class="${swalClasses['timer-progress-bar-container']}">
6721 <div class="${swalClasses['timer-progress-bar']}"></div>
6722 </div>
6723 </div>
6724 `.replace(/(^|\n)\s*/g, '');
6725
6726 /**
6727 * @returns {boolean}
6728 */
6729 const resetOldContainer = () => {
6730 const oldContainer = getContainer();
6731 if (!oldContainer) {
6732 return false;
6733 }
6734 oldContainer.remove();
6735 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6736 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6737 swalClasses['has-column']]);
6738 return true;
6739 };
6740 const resetValidationMessage$1 = () => {
6741 if (globalState.currentInstance) {
6742 globalState.currentInstance.resetValidationMessage();
6743 }
6744 };
6745 const addInputChangeListeners = () => {
6746 const popup = getPopup();
6747 if (!popup) {
6748 return;
6749 }
6750 const input = getDirectChildByClass(popup, swalClasses.input);
6751 const file = getDirectChildByClass(popup, swalClasses.file);
6752 /** @type {HTMLInputElement | null} */
6753 const range = popup.querySelector(`.${swalClasses.range} input`);
6754 /** @type {HTMLOutputElement | null} */
6755 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6756 const select = getDirectChildByClass(popup, swalClasses.select);
6757 /** @type {HTMLInputElement | null} */
6758 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6759 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6760 if (input) {
6761 input.oninput = resetValidationMessage$1;
6762 }
6763 if (file) {
6764 file.onchange = resetValidationMessage$1;
6765 }
6766 if (select) {
6767 select.onchange = resetValidationMessage$1;
6768 }
6769 if (checkbox) {
6770 checkbox.onchange = resetValidationMessage$1;
6771 }
6772 if (textarea) {
6773 textarea.oninput = resetValidationMessage$1;
6774 }
6775 if (range && rangeOutput) {
6776 range.oninput = () => {
6777 resetValidationMessage$1();
6778 rangeOutput.value = range.value;
6779 };
6780 range.onchange = () => {
6781 resetValidationMessage$1();
6782 rangeOutput.value = range.value;
6783 };
6784 }
6785 };
6786
6787 /**
6788 * @param {string | HTMLElement} target
6789 * @returns {HTMLElement}
6790 */
6791 const getTarget = target => {
6792 if (typeof target === 'string') {
6793 const element = document.querySelector(target);
6794 if (!element) {
6795 throw new Error(`Target element "${target}" not found`);
6796 }
6797 return /** @type {HTMLElement} */element;
6798 }
6799 return target;
6800 };
6801
6802 /**
6803 * @param {SweetAlertOptions} params
6804 */
6805 const setupAccessibility = params => {
6806 const popup = getPopup();
6807 if (!popup) {
6808 return;
6809 }
6810 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6811 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6812 if (!params.toast) {
6813 popup.setAttribute('aria-modal', 'true');
6814 }
6815 };
6816
6817 /**
6818 * @param {HTMLElement} targetElement
6819 */
6820 const setupRTL = targetElement => {
6821 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6822 addClass(getContainer(), swalClasses.rtl);
6823 globalState.isRTL = true;
6824 }
6825 };
6826
6827 /**
6828 * Add modal + backdrop to DOM
6829 *
6830 * @param {SweetAlertOptions} params
6831 */
6832 const init = params => {
6833 // Clean up the old popup container if it exists
6834 const oldContainerExisted = resetOldContainer();
6835 if (isNodeEnv()) {
6836 error('SweetAlert2 requires document to initialize');
6837 return;
6838 }
6839 const container = document.createElement('div');
6840 container.className = swalClasses.container;
6841 if (oldContainerExisted) {
6842 addClass(container, swalClasses['no-transition']);
6843 }
6844 setInnerHtml(container, sweetHTML);
6845 container.dataset['swal2Theme'] = params.theme;
6846 const targetElement = getTarget(params.target || 'body');
6847 targetElement.appendChild(container);
6848 if (params.topLayer) {
6849 container.setAttribute('popover', '');
6850 container.showPopover();
6851 }
6852 setupAccessibility(params);
6853 setupRTL(targetElement);
6854 addInputChangeListeners();
6855 };
6856
6857 /**
6858 * @param {HTMLElement | object | string} param
6859 * @param {HTMLElement} target
6860 */
6861 const parseHtmlToContainer = (param, target) => {
6862 // DOM element
6863 if (param instanceof HTMLElement) {
6864 target.appendChild(param);
6865 }
6866
6867 // Object
6868 else if (typeof param === 'object') {
6869 handleObject(param, target);
6870 }
6871
6872 // Plain string
6873 else if (param) {
6874 setInnerHtml(target, param);
6875 }
6876 };
6877
6878 /**
6879 * @param {object} param
6880 * @param {HTMLElement} target
6881 */
6882 const handleObject = (param, target) => {
6883 // JQuery element(s)
6884 if ('jquery' in param) {
6885 handleJqueryElem(target, param);
6886 }
6887
6888 // For other objects use their string representation
6889 else {
6890 setInnerHtml(target, param.toString());
6891 }
6892 };
6893
6894 /**
6895 * @param {HTMLElement} target
6896 * @param {any} elem
6897 */
6898 const handleJqueryElem = (target, elem) => {
6899 target.textContent = '';
6900 if (0 in elem) {
6901 for (let i = 0; i in elem; i++) {
6902 target.appendChild(elem[i].cloneNode(true));
6903 }
6904 } else {
6905 target.appendChild(elem.cloneNode(true));
6906 }
6907 };
6908
6909 /**
6910 * @param {SweetAlert} instance
6911 * @param {SweetAlertOptions} params
6912 */
6913 const renderActions = (instance, params) => {
6914 const actions = getActions();
6915 const loader = getLoader();
6916 if (!actions || !loader) {
6917 return;
6918 }
6919
6920 // Actions (buttons) wrapper
6921 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
6922 hide(actions);
6923 } else {
6924 show(actions);
6925 }
6926
6927 // Custom class
6928 applyCustomClass(actions, params, 'actions');
6929
6930 // Render all the buttons
6931 renderButtons(actions, loader, params);
6932
6933 // Loader
6934 setInnerHtml(loader, params.loaderHtml || '');
6935 applyCustomClass(loader, params, 'loader');
6936 };
6937
6938 /**
6939 * @param {HTMLElement} actions
6940 * @param {HTMLElement} loader
6941 * @param {SweetAlertOptions} params
6942 */
6943 function renderButtons(actions, loader, params) {
6944 const confirmButton = getConfirmButton();
6945 const denyButton = getDenyButton();
6946 const cancelButton = getCancelButton();
6947 if (!confirmButton || !denyButton || !cancelButton) {
6948 return;
6949 }
6950
6951 // Render buttons
6952 renderButton(confirmButton, 'confirm', params);
6953 renderButton(denyButton, 'deny', params);
6954 renderButton(cancelButton, 'cancel', params);
6955 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
6956 if (params.reverseButtons) {
6957 if (params.toast) {
6958 actions.insertBefore(cancelButton, confirmButton);
6959 actions.insertBefore(denyButton, confirmButton);
6960 } else {
6961 actions.insertBefore(cancelButton, loader);
6962 actions.insertBefore(denyButton, loader);
6963 actions.insertBefore(confirmButton, loader);
6964 }
6965 }
6966 }
6967
6968 /**
6969 * @param {HTMLElement} confirmButton
6970 * @param {HTMLElement} denyButton
6971 * @param {HTMLElement} cancelButton
6972 * @param {SweetAlertOptions} params
6973 */
6974 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
6975 if (!params.buttonsStyling) {
6976 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
6977 return;
6978 }
6979 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
6980
6981 // Apply custom background colors and outline colors to action buttons
6982 /** @type {[HTMLElement, string, string | undefined][]} */
6983 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
6984 buttons.forEach(([button, type, color]) => {
6985 if (color) {
6986 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
6987 }
6988 applyOutlineColor(button);
6989 });
6990 }
6991
6992 /**
6993 * @param {HTMLElement} button
6994 */
6995 function applyOutlineColor(button) {
6996 const buttonStyle = window.getComputedStyle(button);
6997 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
6998 // If the button already has a custom outline color, no need to change it
6999 return;
7000 }
7001 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7002 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7003 }
7004
7005 /**
7006 * @param {HTMLElement} button
7007 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7008 * @param {SweetAlertOptions} params
7009 */
7010 function renderButton(button, buttonType, params) {
7011 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7012 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7013 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7014 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7015
7016 // Add buttons custom classes
7017 button.className = swalClasses[buttonType];
7018 applyCustomClass(button, params, `${buttonType}Button`);
7019 }
7020
7021 /**
7022 * @param {SweetAlert} instance
7023 * @param {SweetAlertOptions} params
7024 */
7025 const renderCloseButton = (instance, params) => {
7026 const closeButton = getCloseButton();
7027 if (!closeButton) {
7028 return;
7029 }
7030 setInnerHtml(closeButton, params.closeButtonHtml || '');
7031
7032 // Custom class
7033 applyCustomClass(closeButton, params, 'closeButton');
7034 toggle(closeButton, params.showCloseButton);
7035 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7036 };
7037
7038 /**
7039 * @param {SweetAlert} instance
7040 * @param {SweetAlertOptions} params
7041 */
7042 const renderContainer = (instance, params) => {
7043 const container = getContainer();
7044 if (!container) {
7045 return;
7046 }
7047 handleBackdropParam(container, params.backdrop);
7048 handlePositionParam(container, params.position);
7049 handleGrowParam(container, params.grow);
7050
7051 // Custom class
7052 applyCustomClass(container, params, 'container');
7053 };
7054
7055 /**
7056 * @param {HTMLElement} container
7057 * @param {SweetAlertOptions['backdrop']} backdrop
7058 */
7059 function handleBackdropParam(container, backdrop) {
7060 if (typeof backdrop === 'string') {
7061 container.style.background = backdrop;
7062 } else if (!backdrop) {
7063 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7064 }
7065 }
7066
7067 /**
7068 * @param {HTMLElement} container
7069 * @param {SweetAlertOptions['position']} position
7070 */
7071 function handlePositionParam(container, position) {
7072 if (!position) {
7073 return;
7074 }
7075 if (position in swalClasses) {
7076 addClass(container, swalClasses[position]);
7077 } else {
7078 warn('The "position" parameter is not valid, defaulting to "center"');
7079 addClass(container, swalClasses.center);
7080 }
7081 }
7082
7083 /**
7084 * @param {HTMLElement} container
7085 * @param {SweetAlertOptions['grow']} grow
7086 */
7087 function handleGrowParam(container, grow) {
7088 if (!grow) {
7089 return;
7090 }
7091 addClass(container, swalClasses[`grow-${grow}`]);
7092 }
7093
7094 /**
7095 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7096 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7097 * This is the approach that Babel will probably take to implement private methods/fields
7098 * https://github.com/tc39/proposal-private-methods
7099 * https://github.com/babel/babel/pull/7555
7100 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7101 * then we can use that language feature.
7102 */
7103
7104 var privateProps = {
7105 innerParams: new WeakMap(),
7106 domCache: new WeakMap(),
7107 focusedElement: new WeakMap()
7108 };
7109
7110 /// <reference path="../../../../sweetalert2.d.ts"/>
7111
7112
7113 /** @type {InputClass[]} */
7114 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7115
7116 /**
7117 * @param {SweetAlert} instance
7118 * @param {SweetAlertOptions} params
7119 */
7120 const renderInput = (instance, params) => {
7121 const popup = getPopup();
7122 if (!popup) {
7123 return;
7124 }
7125 const innerParams = privateProps.innerParams.get(instance);
7126 const rerender = !innerParams || params.input !== innerParams.input;
7127 inputClasses.forEach(inputClass => {
7128 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7129 if (!inputContainer) {
7130 return;
7131 }
7132
7133 // set attributes
7134 setAttributes(inputClass, params.inputAttributes);
7135
7136 // set class
7137 inputContainer.className = swalClasses[inputClass];
7138 if (rerender) {
7139 hide(inputContainer);
7140 }
7141 });
7142 if (params.input) {
7143 if (rerender) {
7144 showInput(params);
7145 }
7146 // set custom class
7147 setCustomClass(params);
7148 }
7149 };
7150
7151 /**
7152 * @param {SweetAlertOptions} params
7153 */
7154 const showInput = params => {
7155 if (!params.input) {
7156 return;
7157 }
7158 if (!renderInputType[params.input]) {
7159 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7160 return;
7161 }
7162 const inputContainer = getInputContainer(params.input);
7163 if (!inputContainer) {
7164 return;
7165 }
7166 const input = renderInputType[params.input](inputContainer, params);
7167 show(inputContainer);
7168
7169 // input autofocus
7170 if (params.inputAutoFocus) {
7171 setTimeout(() => {
7172 focusInput(input);
7173 });
7174 }
7175 };
7176
7177 /**
7178 * @param {HTMLInputElement} input
7179 */
7180 const removeAttributes = input => {
7181 for (const {
7182 name
7183 } of Array.from(input.attributes)) {
7184 if (!['id', 'type', 'value', 'style'].includes(name)) {
7185 input.removeAttribute(name);
7186 }
7187 }
7188 };
7189
7190 /**
7191 * @param {InputClass} inputClass
7192 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7193 */
7194 const setAttributes = (inputClass, inputAttributes) => {
7195 const popup = getPopup();
7196 if (!popup) {
7197 return;
7198 }
7199 const input = getInput$1(popup, inputClass);
7200 if (!input) {
7201 return;
7202 }
7203 removeAttributes(input);
7204 for (const attr in inputAttributes) {
7205 input.setAttribute(attr, inputAttributes[attr]);
7206 }
7207 };
7208
7209 /**
7210 * @param {SweetAlertOptions} params
7211 */
7212 const setCustomClass = params => {
7213 if (!params.input) {
7214 return;
7215 }
7216 const inputContainer = getInputContainer(params.input);
7217 if (inputContainer) {
7218 applyCustomClass(inputContainer, params, 'input');
7219 }
7220 };
7221
7222 /**
7223 * @param {HTMLInputElement | HTMLTextAreaElement} input
7224 * @param {SweetAlertOptions} params
7225 */
7226 const setInputPlaceholder = (input, params) => {
7227 if (!input.placeholder && params.inputPlaceholder) {
7228 input.placeholder = params.inputPlaceholder;
7229 }
7230 };
7231
7232 /**
7233 * @param {Input} input
7234 * @param {Input} prependTo
7235 * @param {SweetAlertOptions} params
7236 */
7237 const setInputLabel = (input, prependTo, params) => {
7238 if (params.inputLabel) {
7239 const label = document.createElement('label');
7240 const labelClass = swalClasses['input-label'];
7241 label.setAttribute('for', input.id);
7242 label.className = labelClass;
7243 if (typeof params.customClass === 'object') {
7244 addClass(label, params.customClass.inputLabel);
7245 }
7246 label.innerText = params.inputLabel;
7247 prependTo.insertAdjacentElement('beforebegin', label);
7248 }
7249 };
7250
7251 /**
7252 * @param {SweetAlertInput} inputType
7253 * @returns {HTMLElement | undefined}
7254 */
7255 const getInputContainer = inputType => {
7256 const popup = getPopup();
7257 if (!popup) {
7258 return;
7259 }
7260 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7261 };
7262
7263 /**
7264 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7265 * @param {SweetAlertOptions['inputValue']} inputValue
7266 */
7267 const checkAndSetInputValue = (input, inputValue) => {
7268 if (['string', 'number'].includes(typeof inputValue)) {
7269 input.value = `${inputValue}`;
7270 } else if (!isPromise(inputValue)) {
7271 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7272 }
7273 };
7274
7275 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7276 const renderInputType = {};
7277
7278 /**
7279 * @param {Input | HTMLElement} input
7280 * @param {SweetAlertOptions} params
7281 * @returns {Input}
7282 */
7283 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} */
7284 (input, params) => {
7285 // oxfmt-ignore
7286 const inputElement = /** @type {HTMLInputElement} */input;
7287 checkAndSetInputValue(inputElement, params.inputValue);
7288 setInputLabel(inputElement, inputElement, params);
7289 setInputPlaceholder(inputElement, params);
7290 // oxfmt-ignore
7291 inputElement.type = /** @type {string} */params.input;
7292 return inputElement;
7293 };
7294
7295 /**
7296 * @param {Input | HTMLElement} input
7297 * @param {SweetAlertOptions} params
7298 * @returns {Input}
7299 */
7300 renderInputType.file = (input, params) => {
7301 const inputElement = /** @type {HTMLInputElement} */input;
7302 setInputLabel(inputElement, inputElement, params);
7303 setInputPlaceholder(inputElement, params);
7304 return inputElement;
7305 };
7306
7307 /**
7308 * @param {Input | HTMLElement} range
7309 * @param {SweetAlertOptions} params
7310 * @returns {Input}
7311 */
7312 renderInputType.range = (range, params) => {
7313 const rangeContainer = /** @type {HTMLElement} */range;
7314 const rangeInput = rangeContainer.querySelector('input');
7315 const rangeOutput = rangeContainer.querySelector('output');
7316 if (rangeInput) {
7317 checkAndSetInputValue(rangeInput, params.inputValue);
7318 rangeInput.type = /** @type {string} */params.input;
7319 setInputLabel(rangeInput, /** @type {Input} */range, params);
7320 }
7321 if (rangeOutput) {
7322 checkAndSetInputValue(rangeOutput, params.inputValue);
7323 }
7324 return /** @type {Input} */range;
7325 };
7326
7327 /**
7328 * @param {Input | HTMLElement} select
7329 * @param {SweetAlertOptions} params
7330 * @returns {Input}
7331 */
7332 renderInputType.select = (select, params) => {
7333 const selectElement = /** @type {HTMLSelectElement} */select;
7334 selectElement.textContent = '';
7335 if (params.inputPlaceholder) {
7336 const placeholder = document.createElement('option');
7337 setInnerHtml(placeholder, params.inputPlaceholder);
7338 placeholder.value = '';
7339 placeholder.disabled = true;
7340 placeholder.selected = true;
7341 selectElement.appendChild(placeholder);
7342 }
7343 setInputLabel(selectElement, selectElement, params);
7344 return selectElement;
7345 };
7346
7347 /**
7348 * @param {Input | HTMLElement} radio
7349 * @returns {Input}
7350 */
7351 renderInputType.radio = radio => {
7352 const radioElement = /** @type {HTMLElement} */radio;
7353 radioElement.textContent = '';
7354 return /** @type {Input} */radio;
7355 };
7356
7357 /**
7358 * @param {Input | HTMLElement} checkboxContainer
7359 * @param {SweetAlertOptions} params
7360 * @returns {Input}
7361 */
7362 renderInputType.checkbox = (checkboxContainer, params) => {
7363 const popup = getPopup();
7364 if (!popup) {
7365 throw new Error('Popup not found');
7366 }
7367 const checkbox = getInput$1(popup, 'checkbox');
7368 if (!checkbox) {
7369 throw new Error('Checkbox input not found');
7370 }
7371 checkbox.value = '1';
7372 checkbox.checked = Boolean(params.inputValue);
7373 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7374 const label = containerElement.querySelector('span');
7375 if (label) {
7376 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7377 if (placeholderOrLabel) {
7378 setInnerHtml(label, placeholderOrLabel);
7379 }
7380 }
7381 return checkbox;
7382 };
7383
7384 /**
7385 * @param {Input | HTMLElement} textarea
7386 * @param {SweetAlertOptions} params
7387 * @returns {Input}
7388 */
7389 renderInputType.textarea = (textarea, params) => {
7390 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7391 checkAndSetInputValue(textareaElement, params.inputValue);
7392 setInputPlaceholder(textareaElement, params);
7393 setInputLabel(textareaElement, textareaElement, params);
7394
7395 /**
7396 * @param {HTMLElement} el
7397 * @returns {number}
7398 */
7399 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7400
7401 // https://github.com/sweetalert2/sweetalert2/issues/2291
7402 setTimeout(() => {
7403 // https://github.com/sweetalert2/sweetalert2/issues/1699
7404 if ('MutationObserver' in window) {
7405 const popup = getPopup();
7406 if (!popup) {
7407 return;
7408 }
7409 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7410 const textareaResizeHandler = () => {
7411 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7412 if (!document.body.contains(textareaElement)) {
7413 return;
7414 }
7415 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7416 const popupElement = getPopup();
7417 if (popupElement) {
7418 if (textareaWidth > initialPopupWidth) {
7419 popupElement.style.width = `${textareaWidth}px`;
7420 } else {
7421 applyNumericalStyle(popupElement, 'width', params.width);
7422 }
7423 }
7424 };
7425 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7426 attributes: true,
7427 attributeFilter: ['style']
7428 });
7429 }
7430 });
7431 return textareaElement;
7432 };
7433
7434 /**
7435 * @param {SweetAlert} instance
7436 * @param {SweetAlertOptions} params
7437 */
7438 const renderContent = (instance, params) => {
7439 const htmlContainer = getHtmlContainer();
7440 if (!htmlContainer) {
7441 return;
7442 }
7443 showWhenInnerHtmlPresent(htmlContainer);
7444 applyCustomClass(htmlContainer, params, 'htmlContainer');
7445
7446 // Content as HTML
7447 if (params.html) {
7448 parseHtmlToContainer(params.html, htmlContainer);
7449 show(htmlContainer, 'block');
7450 }
7451
7452 // Content as plain text
7453 else if (params.text) {
7454 htmlContainer.textContent = params.text;
7455 show(htmlContainer, 'block');
7456 }
7457
7458 // No content
7459 else {
7460 hide(htmlContainer);
7461 }
7462 renderInput(instance, params);
7463 };
7464
7465 /**
7466 * @param {SweetAlert} instance
7467 * @param {SweetAlertOptions} params
7468 */
7469 const renderFooter = (instance, params) => {
7470 const footer = getFooter();
7471 if (!footer) {
7472 return;
7473 }
7474 showWhenInnerHtmlPresent(footer);
7475 toggle(footer, Boolean(params.footer), 'block');
7476 if (params.footer) {
7477 parseHtmlToContainer(params.footer, footer);
7478 }
7479
7480 // Custom class
7481 applyCustomClass(footer, params, 'footer');
7482 };
7483
7484 /**
7485 * @param {SweetAlert} instance
7486 * @param {SweetAlertOptions} params
7487 */
7488 const renderIcon = (instance, params) => {
7489 const innerParams = privateProps.innerParams.get(instance);
7490 const icon = getIcon();
7491 if (!icon) {
7492 return;
7493 }
7494
7495 // if the given icon already rendered, apply the styling without re-rendering the icon
7496 if (innerParams && params.icon === innerParams.icon) {
7497 // Custom or default content
7498 setContent(icon, params);
7499 applyStyles(icon, params);
7500 return;
7501 }
7502 if (!params.icon && !params.iconHtml) {
7503 hide(icon);
7504 return;
7505 }
7506 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7507 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7508 hide(icon);
7509 return;
7510 }
7511 show(icon);
7512
7513 // Custom or default content
7514 setContent(icon, params);
7515 applyStyles(icon, params);
7516
7517 // Animate icon
7518 addClass(icon, params.showClass && params.showClass.icon);
7519
7520 // Re-adjust the success icon on system theme change
7521 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7522 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7523 };
7524
7525 /**
7526 * @param {HTMLElement} icon
7527 * @param {SweetAlertOptions} params
7528 */
7529 const applyStyles = (icon, params) => {
7530 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7531 if (params.icon !== iconType) {
7532 removeClass(icon, iconClassName);
7533 }
7534 }
7535 addClass(icon, params.icon && iconTypes[params.icon]);
7536
7537 // Icon color
7538 setColor(icon, params);
7539
7540 // Success icon background color
7541 adjustSuccessIconBackgroundColor();
7542
7543 // Custom class
7544 applyCustomClass(icon, params, 'icon');
7545 };
7546
7547 // Adjust success icon background color to match the popup background color
7548 const adjustSuccessIconBackgroundColor = () => {
7549 const popup = getPopup();
7550 if (!popup) {
7551 return;
7552 }
7553 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7554 /** @type {NodeListOf<HTMLElement>} */
7555 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7556 successIconParts.forEach(part => {
7557 part.style.backgroundColor = popupBackgroundColor;
7558 });
7559 };
7560
7561 /**
7562 *
7563 * @param {SweetAlertOptions} params
7564 * @returns {string}
7565 */
7566 const successIconHtml = params => `
7567 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7568 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7569 <div class="swal2-success-ring"></div>
7570 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7571 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7572 `;
7573 const errorIconHtml = `
7574 <span class="swal2-x-mark">
7575 <span class="swal2-x-mark-line-left"></span>
7576 <span class="swal2-x-mark-line-right"></span>
7577 </span>
7578 `;
7579
7580 /**
7581 * @param {HTMLElement} icon
7582 * @param {SweetAlertOptions} params
7583 */
7584 const setContent = (icon, params) => {
7585 if (!params.icon && !params.iconHtml) {
7586 return;
7587 }
7588 let oldContent = icon.innerHTML;
7589 let newContent = '';
7590 if (params.iconHtml) {
7591 newContent = iconContent(params.iconHtml);
7592 } else if (params.icon === 'success') {
7593 newContent = successIconHtml(params);
7594 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7595 } else if (params.icon === 'error') {
7596 newContent = errorIconHtml;
7597 } else if (params.icon) {
7598 const defaultIconHtml = {
7599 question: '?',
7600 warning: '!',
7601 info: 'i'
7602 };
7603 newContent = iconContent(defaultIconHtml[params.icon]);
7604 }
7605 if (oldContent.trim() !== newContent.trim()) {
7606 setInnerHtml(icon, newContent);
7607 }
7608 };
7609
7610 /**
7611 * @param {HTMLElement} icon
7612 * @param {SweetAlertOptions} params
7613 */
7614 const setColor = (icon, params) => {
7615 if (!params.iconColor) {
7616 return;
7617 }
7618 icon.style.color = params.iconColor;
7619 icon.style.borderColor = params.iconColor;
7620 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7621 setStyle(icon, sel, 'background-color', params.iconColor);
7622 }
7623 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7624 };
7625
7626 /**
7627 * @param {string} content
7628 * @returns {string}
7629 */
7630 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7631
7632 /**
7633 * @param {SweetAlert} instance
7634 * @param {SweetAlertOptions} params
7635 */
7636 const renderImage = (instance, params) => {
7637 const image = getImage();
7638 if (!image) {
7639 return;
7640 }
7641 if (!params.imageUrl) {
7642 hide(image);
7643 return;
7644 }
7645 show(image, '');
7646
7647 // Src, alt
7648 image.setAttribute('src', params.imageUrl);
7649 image.setAttribute('alt', params.imageAlt || '');
7650
7651 // Width, height
7652 applyNumericalStyle(image, 'width', params.imageWidth);
7653 applyNumericalStyle(image, 'height', params.imageHeight);
7654
7655 // Class
7656 image.className = swalClasses.image;
7657 applyCustomClass(image, params, 'image');
7658 };
7659
7660 let dragging = false;
7661 let mousedownX = 0;
7662 let mousedownY = 0;
7663 let initialX = 0;
7664 let initialY = 0;
7665
7666 /**
7667 * @param {HTMLElement} popup
7668 */
7669 const addDraggableListeners = popup => {
7670 popup.addEventListener('mousedown', down);
7671 document.body.addEventListener('mousemove', move);
7672 popup.addEventListener('mouseup', up);
7673 popup.addEventListener('touchstart', down);
7674 document.body.addEventListener('touchmove', move);
7675 popup.addEventListener('touchend', up);
7676 };
7677
7678 /**
7679 * @param {HTMLElement} popup
7680 */
7681 const removeDraggableListeners = popup => {
7682 popup.removeEventListener('mousedown', down);
7683 document.body.removeEventListener('mousemove', move);
7684 popup.removeEventListener('mouseup', up);
7685 popup.removeEventListener('touchstart', down);
7686 document.body.removeEventListener('touchmove', move);
7687 popup.removeEventListener('touchend', up);
7688 };
7689
7690 /**
7691 * @param {MouseEvent | TouchEvent} event
7692 */
7693 const down = event => {
7694 const popup = getPopup();
7695 if (!popup) {
7696 return;
7697 }
7698 const icon = getIcon();
7699 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7700 dragging = true;
7701 const clientXY = getClientXY(event);
7702 mousedownX = clientXY.clientX;
7703 mousedownY = clientXY.clientY;
7704 initialX = parseInt(popup.style.insetInlineStart) || 0;
7705 initialY = parseInt(popup.style.insetBlockStart) || 0;
7706 addClass(popup, 'swal2-dragging');
7707 }
7708 };
7709
7710 /**
7711 * @param {MouseEvent | TouchEvent} event
7712 */
7713 const move = event => {
7714 const popup = getPopup();
7715 if (!popup) {
7716 return;
7717 }
7718 if (dragging) {
7719 let {
7720 clientX,
7721 clientY
7722 } = getClientXY(event);
7723 const deltaX = clientX - mousedownX;
7724 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7725 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7726 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7727 }
7728 };
7729 const up = () => {
7730 const popup = getPopup();
7731 dragging = false;
7732 removeClass(popup, 'swal2-dragging');
7733 };
7734
7735 /**
7736 * @param {MouseEvent | TouchEvent} event
7737 * @returns {{ clientX: number, clientY: number }}
7738 */
7739 const getClientXY = event => {
7740 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
7741 return {
7742 clientX: source.clientX,
7743 clientY: source.clientY
7744 };
7745 };
7746
7747 /**
7748 * @param {SweetAlert} instance
7749 * @param {SweetAlertOptions} params
7750 */
7751 const renderPopup = (instance, params) => {
7752 const container = getContainer();
7753 const popup = getPopup();
7754 if (!container || !popup) {
7755 return;
7756 }
7757
7758 // Width
7759 // https://github.com/sweetalert2/sweetalert2/issues/2170
7760 if (params.toast) {
7761 applyNumericalStyle(container, 'width', params.width);
7762 popup.style.width = '100%';
7763 const loader = getLoader();
7764 if (loader) {
7765 popup.insertBefore(loader, getIcon());
7766 }
7767 } else {
7768 applyNumericalStyle(popup, 'width', params.width);
7769 }
7770
7771 // Padding
7772 applyNumericalStyle(popup, 'padding', params.padding);
7773
7774 // Color
7775 if (params.color) {
7776 popup.style.color = params.color;
7777 }
7778
7779 // Background
7780 if (params.background) {
7781 popup.style.background = params.background;
7782 }
7783 hide(getValidationMessage());
7784
7785 // Classes
7786 addClasses$1(popup, params);
7787 if (params.draggable && !params.toast) {
7788 addClass(popup, swalClasses.draggable);
7789 addDraggableListeners(popup);
7790 } else {
7791 removeClass(popup, swalClasses.draggable);
7792 removeDraggableListeners(popup);
7793 }
7794 };
7795
7796 /**
7797 * @param {HTMLElement} popup
7798 * @param {SweetAlertOptions} params
7799 */
7800 const addClasses$1 = (popup, params) => {
7801 const showClass = params.showClass || {};
7802 // Default Class + showClass when updating Swal.update({})
7803 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7804 if (params.toast) {
7805 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7806 addClass(popup, swalClasses.toast);
7807 } else {
7808 addClass(popup, swalClasses.modal);
7809 }
7810
7811 // Custom class
7812 applyCustomClass(popup, params, 'popup');
7813 // TODO: remove in the next major
7814 if (typeof params.customClass === 'string') {
7815 addClass(popup, params.customClass);
7816 }
7817
7818 // Icon class (#1842)
7819 if (params.icon) {
7820 addClass(popup, swalClasses[`icon-${params.icon}`]);
7821 }
7822 };
7823
7824 /**
7825 * @param {SweetAlert} instance
7826 * @param {SweetAlertOptions} params
7827 */
7828 const renderProgressSteps = (instance, params) => {
7829 const progressStepsContainer = getProgressSteps();
7830 if (!progressStepsContainer) {
7831 return;
7832 }
7833 const {
7834 progressSteps,
7835 currentProgressStep
7836 } = params;
7837 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
7838 hide(progressStepsContainer);
7839 return;
7840 }
7841 show(progressStepsContainer);
7842 progressStepsContainer.textContent = '';
7843 if (currentProgressStep >= progressSteps.length) {
7844 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
7845 }
7846 progressSteps.forEach((step, index) => {
7847 const stepEl = createStepElement(step);
7848 progressStepsContainer.appendChild(stepEl);
7849 if (index === currentProgressStep) {
7850 addClass(stepEl, swalClasses['active-progress-step']);
7851 }
7852 if (index !== progressSteps.length - 1) {
7853 const lineEl = createLineElement(params);
7854 progressStepsContainer.appendChild(lineEl);
7855 }
7856 });
7857 };
7858
7859 /**
7860 * @param {string} step
7861 * @returns {HTMLLIElement}
7862 */
7863 const createStepElement = step => {
7864 const stepEl = document.createElement('li');
7865 addClass(stepEl, swalClasses['progress-step']);
7866 setInnerHtml(stepEl, step);
7867 return stepEl;
7868 };
7869
7870 /**
7871 * @param {SweetAlertOptions} params
7872 * @returns {HTMLLIElement}
7873 */
7874 const createLineElement = params => {
7875 const lineEl = document.createElement('li');
7876 addClass(lineEl, swalClasses['progress-step-line']);
7877 if (params.progressStepsDistance) {
7878 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
7879 }
7880 return lineEl;
7881 };
7882
7883 /**
7884 * @param {SweetAlert} instance
7885 * @param {SweetAlertOptions} params
7886 */
7887 const renderTitle = (instance, params) => {
7888 const title = getTitle();
7889 if (!title) {
7890 return;
7891 }
7892 showWhenInnerHtmlPresent(title);
7893 toggle(title, Boolean(params.title || params.titleText), 'block');
7894 if (params.title) {
7895 parseHtmlToContainer(params.title, title);
7896 }
7897 if (params.titleText) {
7898 title.innerText = params.titleText;
7899 }
7900
7901 // Custom class
7902 applyCustomClass(title, params, 'title');
7903 };
7904
7905 /**
7906 * @param {SweetAlert} instance
7907 * @param {SweetAlertOptions} params
7908 */
7909 const render = (instance, params) => {
7910 var _globalState$eventEmi;
7911 renderPopup(instance, params);
7912 renderContainer(instance, params);
7913 renderProgressSteps(instance, params);
7914 renderIcon(instance, params);
7915 renderImage(instance, params);
7916 renderTitle(instance, params);
7917 renderCloseButton(instance, params);
7918 renderContent(instance, params);
7919 renderActions(instance, params);
7920 renderFooter(instance, params);
7921 const popup = getPopup();
7922 if (typeof params.didRender === 'function' && popup) {
7923 params.didRender(popup);
7924 }
7925 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
7926 };
7927
7928 /*
7929 * Global function to determine if SweetAlert2 popup is shown
7930 */
7931 const isVisible = () => {
7932 return isVisible$1(getPopup());
7933 };
7934
7935 /*
7936 * Global function to click 'Confirm' button
7937 */
7938 const clickConfirm = () => {
7939 var _dom$getConfirmButton;
7940 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
7941 };
7942
7943 /*
7944 * Global function to click 'Deny' button
7945 */
7946 const clickDeny = () => {
7947 var _dom$getDenyButton;
7948 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
7949 };
7950
7951 /*
7952 * Global function to click 'Cancel' button
7953 */
7954 const clickCancel = () => {
7955 var _dom$getCancelButton;
7956 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
7957 };
7958
7959 /** @type {Record<DismissReason, DismissReason>} */
7960 const DismissReason = Object.freeze({
7961 cancel: 'cancel',
7962 backdrop: 'backdrop',
7963 close: 'close',
7964 esc: 'esc',
7965 timer: 'timer'
7966 });
7967
7968 /**
7969 * @param {GlobalState} globalState
7970 */
7971 const removeKeydownHandler = globalState => {
7972 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
7973 const handler = /** @type {EventListenerOrEventListenerObject} */
7974 /** @type {unknown} */globalState.keydownHandler;
7975 globalState.keydownTarget.removeEventListener('keydown', handler, {
7976 capture: globalState.keydownListenerCapture
7977 });
7978 globalState.keydownHandlerAdded = false;
7979 }
7980 };
7981
7982 /**
7983 * @param {GlobalState} globalState
7984 * @param {SweetAlertOptions} innerParams
7985 * @param {(dismiss: DismissReason) => void} dismissWith
7986 */
7987 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
7988 removeKeydownHandler(globalState);
7989 if (!innerParams.toast) {
7990 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
7991 const handler = e => keydownHandler(innerParams, e, dismissWith);
7992 globalState.keydownHandler = handler;
7993 const target = innerParams.keydownListenerCapture ? window : getPopup();
7994 if (target) {
7995 globalState.keydownTarget = target;
7996 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
7997 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
7998 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
7999 capture: globalState.keydownListenerCapture
8000 });
8001 globalState.keydownHandlerAdded = true;
8002 }
8003 }
8004 };
8005
8006 /**
8007 * @param {number} index
8008 * @param {number} increment
8009 * @returns {boolean} shouldPreventDefault
8010 */
8011 const setFocus = (index, increment) => {
8012 var _dom$getPopup;
8013 const focusableElements = getFocusableElements();
8014 // search for visible elements and select the next possible match
8015 if (focusableElements.length) {
8016 index = index + increment;
8017
8018 // shift + tab when .swal2-popup is focused
8019 if (index === -2) {
8020 index = focusableElements.length - 1;
8021 }
8022
8023 // rollover to first item
8024 if (index === focusableElements.length) {
8025 index = 0;
8026
8027 // go to last item
8028 } else if (index === -1) {
8029 index = focusableElements.length - 1;
8030 }
8031 focusableElements[index].focus();
8032
8033 // don't prevent default for iframes (Firefox fix)
8034 // https://github.com/sweetalert2/sweetalert2/issues/2931
8035 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
8036 return false;
8037 }
8038 return true;
8039 }
8040 // no visible focusable elements, focus the popup
8041 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8042 return true;
8043 };
8044 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8045 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8046
8047 /**
8048 * @param {SweetAlertOptions} innerParams
8049 * @param {KeyboardEvent} event
8050 * @param {(dismiss: DismissReason) => void} dismissWith
8051 */
8052 const keydownHandler = (innerParams, event, dismissWith) => {
8053 if (!innerParams) {
8054 return; // This instance has already been destroyed
8055 }
8056
8057 // Ignore keydown during IME composition
8058 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8059 // https://github.com/sweetalert2/sweetalert2/issues/720
8060 // https://github.com/sweetalert2/sweetalert2/issues/2406
8061 if (event.isComposing || event.keyCode === 229) {
8062 return;
8063 }
8064 if (innerParams.stopKeydownPropagation) {
8065 event.stopPropagation();
8066 }
8067
8068 // ENTER
8069 if (event.key === 'Enter') {
8070 handleEnter(event, innerParams);
8071 }
8072
8073 // TAB
8074 else if (event.key === 'Tab') {
8075 handleTab(event);
8076 }
8077
8078 // ARROWS - switch focus between buttons
8079 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8080 handleArrows(event.key);
8081 }
8082
8083 // ESC
8084 else if (event.key === 'Escape') {
8085 handleEsc(event, innerParams, dismissWith);
8086 }
8087 };
8088
8089 /**
8090 * @param {KeyboardEvent} event
8091 * @param {SweetAlertOptions} innerParams
8092 */
8093 const handleEnter = (event, innerParams) => {
8094 // https://github.com/sweetalert2/sweetalert2/issues/2386
8095 if (!callIfFunction(innerParams.allowEnterKey)) {
8096 return;
8097 }
8098 const popup = getPopup();
8099 if (!popup || !innerParams.input) {
8100 return;
8101 }
8102 const input = getInput$1(popup, innerParams.input);
8103 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8104 if (['textarea', 'file'].includes(innerParams.input)) {
8105 return; // do not submit
8106 }
8107 clickConfirm();
8108 event.preventDefault();
8109 }
8110 };
8111
8112 /**
8113 * @param {KeyboardEvent} event
8114 */
8115 const handleTab = event => {
8116 const targetElement = event.target;
8117 const focusableElements = getFocusableElements();
8118 const btnIndex = focusableElements.findIndex(el => el === targetElement);
8119
8120 // don't prevent default for iframes (Firefox fix)
8121 // https://github.com/sweetalert2/sweetalert2/issues/2931
8122 let shouldPreventDefault = true;
8123
8124 // Cycle to the next button
8125 if (!event.shiftKey) {
8126 shouldPreventDefault = setFocus(btnIndex, 1);
8127 }
8128
8129 // Cycle to the prev button
8130 else {
8131 shouldPreventDefault = setFocus(btnIndex, -1);
8132 }
8133 event.stopPropagation();
8134 if (shouldPreventDefault) {
8135 event.preventDefault();
8136 }
8137 };
8138
8139 /**
8140 * @param {string} key
8141 */
8142 const handleArrows = key => {
8143 const actions = getActions();
8144 const confirmButton = getConfirmButton();
8145 const denyButton = getDenyButton();
8146 const cancelButton = getCancelButton();
8147 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8148 return;
8149 }
8150 /** @type HTMLElement[] */
8151 const buttons = [confirmButton, denyButton, cancelButton];
8152 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8153 return;
8154 }
8155 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8156 let buttonToFocus = document.activeElement;
8157 if (!buttonToFocus) {
8158 return;
8159 }
8160 for (let i = 0; i < actions.children.length; i++) {
8161 buttonToFocus = buttonToFocus[sibling];
8162 if (!buttonToFocus) {
8163 return;
8164 }
8165 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8166 break;
8167 }
8168 }
8169 if (buttonToFocus instanceof HTMLButtonElement) {
8170 buttonToFocus.focus();
8171 }
8172 };
8173
8174 /**
8175 * @param {KeyboardEvent} event
8176 * @param {SweetAlertOptions} innerParams
8177 * @param {(dismiss: DismissReason) => void} dismissWith
8178 */
8179 const handleEsc = (event, innerParams, dismissWith) => {
8180 event.preventDefault();
8181 if (callIfFunction(innerParams.allowEscapeKey)) {
8182 dismissWith(DismissReason.esc);
8183 }
8184 };
8185
8186 /**
8187 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8188 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8189 * This is the approach that Babel will probably take to implement private methods/fields
8190 * https://github.com/tc39/proposal-private-methods
8191 * https://github.com/babel/babel/pull/7555
8192 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8193 * then we can use that language feature.
8194 */
8195
8196 var privateMethods = {
8197 swalPromiseResolve: new WeakMap(),
8198 swalPromiseReject: new WeakMap()
8199 };
8200
8201 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8202 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8203 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8204 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8205
8206 const setAriaHidden = () => {
8207 const container = getContainer();
8208 const bodyChildren = Array.from(document.body.children);
8209 bodyChildren.forEach(el => {
8210 if (el.contains(container)) {
8211 return;
8212 }
8213 if (el.hasAttribute('aria-hidden')) {
8214 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8215 }
8216 el.setAttribute('aria-hidden', 'true');
8217 });
8218 };
8219 const unsetAriaHidden = () => {
8220 const bodyChildren = Array.from(document.body.children);
8221 bodyChildren.forEach(el => {
8222 if (el.hasAttribute('data-previous-aria-hidden')) {
8223 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8224 el.removeAttribute('data-previous-aria-hidden');
8225 } else {
8226 el.removeAttribute('aria-hidden');
8227 }
8228 });
8229 };
8230
8231 // @ts-ignore
8232 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8233
8234 // @ts-ignore
8235 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
8236
8237 /**
8238 * Fix iOS scrolling
8239 * http://stackoverflow.com/q/39626302
8240 */
8241 const iOSfix = () => {
8242 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8243 const offset = document.body.scrollTop;
8244 document.body.style.top = `${offset * -1}px`;
8245 addClass(document.body, swalClasses.iosfix);
8246 lockBodyScroll();
8247 }
8248 };
8249
8250 /**
8251 * https://github.com/sweetalert2/sweetalert2/issues/1246
8252 */
8253 const lockBodyScroll = () => {
8254 const container = getContainer();
8255 if (!container) {
8256 return;
8257 }
8258 /** @type {boolean} */
8259 let preventTouchMove;
8260 /**
8261 * @param {TouchEvent} event
8262 */
8263 container.ontouchstart = event => {
8264 preventTouchMove = shouldPreventTouchMove(event);
8265 };
8266 /**
8267 * @param {TouchEvent} event
8268 */
8269 container.ontouchmove = event => {
8270 if (preventTouchMove) {
8271 event.preventDefault();
8272 event.stopPropagation();
8273 }
8274 };
8275 };
8276
8277 /**
8278 * @param {TouchEvent} event
8279 * @returns {boolean}
8280 */
8281 const shouldPreventTouchMove = event => {
8282 const target = event.target;
8283 const container = getContainer();
8284 const htmlContainer = getHtmlContainer();
8285 if (!container || !htmlContainer) {
8286 return false;
8287 }
8288 if (isStylus(event) || isZoom(event)) {
8289 return false;
8290 }
8291 if (target === container) {
8292 return true;
8293 }
8294 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8295 // #2823
8296 target.tagName !== 'INPUT' &&
8297 // #1603
8298 target.tagName !== 'TEXTAREA' &&
8299 // #2266
8300 !(isScrollable(htmlContainer) &&
8301 // #1944
8302 htmlContainer.contains(target))) {
8303 return true;
8304 }
8305 return false;
8306 };
8307
8308 /**
8309 * https://github.com/sweetalert2/sweetalert2/issues/1786
8310 *
8311 * @param {TouchEvent} event
8312 * @returns {boolean}
8313 */
8314 const isStylus = event => {
8315 return Boolean(event.touches && event.touches.length &&
8316 // @ts-ignore - touchType is not a standard property
8317 event.touches[0].touchType === 'stylus');
8318 };
8319
8320 /**
8321 * https://github.com/sweetalert2/sweetalert2/issues/1891
8322 *
8323 * @param {TouchEvent} event
8324 * @returns {boolean}
8325 */
8326 const isZoom = event => {
8327 return event.touches && event.touches.length > 1;
8328 };
8329 const undoIOSfix = () => {
8330 if (hasClass(document.body, swalClasses.iosfix)) {
8331 const offset = parseInt(document.body.style.top, 10);
8332 removeClass(document.body, swalClasses.iosfix);
8333 document.body.style.top = '';
8334 document.body.scrollTop = offset * -1;
8335 }
8336 };
8337
8338 /**
8339 * Measure scrollbar width for padding body during modal show/hide
8340 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8341 *
8342 * @returns {number}
8343 */
8344 const measureScrollbar = () => {
8345 const scrollDiv = document.createElement('div');
8346 scrollDiv.className = swalClasses['scrollbar-measure'];
8347 document.body.appendChild(scrollDiv);
8348 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8349 document.body.removeChild(scrollDiv);
8350 return scrollbarWidth;
8351 };
8352
8353 /**
8354 * Remember state in cases where opening and handling a modal will fiddle with it.
8355 * @type {number | null}
8356 */
8357 let previousBodyPadding = null;
8358
8359 /**
8360 * @param {string} initialBodyOverflow
8361 */
8362 const replaceScrollbarWithPadding = initialBodyOverflow => {
8363 // for queues, do not do this more than once
8364 if (previousBodyPadding !== null) {
8365 return;
8366 }
8367 // if the body has overflow
8368 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8369 ) {
8370 // add padding so the content doesn't shift after removal of scrollbar
8371 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8372 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8373 }
8374 };
8375 const undoReplaceScrollbarWithPadding = () => {
8376 if (previousBodyPadding !== null) {
8377 document.body.style.paddingRight = `${previousBodyPadding}px`;
8378 previousBodyPadding = null;
8379 }
8380 };
8381
8382 /**
8383 * @param {SweetAlert} instance
8384 * @param {HTMLElement} container
8385 * @param {boolean} returnFocus
8386 * @param {(() => void) | undefined} didClose
8387 */
8388 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8389 if (isToast()) {
8390 triggerDidCloseAndDispose(instance, didClose);
8391 } else {
8392 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8393 removeKeydownHandler(globalState);
8394 }
8395
8396 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8397 // for some reason removing the container in Safari will scroll the document to bottom
8398 if (isSafariOrIOS) {
8399 container.setAttribute('style', 'display:none !important');
8400 container.removeAttribute('class');
8401 container.innerHTML = '';
8402 } else {
8403 container.remove();
8404 }
8405 if (isModal()) {
8406 undoReplaceScrollbarWithPadding();
8407 undoIOSfix();
8408 unsetAriaHidden();
8409 }
8410 removeBodyClasses();
8411 }
8412
8413 /**
8414 * Remove SweetAlert2 classes from body
8415 */
8416 function removeBodyClasses() {
8417 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8418 }
8419
8420 /**
8421 * Instance method to close sweetAlert
8422 *
8423 * @param {SweetAlertResult | undefined} resolveValue
8424 * @this {SweetAlert}
8425 */
8426 function close(resolveValue) {
8427 resolveValue = prepareResolveValue(resolveValue);
8428 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8429 const didClose = triggerClosePopup(this);
8430 if (this.isAwaitingPromise) {
8431 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8432 if (!resolveValue.isDismissed) {
8433 handleAwaitingPromise(this);
8434 swalPromiseResolve(resolveValue);
8435 }
8436 } else if (didClose) {
8437 // Resolve Swal promise
8438 swalPromiseResolve(resolveValue);
8439 }
8440 }
8441
8442 /**
8443 * @param {SweetAlert} instance
8444 * @returns {boolean}
8445 */
8446 const triggerClosePopup = instance => {
8447 const popup = getPopup();
8448 if (!popup) {
8449 return false;
8450 }
8451 const innerParams = privateProps.innerParams.get(instance);
8452 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8453 return false;
8454 }
8455 removeClass(popup, innerParams.showClass.popup);
8456 addClass(popup, innerParams.hideClass.popup);
8457 const backdrop = getContainer();
8458 removeClass(backdrop, innerParams.showClass.backdrop);
8459 addClass(backdrop, innerParams.hideClass.backdrop);
8460 handlePopupAnimation(instance, popup, innerParams);
8461 return true;
8462 };
8463
8464 /**
8465 * @param {Error | string} error
8466 * @this {SweetAlert}
8467 */
8468 function rejectPromise(error) {
8469 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8470 handleAwaitingPromise(this);
8471 if (rejectPromise) {
8472 // Reject Swal promise
8473 rejectPromise(error);
8474 }
8475 }
8476
8477 /**
8478 * @param {SweetAlert} instance
8479 */
8480 const handleAwaitingPromise = instance => {
8481 if (instance.isAwaitingPromise) {
8482 // @ts-ignore
8483 delete instance.isAwaitingPromise;
8484 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8485 if (!privateProps.innerParams.get(instance)) {
8486 instance._destroy();
8487 }
8488 }
8489 };
8490
8491 /**
8492 * @param {SweetAlertResult | undefined} resolveValue
8493 * @returns {SweetAlertResult}
8494 */
8495 const prepareResolveValue = resolveValue => {
8496 // When user calls Swal.close()
8497 if (typeof resolveValue === 'undefined') {
8498 return {
8499 isConfirmed: false,
8500 isDenied: false,
8501 isDismissed: true
8502 };
8503 }
8504 return Object.assign({
8505 isConfirmed: false,
8506 isDenied: false,
8507 isDismissed: false
8508 }, resolveValue);
8509 };
8510
8511 /**
8512 * @param {SweetAlert} instance
8513 * @param {HTMLElement} popup
8514 * @param {SweetAlertOptions} innerParams
8515 */
8516 const handlePopupAnimation = (instance, popup, innerParams) => {
8517 var _globalState$eventEmi;
8518 const container = getContainer();
8519 // If animation is supported, animate
8520 const animationIsSupported = hasCssAnimation(popup);
8521 if (typeof innerParams.willClose === 'function') {
8522 innerParams.willClose(popup);
8523 }
8524 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8525 if (animationIsSupported && container) {
8526 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8527 } else if (container) {
8528 // Otherwise, remove immediately
8529 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8530 }
8531 };
8532
8533 /**
8534 * @param {SweetAlert} instance
8535 * @param {HTMLElement} popup
8536 * @param {HTMLElement} container
8537 * @param {boolean} returnFocus
8538 * @param {(() => void) | undefined} didClose
8539 */
8540 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8541 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8542 /**
8543 * @param {AnimationEvent | TransitionEvent} e
8544 */
8545 const swalCloseAnimationFinished = function (e) {
8546 if (e.target === popup) {
8547 var _globalState$swalClos;
8548 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8549 delete globalState.swalCloseEventFinishedCallback;
8550 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8551 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8552 }
8553 };
8554 popup.addEventListener('animationend', swalCloseAnimationFinished);
8555 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8556 };
8557
8558 /**
8559 * @param {SweetAlert} instance
8560 * @param {(() => void) | undefined} didClose
8561 */
8562 const triggerDidCloseAndDispose = (instance, didClose) => {
8563 setTimeout(() => {
8564 var _globalState$eventEmi2;
8565 if (typeof didClose === 'function') {
8566 didClose.bind(instance.params)();
8567 }
8568 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8569 // instance might have been destroyed already
8570 if (instance._destroy) {
8571 instance._destroy();
8572 }
8573 });
8574 };
8575
8576 /**
8577 * Shows loader (spinner), this is useful with AJAX requests.
8578 * By default the loader be shown instead of the "Confirm" button.
8579 *
8580 * @param {HTMLButtonElement | null} [buttonToReplace]
8581 */
8582 const showLoading = buttonToReplace => {
8583 let popup = getPopup();
8584 if (!popup) {
8585 new Swal();
8586 }
8587 popup = getPopup();
8588 if (!popup) {
8589 return;
8590 }
8591 const loader = getLoader();
8592 if (isToast()) {
8593 hide(getIcon());
8594 } else {
8595 replaceButton(popup, buttonToReplace);
8596 }
8597 show(loader);
8598 popup.setAttribute('data-loading', 'true');
8599 popup.setAttribute('aria-busy', 'true');
8600 popup.focus();
8601 };
8602
8603 /**
8604 * @param {HTMLElement} popup
8605 * @param {HTMLButtonElement | null} [buttonToReplace]
8606 */
8607 const replaceButton = (popup, buttonToReplace) => {
8608 const actions = getActions();
8609 const loader = getLoader();
8610 if (!actions || !loader) {
8611 return;
8612 }
8613 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8614 buttonToReplace = getConfirmButton();
8615 }
8616 show(actions);
8617 if (buttonToReplace) {
8618 hide(buttonToReplace);
8619 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8620 actions.insertBefore(loader, buttonToReplace);
8621 }
8622 addClass([popup, actions], swalClasses.loading);
8623 };
8624
8625 /**
8626 * @param {SweetAlert} instance
8627 * @param {SweetAlertOptions} params
8628 */
8629 const handleInputOptionsAndValue = (instance, params) => {
8630 if (params.input === 'select' || params.input === 'radio') {
8631 handleInputOptions(instance, params);
8632 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8633 showLoading(getConfirmButton());
8634 handleInputValue(instance, params);
8635 }
8636 };
8637
8638 /**
8639 * @param {SweetAlert} instance
8640 * @param {SweetAlertOptions} innerParams
8641 * @returns {SweetAlertInputValue}
8642 */
8643 const getInputValue = (instance, innerParams) => {
8644 const input = instance.getInput();
8645 if (!input) {
8646 return null;
8647 }
8648 switch (innerParams.input) {
8649 case 'checkbox':
8650 return getCheckboxValue(input);
8651 case 'radio':
8652 return getRadioValue(input);
8653 case 'file':
8654 return getFileValue(input);
8655 default:
8656 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8657 }
8658 };
8659
8660 /**
8661 * @param {HTMLInputElement} input
8662 * @returns {number}
8663 */
8664 const getCheckboxValue = input => input.checked ? 1 : 0;
8665
8666 /**
8667 * @param {HTMLInputElement} input
8668 * @returns {string | null}
8669 */
8670 const getRadioValue = input => input.checked ? input.value : null;
8671
8672 /**
8673 * @param {HTMLInputElement} input
8674 * @returns {FileList | File | null}
8675 */
8676 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8677
8678 /**
8679 * @param {SweetAlert} instance
8680 * @param {SweetAlertOptions} params
8681 */
8682 const handleInputOptions = (instance, params) => {
8683 const popup = getPopup();
8684 if (!popup) {
8685 return;
8686 }
8687 /**
8688 * @param {*} inputOptions
8689 */
8690 const processInputOptions = inputOptions => {
8691 if (params.input === 'select') {
8692 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8693 } else if (params.input === 'radio') {
8694 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8695 }
8696 };
8697 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8698 showLoading(getConfirmButton());
8699 asPromise(params.inputOptions).then(inputOptions => {
8700 instance.hideLoading();
8701 processInputOptions(inputOptions);
8702 });
8703 } else if (typeof params.inputOptions === 'object') {
8704 processInputOptions(params.inputOptions);
8705 } else {
8706 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8707 }
8708 };
8709
8710 /**
8711 * @param {SweetAlert} instance
8712 * @param {SweetAlertOptions} params
8713 */
8714 const handleInputValue = (instance, params) => {
8715 const input = instance.getInput();
8716 if (!input) {
8717 return;
8718 }
8719 hide(input);
8720 asPromise(params.inputValue).then(inputValue => {
8721 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8722 show(input);
8723 input.focus();
8724 instance.hideLoading();
8725 }).catch(err => {
8726 error(`Error in inputValue promise: ${err}`);
8727 input.value = '';
8728 show(input);
8729 input.focus();
8730 instance.hideLoading();
8731 });
8732 };
8733
8734 /**
8735 * @param {HTMLElement} popup
8736 * @param {InputOptionFlattened[]} inputOptions
8737 * @param {SweetAlertOptions} params
8738 */
8739 function populateSelectOptions(popup, inputOptions, params) {
8740 const select = getDirectChildByClass(popup, swalClasses.select);
8741 if (!select) {
8742 return;
8743 }
8744 /**
8745 * @param {HTMLElement} parent
8746 * @param {string} optionLabel
8747 * @param {string} optionValue
8748 */
8749 const renderOption = (parent, optionLabel, optionValue) => {
8750 const option = document.createElement('option');
8751 option.value = optionValue;
8752 setInnerHtml(option, optionLabel);
8753 option.selected = isSelected(optionValue, params.inputValue);
8754 parent.appendChild(option);
8755 };
8756 inputOptions.forEach(inputOption => {
8757 const optionValue = inputOption[0];
8758 const optionLabel = inputOption[1];
8759 // <optgroup> spec:
8760 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8761 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8762 // check whether this is a <optgroup>
8763 if (Array.isArray(optionLabel)) {
8764 // if it is an array, then it is an <optgroup>
8765 const optgroup = document.createElement('optgroup');
8766 optgroup.label = optionValue;
8767 optgroup.disabled = false; // not configurable for now
8768 select.appendChild(optgroup);
8769 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8770 } else {
8771 // case of <option>
8772 renderOption(select, optionLabel, optionValue);
8773 }
8774 });
8775 select.focus();
8776 }
8777
8778 /**
8779 * @param {HTMLElement} popup
8780 * @param {InputOptionFlattened[]} inputOptions
8781 * @param {SweetAlertOptions} params
8782 */
8783 function populateRadioOptions(popup, inputOptions, params) {
8784 const radio = getDirectChildByClass(popup, swalClasses.radio);
8785 if (!radio) {
8786 return;
8787 }
8788 inputOptions.forEach(inputOption => {
8789 const radioValue = inputOption[0];
8790 const radioLabel = inputOption[1];
8791 const radioInput = document.createElement('input');
8792 const radioLabelElement = document.createElement('label');
8793 radioInput.type = 'radio';
8794 radioInput.name = swalClasses.radio;
8795 radioInput.value = radioValue;
8796 if (isSelected(radioValue, params.inputValue)) {
8797 radioInput.checked = true;
8798 }
8799 const label = document.createElement('span');
8800 setInnerHtml(label, radioLabel);
8801 label.className = swalClasses.label;
8802 radioLabelElement.appendChild(radioInput);
8803 radioLabelElement.appendChild(label);
8804 radio.appendChild(radioLabelElement);
8805 });
8806 const radios = radio.querySelectorAll('input');
8807 if (radios.length) {
8808 radios[0].focus();
8809 }
8810 }
8811
8812 /**
8813 * Converts `inputOptions` into an array of `[value, label]`s
8814 *
8815 * @param {*} inputOptions
8816 * @typedef {string[]} InputOptionFlattened
8817 * @returns {InputOptionFlattened[]}
8818 */
8819 const formatInputOptions = inputOptions => {
8820 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
8821 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
8822 };
8823
8824 /**
8825 * @param {string} optionValue
8826 * @param {SweetAlertInputValue} inputValue
8827 * @returns {boolean}
8828 */
8829 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
8830
8831 /**
8832 * @param {SweetAlert} instance
8833 */
8834 const handleConfirmButtonClick = instance => {
8835 const innerParams = privateProps.innerParams.get(instance);
8836 instance.disableButtons();
8837 if (innerParams.input) {
8838 handleConfirmOrDenyWithInput(instance, 'confirm');
8839 } else {
8840 confirm(instance, true);
8841 }
8842 };
8843
8844 /**
8845 * @param {SweetAlert} instance
8846 */
8847 const handleDenyButtonClick = instance => {
8848 const innerParams = privateProps.innerParams.get(instance);
8849 instance.disableButtons();
8850 if (innerParams.returnInputValueOnDeny) {
8851 handleConfirmOrDenyWithInput(instance, 'deny');
8852 } else {
8853 deny(instance, false);
8854 }
8855 };
8856
8857 /**
8858 * @param {SweetAlert} instance
8859 * @param {(dismiss: DismissReason) => void} dismissWith
8860 */
8861 const handleCancelButtonClick = (instance, dismissWith) => {
8862 instance.disableButtons();
8863 dismissWith(DismissReason.cancel);
8864 };
8865
8866 /**
8867 * @param {SweetAlert} instance
8868 * @param {'confirm' | 'deny'} type
8869 */
8870 const handleConfirmOrDenyWithInput = (instance, type) => {
8871 const innerParams = privateProps.innerParams.get(instance);
8872 if (!innerParams.input) {
8873 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
8874 return;
8875 }
8876 const input = instance.getInput();
8877 const inputValue = getInputValue(instance, innerParams);
8878 if (innerParams.inputValidator) {
8879 handleInputValidator(instance, inputValue, type);
8880 } else if (input && !input.checkValidity()) {
8881 instance.enableButtons();
8882 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
8883 } else if (type === 'deny') {
8884 deny(instance, inputValue);
8885 } else {
8886 confirm(instance, inputValue);
8887 }
8888 };
8889
8890 /**
8891 * @param {SweetAlert} instance
8892 * @param {SweetAlertInputValue} inputValue
8893 * @param {'confirm' | 'deny'} type
8894 */
8895 const handleInputValidator = (instance, inputValue, type) => {
8896 const innerParams = privateProps.innerParams.get(instance);
8897 instance.disableInput();
8898 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
8899 validationPromise.then(validationMessage => {
8900 instance.enableButtons();
8901 instance.enableInput();
8902 if (validationMessage) {
8903 instance.showValidationMessage(validationMessage);
8904 } else if (type === 'deny') {
8905 deny(instance, inputValue);
8906 } else {
8907 confirm(instance, inputValue);
8908 }
8909 });
8910 };
8911
8912 /**
8913 * @param {SweetAlert} instance
8914 * @param {*} value
8915 */
8916 const deny = (instance, value) => {
8917 const innerParams = privateProps.innerParams.get(instance);
8918 if (innerParams.showLoaderOnDeny) {
8919 showLoading(getDenyButton());
8920 }
8921 if (innerParams.preDeny) {
8922 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
8923 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
8924 preDenyPromise.then(preDenyValue => {
8925 if (preDenyValue === false) {
8926 instance.hideLoading();
8927 handleAwaitingPromise(instance);
8928 } else {
8929 instance.close(/** @type SweetAlertResult */{
8930 isDenied: true,
8931 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
8932 });
8933 }
8934 }).catch(error => rejectWith(instance, error));
8935 } else {
8936 instance.close(/** @type SweetAlertResult */{
8937 isDenied: true,
8938 value
8939 });
8940 }
8941 };
8942
8943 /**
8944 * @param {SweetAlert} instance
8945 * @param {*} value
8946 */
8947 const succeedWith = (instance, value) => {
8948 instance.close(/** @type SweetAlertResult */{
8949 isConfirmed: true,
8950 value
8951 });
8952 };
8953
8954 /**
8955 *
8956 * @param {SweetAlert} instance
8957 * @param {string} error
8958 */
8959 const rejectWith = (instance, error) => {
8960 instance.rejectPromise(error);
8961 };
8962
8963 /**
8964 *
8965 * @param {SweetAlert} instance
8966 * @param {*} value
8967 */
8968 const confirm = (instance, value) => {
8969 const innerParams = privateProps.innerParams.get(instance);
8970 if (innerParams.showLoaderOnConfirm) {
8971 showLoading();
8972 }
8973 if (innerParams.preConfirm) {
8974 instance.resetValidationMessage();
8975 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
8976 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
8977 preConfirmPromise.then(preConfirmValue => {
8978 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
8979 instance.hideLoading();
8980 handleAwaitingPromise(instance);
8981 } else {
8982 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
8983 }
8984 }).catch(error => rejectWith(instance, error));
8985 } else {
8986 succeedWith(instance, value);
8987 }
8988 };
8989
8990 /**
8991 * Hides loader and shows back the button which was hidden by .showLoading()
8992 * @this {SweetAlert}
8993 */
8994 function hideLoading() {
8995 // do nothing if popup is closed
8996 const innerParams = privateProps.innerParams.get(this);
8997 if (!innerParams) {
8998 return;
8999 }
9000 const domCache = privateProps.domCache.get(this);
9001 hide(domCache.loader);
9002 if (isToast()) {
9003 if (innerParams.icon) {
9004 show(getIcon());
9005 }
9006 } else {
9007 showRelatedButton(domCache);
9008 }
9009 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9010 domCache.popup.removeAttribute('aria-busy');
9011 domCache.popup.removeAttribute('data-loading');
9012 this.enableButtons();
9013 }
9014
9015 /**
9016 * @param {DomCache} domCache
9017 */
9018 const showRelatedButton = domCache => {
9019 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9020 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9021 if (buttonToReplace.length) {
9022 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9023 } else if (allButtonsAreHidden()) {
9024 hide(domCache.actions);
9025 }
9026 };
9027
9028 /**
9029 * Gets the input DOM node, this method works with input parameter.
9030 *
9031 * @returns {HTMLInputElement | null}
9032 * @this {SweetAlert}
9033 */
9034 function getInput() {
9035 const innerParams = privateProps.innerParams.get(this);
9036 const domCache = privateProps.domCache.get(this);
9037 if (!domCache) {
9038 return null;
9039 }
9040 return getInput$1(domCache.popup, innerParams.input);
9041 }
9042
9043 /**
9044 * @param {SweetAlert} instance
9045 * @param {string[]} buttons
9046 * @param {boolean} disabled
9047 */
9048 function setButtonsDisabled(instance, buttons, disabled) {
9049 const domCache = privateProps.domCache.get(instance);
9050 buttons.forEach(button => {
9051 domCache[button].disabled = disabled;
9052 });
9053 }
9054
9055 /**
9056 * @param {HTMLInputElement | null} input
9057 * @param {boolean} disabled
9058 */
9059 function setInputDisabled(input, disabled) {
9060 const popup = getPopup();
9061 if (!popup || !input) {
9062 return;
9063 }
9064 if (input.type === 'radio') {
9065 /** @type {NodeListOf<HTMLInputElement>} */
9066 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9067 radios.forEach(radio => {
9068 radio.disabled = disabled;
9069 });
9070 } else {
9071 input.disabled = disabled;
9072 }
9073 }
9074
9075 /**
9076 * Enable all the buttons
9077 * @this {SweetAlert}
9078 */
9079 function enableButtons() {
9080 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9081 const focusedElement = privateProps.focusedElement.get(this);
9082 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
9083 focusedElement.focus();
9084 }
9085 privateProps.focusedElement.delete(this);
9086 }
9087
9088 /**
9089 * Disable all the buttons
9090 * @this {SweetAlert}
9091 */
9092 function disableButtons() {
9093 privateProps.focusedElement.set(this, document.activeElement);
9094 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9095 }
9096
9097 /**
9098 * Enable the input field
9099 * @this {SweetAlert}
9100 */
9101 function enableInput() {
9102 setInputDisabled(this.getInput(), false);
9103 }
9104
9105 /**
9106 * Disable the input field
9107 * @this {SweetAlert}
9108 */
9109 function disableInput() {
9110 setInputDisabled(this.getInput(), true);
9111 }
9112
9113 /**
9114 * Show block with validation message
9115 *
9116 * @param {string} error
9117 * @this {SweetAlert}
9118 */
9119 function showValidationMessage(error) {
9120 const domCache = privateProps.domCache.get(this);
9121 const params = privateProps.innerParams.get(this);
9122 setInnerHtml(domCache.validationMessage, error);
9123 domCache.validationMessage.className = swalClasses['validation-message'];
9124 if (params.customClass && params.customClass.validationMessage) {
9125 addClass(domCache.validationMessage, params.customClass.validationMessage);
9126 }
9127 show(domCache.validationMessage);
9128 const input = this.getInput();
9129 if (input) {
9130 input.setAttribute('aria-invalid', 'true');
9131 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9132 focusInput(input);
9133 addClass(input, swalClasses.inputerror);
9134 }
9135 }
9136
9137 /**
9138 * Hide block with validation message
9139 *
9140 * @this {SweetAlert}
9141 */
9142 function resetValidationMessage() {
9143 const domCache = privateProps.domCache.get(this);
9144 if (domCache.validationMessage) {
9145 hide(domCache.validationMessage);
9146 }
9147 const input = this.getInput();
9148 if (input) {
9149 input.removeAttribute('aria-invalid');
9150 input.removeAttribute('aria-describedby');
9151 removeClass(input, swalClasses.inputerror);
9152 }
9153 }
9154
9155 const defaultParams = {
9156 title: '',
9157 titleText: '',
9158 text: '',
9159 html: '',
9160 footer: '',
9161 icon: undefined,
9162 iconColor: undefined,
9163 iconHtml: undefined,
9164 template: undefined,
9165 toast: false,
9166 draggable: false,
9167 animation: true,
9168 theme: 'light',
9169 showClass: {
9170 popup: 'swal2-show',
9171 backdrop: 'swal2-backdrop-show',
9172 icon: 'swal2-icon-show'
9173 },
9174 hideClass: {
9175 popup: 'swal2-hide',
9176 backdrop: 'swal2-backdrop-hide',
9177 icon: 'swal2-icon-hide'
9178 },
9179 customClass: {},
9180 target: 'body',
9181 color: undefined,
9182 backdrop: true,
9183 heightAuto: true,
9184 allowOutsideClick: true,
9185 allowEscapeKey: true,
9186 allowEnterKey: true,
9187 stopKeydownPropagation: true,
9188 keydownListenerCapture: false,
9189 showConfirmButton: true,
9190 showDenyButton: false,
9191 showCancelButton: false,
9192 preConfirm: undefined,
9193 preDeny: undefined,
9194 confirmButtonText: 'OK',
9195 confirmButtonAriaLabel: '',
9196 confirmButtonColor: undefined,
9197 denyButtonText: 'No',
9198 denyButtonAriaLabel: '',
9199 denyButtonColor: undefined,
9200 cancelButtonText: 'Cancel',
9201 cancelButtonAriaLabel: '',
9202 cancelButtonColor: undefined,
9203 buttonsStyling: true,
9204 reverseButtons: false,
9205 focusConfirm: true,
9206 focusDeny: false,
9207 focusCancel: false,
9208 returnFocus: true,
9209 showCloseButton: false,
9210 closeButtonHtml: '&times;',
9211 closeButtonAriaLabel: 'Close this dialog',
9212 loaderHtml: '',
9213 showLoaderOnConfirm: false,
9214 showLoaderOnDeny: false,
9215 imageUrl: undefined,
9216 imageWidth: undefined,
9217 imageHeight: undefined,
9218 imageAlt: '',
9219 timer: undefined,
9220 timerProgressBar: false,
9221 width: undefined,
9222 padding: undefined,
9223 background: undefined,
9224 input: undefined,
9225 inputPlaceholder: '',
9226 inputLabel: '',
9227 inputValue: '',
9228 inputOptions: {},
9229 inputAutoFocus: true,
9230 inputAutoTrim: true,
9231 inputAttributes: {},
9232 inputValidator: undefined,
9233 returnInputValueOnDeny: false,
9234 validationMessage: undefined,
9235 grow: false,
9236 position: 'center',
9237 progressSteps: [],
9238 currentProgressStep: undefined,
9239 progressStepsDistance: undefined,
9240 willOpen: undefined,
9241 didOpen: undefined,
9242 didRender: undefined,
9243 willClose: undefined,
9244 didClose: undefined,
9245 didDestroy: undefined,
9246 scrollbarPadding: true,
9247 topLayer: false
9248 };
9249 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'];
9250
9251 /** @type {Record<string, string | undefined>} */
9252 const deprecatedParams = {
9253 allowEnterKey: undefined
9254 };
9255 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9256
9257 /**
9258 * Is valid parameter
9259 *
9260 * @param {string} paramName
9261 * @returns {boolean}
9262 */
9263 const isValidParameter = paramName => {
9264 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9265 };
9266
9267 /**
9268 * Is valid parameter for Swal.update() method
9269 *
9270 * @param {string} paramName
9271 * @returns {boolean}
9272 */
9273 const isUpdatableParameter = paramName => {
9274 return updatableParams.indexOf(paramName) !== -1;
9275 };
9276
9277 /**
9278 * Is deprecated parameter
9279 *
9280 * @param {string} paramName
9281 * @returns {string | undefined}
9282 */
9283 const isDeprecatedParameter = paramName => {
9284 return deprecatedParams[paramName];
9285 };
9286
9287 /**
9288 * @param {string} param
9289 */
9290 const checkIfParamIsValid = param => {
9291 if (!isValidParameter(param)) {
9292 warn(`Unknown parameter "${param}"`);
9293 }
9294 };
9295
9296 /**
9297 * @param {string} param
9298 */
9299 const checkIfToastParamIsValid = param => {
9300 if (toastIncompatibleParams.includes(param)) {
9301 warn(`The parameter "${param}" is incompatible with toasts`);
9302 }
9303 };
9304
9305 /**
9306 * @param {string} param
9307 */
9308 const checkIfParamIsDeprecated = param => {
9309 const isDeprecated = isDeprecatedParameter(param);
9310 if (isDeprecated) {
9311 warnAboutDeprecation(param, isDeprecated);
9312 }
9313 };
9314
9315 /**
9316 * Show relevant warnings for given params
9317 *
9318 * @param {SweetAlertOptions} params
9319 */
9320 const showWarningsForParams = params => {
9321 if (params.backdrop === false && params.allowOutsideClick) {
9322 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9323 }
9324 if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'bootstrap-4', 'bootstrap-4-light', 'bootstrap-4-dark', 'bootstrap-5', 'bootstrap-5-light', 'bootstrap-5-dark', 'material-ui', 'material-ui-light', 'material-ui-dark', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
9325 warn(`Invalid theme "${params.theme}"`);
9326 }
9327 for (const param in params) {
9328 checkIfParamIsValid(param);
9329 if (params.toast) {
9330 checkIfToastParamIsValid(param);
9331 }
9332 checkIfParamIsDeprecated(param);
9333 }
9334 };
9335
9336 /**
9337 * Updates popup parameters.
9338 *
9339 * @this {any}
9340 * @param {SweetAlertOptions} params
9341 */
9342 function update(params) {
9343 const container = getContainer();
9344 const popup = getPopup();
9345 const innerParams = privateProps.innerParams.get(this);
9346 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9347 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.`);
9348 return;
9349 }
9350 const validUpdatableParams = filterValidParams(params);
9351 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9352 showWarningsForParams(updatedParams);
9353 if (container) {
9354 container.dataset['swal2Theme'] = updatedParams.theme;
9355 }
9356 render(this, updatedParams);
9357 privateProps.innerParams.set(this, updatedParams);
9358 Object.defineProperties(this, {
9359 params: {
9360 value: Object.assign({}, this.params, params),
9361 writable: false,
9362 enumerable: true
9363 }
9364 });
9365 }
9366
9367 /**
9368 * @param {SweetAlertOptions} params
9369 * @returns {SweetAlertOptions}
9370 */
9371 const filterValidParams = params => {
9372 /** @type {Record<string, any>} */
9373 const validUpdatableParams = {};
9374 Object.keys(params).forEach(param => {
9375 if (isUpdatableParameter(param)) {
9376 const typedParams = /** @type {Record<string, any>} */params;
9377 validUpdatableParams[param] = typedParams[param];
9378 } else {
9379 warn(`Invalid parameter to update: ${param}`);
9380 }
9381 });
9382 return validUpdatableParams;
9383 };
9384
9385 /**
9386 * Dispose the current SweetAlert2 instance
9387 * @this {SweetAlert}
9388 */
9389 function _destroy() {
9390 var _globalState$eventEmi;
9391 const domCache = privateProps.domCache.get(this);
9392 const innerParams = privateProps.innerParams.get(this);
9393 if (!innerParams) {
9394 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9395 return; // This instance has already been destroyed
9396 }
9397
9398 // Check if there is another Swal closing
9399 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9400 globalState.swalCloseEventFinishedCallback();
9401 delete globalState.swalCloseEventFinishedCallback;
9402 }
9403 if (typeof innerParams.didDestroy === 'function') {
9404 innerParams.didDestroy();
9405 }
9406 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9407 disposeSwal(this);
9408 }
9409
9410 /**
9411 * @param {SweetAlert} instance
9412 */
9413 const disposeSwal = instance => {
9414 disposeWeakMaps(instance);
9415 // Unset this.params so GC will dispose it (#1569)
9416 // @ts-ignore
9417 delete instance.params;
9418 // Unset globalState props so GC will dispose globalState (#1569)
9419 delete globalState.keydownHandler;
9420 delete globalState.keydownTarget;
9421 // Unset currentInstance
9422 delete globalState.currentInstance;
9423 };
9424
9425 /**
9426 * @param {SweetAlert} instance
9427 */
9428 const disposeWeakMaps = instance => {
9429 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9430 if (instance.isAwaitingPromise) {
9431 unsetWeakMaps(privateProps, instance);
9432 instance.isAwaitingPromise = true;
9433 } else {
9434 unsetWeakMaps(privateMethods, instance);
9435 unsetWeakMaps(privateProps, instance);
9436
9437 // @ts-ignore
9438 delete instance.isAwaitingPromise;
9439 // Unset instance methods
9440 // @ts-ignore
9441 delete instance.disableButtons;
9442 // @ts-ignore
9443 delete instance.enableButtons;
9444 // @ts-ignore
9445 delete instance.getInput;
9446 // @ts-ignore
9447 delete instance.disableInput;
9448 // @ts-ignore
9449 delete instance.enableInput;
9450 // @ts-ignore
9451 delete instance.hideLoading;
9452 // @ts-ignore
9453 delete instance.disableLoading;
9454 // @ts-ignore
9455 delete instance.showValidationMessage;
9456 // @ts-ignore
9457 delete instance.resetValidationMessage;
9458 // @ts-ignore
9459 delete instance.close;
9460 // @ts-ignore
9461 delete instance.closePopup;
9462 // @ts-ignore
9463 delete instance.closeModal;
9464 // @ts-ignore
9465 delete instance.closeToast;
9466 // @ts-ignore
9467 delete instance.rejectPromise;
9468 // @ts-ignore
9469 delete instance.update;
9470 // @ts-ignore
9471 delete instance._destroy;
9472 }
9473 };
9474
9475 /**
9476 * @param {Record<string, WeakMap<any, any>>} obj
9477 * @param {SweetAlert} instance
9478 */
9479 const unsetWeakMaps = (obj, instance) => {
9480 for (const i in obj) {
9481 obj[i].delete(instance);
9482 }
9483 };
9484
9485 var instanceMethods = /*#__PURE__*/Object.freeze({
9486 __proto__: null,
9487 _destroy: _destroy,
9488 close: close,
9489 closeModal: close,
9490 closePopup: close,
9491 closeToast: close,
9492 disableButtons: disableButtons,
9493 disableInput: disableInput,
9494 disableLoading: hideLoading,
9495 enableButtons: enableButtons,
9496 enableInput: enableInput,
9497 getInput: getInput,
9498 handleAwaitingPromise: handleAwaitingPromise,
9499 hideLoading: hideLoading,
9500 rejectPromise: rejectPromise,
9501 resetValidationMessage: resetValidationMessage,
9502 showValidationMessage: showValidationMessage,
9503 update: update
9504 });
9505
9506 /**
9507 * @param {SweetAlertOptions} innerParams
9508 * @param {DomCache} domCache
9509 * @param {(dismiss: DismissReason) => void} dismissWith
9510 */
9511 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9512 if (innerParams.toast) {
9513 handleToastClick(innerParams, domCache, dismissWith);
9514 } else {
9515 // Ignore click events that had mousedown on the popup but mouseup on the container
9516 // This can happen when the user drags a slider
9517 handleModalMousedown(domCache);
9518
9519 // Ignore click events that had mousedown on the container but mouseup on the popup
9520 handleContainerMousedown(domCache);
9521 handleModalClick(innerParams, domCache, dismissWith);
9522 }
9523 };
9524
9525 /**
9526 * @param {SweetAlertOptions} innerParams
9527 * @param {DomCache} domCache
9528 * @param {(dismiss: DismissReason) => void} dismissWith
9529 */
9530 const handleToastClick = (innerParams, domCache, dismissWith) => {
9531 // Closing toast by internal click
9532 domCache.popup.onclick = () => {
9533 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9534 return;
9535 }
9536 dismissWith(DismissReason.close);
9537 };
9538 };
9539
9540 /**
9541 * @param {SweetAlertOptions} innerParams
9542 * @returns {boolean}
9543 */
9544 const isAnyButtonShown = innerParams => {
9545 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9546 };
9547 let ignoreOutsideClick = false;
9548
9549 /**
9550 * @param {DomCache} domCache
9551 */
9552 const handleModalMousedown = domCache => {
9553 domCache.popup.onmousedown = () => {
9554 domCache.container.onmouseup = function (e) {
9555 domCache.container.onmouseup = () => {};
9556 // We only check if the mouseup target is the container because usually it doesn't
9557 // have any other direct children aside of the popup
9558 if (e.target === domCache.container) {
9559 ignoreOutsideClick = true;
9560 }
9561 };
9562 };
9563 };
9564
9565 /**
9566 * @param {DomCache} domCache
9567 */
9568 const handleContainerMousedown = domCache => {
9569 domCache.container.onmousedown = e => {
9570 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9571 if (e.target === domCache.container) {
9572 e.preventDefault();
9573 }
9574 domCache.popup.onmouseup = function (e) {
9575 domCache.popup.onmouseup = () => {};
9576 // We also need to check if the mouseup target is a child of the popup
9577 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9578 ignoreOutsideClick = true;
9579 }
9580 };
9581 };
9582 };
9583
9584 /**
9585 * @param {SweetAlertOptions} innerParams
9586 * @param {DomCache} domCache
9587 * @param {(dismiss: DismissReason) => void} dismissWith
9588 */
9589 const handleModalClick = (innerParams, domCache, dismissWith) => {
9590 domCache.container.onclick = e => {
9591 if (ignoreOutsideClick) {
9592 ignoreOutsideClick = false;
9593 return;
9594 }
9595 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9596 dismissWith(DismissReason.backdrop);
9597 }
9598 };
9599 };
9600
9601 /**
9602 * @param {unknown} elem
9603 * @returns {boolean}
9604 */
9605 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
9606
9607 /**
9608 * @param {unknown} elem
9609 * @returns {boolean}
9610 */
9611 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9612
9613 /**
9614 * @param {ReadonlyArray<unknown>} args
9615 * @returns {SweetAlertOptions}
9616 */
9617 const argsToParams = args => {
9618 /** @type {Record<string, unknown>} */
9619 const params = {};
9620 if (typeof args[0] === 'object' && !isElement(args[0])) {
9621 Object.assign(params, args[0]);
9622 } else {
9623 ['title', 'html', 'icon'].forEach((name, index) => {
9624 const arg = args[index];
9625 if (typeof arg === 'string' || isElement(arg)) {
9626 params[name] = arg;
9627 } else if (arg !== undefined) {
9628 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9629 }
9630 });
9631 }
9632 return /** @type {SweetAlertOptions} */params;
9633 };
9634
9635 /**
9636 * Main method to create a new SweetAlert2 popup
9637 *
9638 * @this {new (...args: any[]) => any}
9639 * @param {...SweetAlertOptions} args
9640 * @returns {Promise<SweetAlertResult>}
9641 */
9642 function fire(...args) {
9643 return new this(...args);
9644 }
9645
9646 /**
9647 * Returns an extended version of `Swal` containing `params` as defaults.
9648 * Useful for reusing Swal configuration.
9649 *
9650 * For example:
9651 *
9652 * Before:
9653 * const textPromptOptions = { input: 'text', showCancelButton: true }
9654 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9655 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9656 *
9657 * After:
9658 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9659 * const {value: firstName} = await TextPrompt('What is your first name?')
9660 * const {value: lastName} = await TextPrompt('What is your last name?')
9661 *
9662 * @param {SweetAlertOptions} mixinParams
9663 * @returns {SweetAlert}
9664 * @this {typeof import('../SweetAlert.js').SweetAlert}
9665 */
9666 function mixin(mixinParams) {
9667 // @ts-ignore: 'this' refers to the SweetAlert constructor
9668 class MixinSwal extends this {
9669 /**
9670 * @param {any} params
9671 * @param {any} priorityMixinParams
9672 */
9673 _main(params, priorityMixinParams) {
9674 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9675 }
9676 }
9677 // @ts-ignore
9678 return MixinSwal;
9679 }
9680
9681 /**
9682 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9683 * Otherwise, returns undefined.
9684 *
9685 * @returns {number | undefined}
9686 */
9687 const getTimerLeft = () => {
9688 return globalState.timeout && globalState.timeout.getTimerLeft();
9689 };
9690
9691 /**
9692 * Stop timer. Returns number of milliseconds of timer remained.
9693 * If `timer` parameter isn't set, returns undefined.
9694 *
9695 * @returns {number | undefined}
9696 */
9697 const stopTimer = () => {
9698 if (globalState.timeout) {
9699 stopTimerProgressBar();
9700 return globalState.timeout.stop();
9701 }
9702 };
9703
9704 /**
9705 * Resume timer. Returns number of milliseconds of timer remained.
9706 * If `timer` parameter isn't set, returns undefined.
9707 *
9708 * @returns {number | undefined}
9709 */
9710 const resumeTimer = () => {
9711 if (globalState.timeout) {
9712 const remaining = globalState.timeout.start();
9713 animateTimerProgressBar(remaining);
9714 return remaining;
9715 }
9716 };
9717
9718 /**
9719 * Resume timer. Returns number of milliseconds of timer remained.
9720 * If `timer` parameter isn't set, returns undefined.
9721 *
9722 * @returns {number | undefined}
9723 */
9724 const toggleTimer = () => {
9725 const timer = globalState.timeout;
9726 return timer && (timer.running ? stopTimer() : resumeTimer());
9727 };
9728
9729 /**
9730 * Increase timer. Returns number of milliseconds of an updated timer.
9731 * If `timer` parameter isn't set, returns undefined.
9732 *
9733 * @param {number} ms
9734 * @returns {number | undefined}
9735 */
9736 const increaseTimer = ms => {
9737 if (globalState.timeout) {
9738 const remaining = globalState.timeout.increase(ms);
9739 animateTimerProgressBar(remaining, true);
9740 return remaining;
9741 }
9742 };
9743
9744 /**
9745 * Check if timer is running. Returns true if timer is running
9746 * or false if timer is paused or stopped.
9747 * If `timer` parameter isn't set, returns undefined
9748 *
9749 * @returns {boolean}
9750 */
9751 const isTimerRunning = () => {
9752 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9753 };
9754
9755 let bodyClickListenerAdded = false;
9756 /** @type {Record<string, any>} */
9757 const clickHandlers = {};
9758
9759 /**
9760 * @this {any}
9761 * @param {string} attr
9762 */
9763 function bindClickHandler(attr = 'data-swal-template') {
9764 clickHandlers[attr] = this;
9765 if (!bodyClickListenerAdded) {
9766 document.body.addEventListener('click', bodyClickListener);
9767 bodyClickListenerAdded = true;
9768 }
9769 }
9770
9771 /**
9772 * @param {MouseEvent} event
9773 */
9774 const bodyClickListener = event => {
9775 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9776 for (const attr in clickHandlers) {
9777 const template = el.getAttribute && el.getAttribute(attr);
9778 if (template) {
9779 clickHandlers[attr].fire({
9780 template
9781 });
9782 return;
9783 }
9784 }
9785 }
9786 };
9787
9788 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9789
9790 class EventEmitter {
9791 constructor() {
9792 /** @type {Events} */
9793 this.events = {};
9794 }
9795
9796 /**
9797 * @param {string} eventName
9798 * @returns {EventHandlers}
9799 */
9800 _getHandlersByEventName(eventName) {
9801 if (typeof this.events[eventName] === 'undefined') {
9802 // not Set because we need to keep the FIFO order
9803 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9804 this.events[eventName] = [];
9805 }
9806 return this.events[eventName];
9807 }
9808
9809 /**
9810 * @param {string} eventName
9811 * @param {EventHandler} eventHandler
9812 */
9813 on(eventName, eventHandler) {
9814 const currentHandlers = this._getHandlersByEventName(eventName);
9815 if (!currentHandlers.includes(eventHandler)) {
9816 currentHandlers.push(eventHandler);
9817 }
9818 }
9819
9820 /**
9821 * @param {string} eventName
9822 * @param {EventHandler} eventHandler
9823 */
9824 once(eventName, eventHandler) {
9825 /**
9826 * @param {...any} args
9827 */
9828 const onceFn = (...args) => {
9829 this.removeListener(eventName, onceFn);
9830 // @ts-ignore
9831 eventHandler.apply(this, args);
9832 };
9833 this.on(eventName, onceFn);
9834 }
9835
9836 /**
9837 * @param {string} eventName
9838 * @param {...any} args
9839 */
9840 emit(eventName, ...args) {
9841 this._getHandlersByEventName(eventName).forEach(
9842 /**
9843 * @param {EventHandler} eventHandler
9844 */
9845 eventHandler => {
9846 try {
9847 // @ts-ignore
9848 eventHandler.apply(this, args);
9849 } catch (error) {
9850 console.error(error);
9851 }
9852 });
9853 }
9854
9855 /**
9856 * @param {string} eventName
9857 * @param {EventHandler} eventHandler
9858 */
9859 removeListener(eventName, eventHandler) {
9860 const currentHandlers = this._getHandlersByEventName(eventName);
9861 const index = currentHandlers.indexOf(eventHandler);
9862 if (index > -1) {
9863 currentHandlers.splice(index, 1);
9864 }
9865 }
9866
9867 /**
9868 * @param {string} eventName
9869 */
9870 removeAllListeners(eventName) {
9871 if (this.events[eventName] !== undefined) {
9872 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
9873 this.events[eventName].length = 0;
9874 }
9875 }
9876 reset() {
9877 this.events = {};
9878 }
9879 }
9880
9881 globalState.eventEmitter = new EventEmitter();
9882
9883 /**
9884 * @param {string} eventName
9885 * @param {EventHandler} eventHandler
9886 */
9887 const on = (eventName, eventHandler) => {
9888 if (globalState.eventEmitter) {
9889 globalState.eventEmitter.on(eventName, eventHandler);
9890 }
9891 };
9892
9893 /**
9894 * @param {string} eventName
9895 * @param {EventHandler} eventHandler
9896 */
9897 const once = (eventName, eventHandler) => {
9898 if (globalState.eventEmitter) {
9899 globalState.eventEmitter.once(eventName, eventHandler);
9900 }
9901 };
9902
9903 /**
9904 * @param {string} [eventName]
9905 * @param {EventHandler} [eventHandler]
9906 */
9907 const off = (eventName, eventHandler) => {
9908 if (!globalState.eventEmitter) {
9909 return;
9910 }
9911
9912 // Remove all handlers for all events
9913 if (!eventName) {
9914 globalState.eventEmitter.reset();
9915 return;
9916 }
9917 if (eventHandler) {
9918 // Remove a specific handler
9919 globalState.eventEmitter.removeListener(eventName, eventHandler);
9920 } else {
9921 // Remove all handlers for a specific event
9922 globalState.eventEmitter.removeAllListeners(eventName);
9923 }
9924 };
9925
9926 var staticMethods = /*#__PURE__*/Object.freeze({
9927 __proto__: null,
9928 argsToParams: argsToParams,
9929 bindClickHandler: bindClickHandler,
9930 clickCancel: clickCancel,
9931 clickConfirm: clickConfirm,
9932 clickDeny: clickDeny,
9933 enableLoading: showLoading,
9934 fire: fire,
9935 getActions: getActions,
9936 getCancelButton: getCancelButton,
9937 getCloseButton: getCloseButton,
9938 getConfirmButton: getConfirmButton,
9939 getContainer: getContainer,
9940 getDenyButton: getDenyButton,
9941 getFocusableElements: getFocusableElements,
9942 getFooter: getFooter,
9943 getHtmlContainer: getHtmlContainer,
9944 getIcon: getIcon,
9945 getIconContent: getIconContent,
9946 getImage: getImage,
9947 getInputLabel: getInputLabel,
9948 getLoader: getLoader,
9949 getPopup: getPopup,
9950 getProgressSteps: getProgressSteps,
9951 getTimerLeft: getTimerLeft,
9952 getTimerProgressBar: getTimerProgressBar,
9953 getTitle: getTitle,
9954 getValidationMessage: getValidationMessage,
9955 increaseTimer: increaseTimer,
9956 isDeprecatedParameter: isDeprecatedParameter,
9957 isLoading: isLoading,
9958 isTimerRunning: isTimerRunning,
9959 isUpdatableParameter: isUpdatableParameter,
9960 isValidParameter: isValidParameter,
9961 isVisible: isVisible,
9962 mixin: mixin,
9963 off: off,
9964 on: on,
9965 once: once,
9966 resumeTimer: resumeTimer,
9967 showLoading: showLoading,
9968 stopTimer: stopTimer,
9969 toggleTimer: toggleTimer
9970 });
9971
9972 class Timer {
9973 /**
9974 * @param {() => void} callback
9975 * @param {number} delay
9976 */
9977 constructor(callback, delay) {
9978 this.callback = callback;
9979 this.remaining = delay;
9980 this.running = false;
9981 this.start();
9982 }
9983
9984 /**
9985 * @returns {number}
9986 */
9987 start() {
9988 if (!this.running) {
9989 this.running = true;
9990 this.started = new Date();
9991 this.id = setTimeout(this.callback, this.remaining);
9992 }
9993 return this.remaining;
9994 }
9995
9996 /**
9997 * @returns {number}
9998 */
9999 stop() {
10000 if (this.started && this.running) {
10001 this.running = false;
10002 clearTimeout(this.id);
10003 this.remaining -= new Date().getTime() - this.started.getTime();
10004 }
10005 return this.remaining;
10006 }
10007
10008 /**
10009 * @param {number} n
10010 * @returns {number}
10011 */
10012 increase(n) {
10013 const running = this.running;
10014 if (running) {
10015 this.stop();
10016 }
10017 this.remaining += n;
10018 if (running) {
10019 this.start();
10020 }
10021 return this.remaining;
10022 }
10023
10024 /**
10025 * @returns {number}
10026 */
10027 getTimerLeft() {
10028 if (this.running) {
10029 this.stop();
10030 this.start();
10031 }
10032 return this.remaining;
10033 }
10034
10035 /**
10036 * @returns {boolean}
10037 */
10038 isRunning() {
10039 return this.running;
10040 }
10041 }
10042
10043 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10044
10045 /**
10046 * @param {SweetAlertOptions} params
10047 * @returns {SweetAlertOptions}
10048 */
10049 const getTemplateParams = params => {
10050 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10051 if (!template) {
10052 return {};
10053 }
10054 /** @type {DocumentFragment} */
10055 const templateContent = template.content;
10056 showWarningsForElements(templateContent);
10057 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10058 return result;
10059 };
10060
10061 /**
10062 * @param {DocumentFragment} templateContent
10063 * @returns {Record<string, string | boolean | number>}
10064 */
10065 const getSwalParams = templateContent => {
10066 /** @type {Record<string, string | boolean | number>} */
10067 const result = {};
10068 /** @type {HTMLElement[]} */
10069 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10070 swalParams.forEach(param => {
10071 showWarningsForAttributes(param, ['name', 'value']);
10072 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10073 const value = param.getAttribute('value');
10074 if (!paramName || !value) {
10075 return;
10076 }
10077 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10078 result[paramName] = value !== 'false';
10079 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10080 result[paramName] = JSON.parse(value);
10081 } else {
10082 result[paramName] = value;
10083 }
10084 });
10085 return result;
10086 };
10087
10088 /**
10089 * @param {DocumentFragment} templateContent
10090 * @returns {Record<string, () => void>}
10091 */
10092 const getSwalFunctionParams = templateContent => {
10093 /** @type {Record<string, () => void>} */
10094 const result = {};
10095 /** @type {HTMLElement[]} */
10096 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10097 swalFunctions.forEach(param => {
10098 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10099 const value = param.getAttribute('value');
10100 if (!paramName || !value) {
10101 return;
10102 }
10103 result[paramName] = new Function(`return ${value}`)();
10104 });
10105 return result;
10106 };
10107
10108 /**
10109 * @param {DocumentFragment} templateContent
10110 * @returns {Record<string, string | boolean>}
10111 */
10112 const getSwalButtons = templateContent => {
10113 /** @type {Record<string, string | boolean>} */
10114 const result = {};
10115 /** @type {HTMLElement[]} */
10116 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10117 swalButtons.forEach(button => {
10118 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10119 const type = button.getAttribute('type');
10120 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10121 return;
10122 }
10123 result[`${type}ButtonText`] = button.innerHTML;
10124 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10125 const color = button.getAttribute('color');
10126 if (color !== null) {
10127 result[`${type}ButtonColor`] = color;
10128 }
10129 const ariaLabel = button.getAttribute('aria-label');
10130 if (ariaLabel !== null) {
10131 result[`${type}ButtonAriaLabel`] = ariaLabel;
10132 }
10133 });
10134 return result;
10135 };
10136
10137 /**
10138 * @param {DocumentFragment} templateContent
10139 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10140 */
10141 const getSwalImage = templateContent => {
10142 const result = {};
10143 /** @type {HTMLElement | null} */
10144 const image = templateContent.querySelector('swal-image');
10145 if (image) {
10146 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10147 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
10148 const src = image.getAttribute('src');
10149 if (src !== null) result.imageUrl = src || undefined;
10150 const width = image.getAttribute('width');
10151 if (width !== null) result.imageWidth = width || undefined;
10152 const height = image.getAttribute('height');
10153 if (height !== null) result.imageHeight = height || undefined;
10154 const alt = image.getAttribute('alt');
10155 if (alt !== null) result.imageAlt = alt || undefined;
10156 }
10157 return result;
10158 };
10159
10160 /**
10161 * @param {DocumentFragment} templateContent
10162 * @returns {object}
10163 */
10164 const getSwalIcon = templateContent => {
10165 const result = {};
10166 /** @type {HTMLElement | null} */
10167 const icon = templateContent.querySelector('swal-icon');
10168 if (icon) {
10169 showWarningsForAttributes(icon, ['type', 'color']);
10170 if (icon.hasAttribute('type')) {
10171 result.icon = icon.getAttribute('type');
10172 }
10173 if (icon.hasAttribute('color')) {
10174 result.iconColor = icon.getAttribute('color');
10175 }
10176 result.iconHtml = icon.innerHTML;
10177 }
10178 return result;
10179 };
10180
10181 /**
10182 * @param {DocumentFragment} templateContent
10183 * @returns {object}
10184 */
10185 const getSwalInput = templateContent => {
10186 /** @type {Record<string, any>} */
10187 const result = {};
10188 /** @type {HTMLElement | null} */
10189 const input = templateContent.querySelector('swal-input');
10190 if (input) {
10191 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10192 result.input = input.getAttribute('type') || 'text';
10193 if (input.hasAttribute('label')) {
10194 result.inputLabel = input.getAttribute('label');
10195 }
10196 if (input.hasAttribute('placeholder')) {
10197 result.inputPlaceholder = input.getAttribute('placeholder');
10198 }
10199 if (input.hasAttribute('value')) {
10200 result.inputValue = input.getAttribute('value');
10201 }
10202 }
10203 /** @type {HTMLElement[]} */
10204 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10205 if (inputOptions.length) {
10206 result.inputOptions = {};
10207 inputOptions.forEach(option => {
10208 showWarningsForAttributes(option, ['value']);
10209 const optionValue = option.getAttribute('value');
10210 if (!optionValue) {
10211 return;
10212 }
10213 const optionName = option.innerHTML;
10214 result.inputOptions[optionValue] = optionName;
10215 });
10216 }
10217 return result;
10218 };
10219
10220 /**
10221 * @param {DocumentFragment} templateContent
10222 * @param {string[]} paramNames
10223 * @returns {Record<string, string>}
10224 */
10225 const getSwalStringParams = (templateContent, paramNames) => {
10226 /** @type {Record<string, string>} */
10227 const result = {};
10228 for (const i in paramNames) {
10229 const paramName = paramNames[i];
10230 /** @type {HTMLElement | null} */
10231 const tag = templateContent.querySelector(paramName);
10232 if (tag) {
10233 showWarningsForAttributes(tag, []);
10234 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10235 }
10236 }
10237 return result;
10238 };
10239
10240 /**
10241 * @param {DocumentFragment} templateContent
10242 */
10243 const showWarningsForElements = templateContent => {
10244 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10245 Array.from(templateContent.children).forEach(el => {
10246 const tagName = el.tagName.toLowerCase();
10247 if (!allowedElements.includes(tagName)) {
10248 warn(`Unrecognized element <${tagName}>`);
10249 }
10250 });
10251 };
10252
10253 /**
10254 * @param {HTMLElement} el
10255 * @param {string[]} allowedAttributes
10256 */
10257 const showWarningsForAttributes = (el, allowedAttributes) => {
10258 Array.from(el.attributes).forEach(attribute => {
10259 if (allowedAttributes.indexOf(attribute.name) === -1) {
10260 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.'}`]);
10261 }
10262 });
10263 };
10264
10265 const SHOW_CLASS_TIMEOUT = 10;
10266
10267 /**
10268 * Open popup, add necessary classes and styles, fix scrollbar
10269 *
10270 * @param {SweetAlertOptions} params
10271 */
10272 const openPopup = params => {
10273 var _globalState$eventEmi, _globalState$eventEmi2;
10274 const container = getContainer();
10275 const popup = getPopup();
10276 if (!container || !popup) {
10277 return;
10278 }
10279 if (typeof params.willOpen === 'function') {
10280 params.willOpen(popup);
10281 }
10282 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10283 const bodyStyles = window.getComputedStyle(document.body);
10284 const initialBodyOverflow = bodyStyles.overflowY;
10285 addClasses(container, popup, params);
10286
10287 // scrolling is 'hidden' until animation is done, after that 'auto'
10288 setTimeout(() => {
10289 setScrollingVisibility(container, popup);
10290 }, SHOW_CLASS_TIMEOUT);
10291 if (isModal()) {
10292 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10293 setAriaHidden();
10294 }
10295
10296 // https://github.com/sweetalert2/sweetalert2/issues/2923
10297 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
10298 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
10299 container.style.pointerEvents = 'auto';
10300 }
10301 if (!isToast() && !globalState.previousActiveElement) {
10302 globalState.previousActiveElement = document.activeElement;
10303 }
10304 if (typeof params.didOpen === 'function') {
10305 const didOpen = params.didOpen;
10306 setTimeout(() => didOpen(popup));
10307 }
10308 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10309 };
10310
10311 /**
10312 * @param {Event} event
10313 */
10314 const swalOpenAnimationFinished = event => {
10315 const popup = getPopup();
10316 if (!popup || event.target !== popup) {
10317 return;
10318 }
10319 const container = getContainer();
10320 if (!container) {
10321 return;
10322 }
10323 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10324 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10325 container.style.overflowY = 'auto';
10326
10327 // no-transition is added in init() in case one swal is opened right after another
10328 removeClass(container, swalClasses['no-transition']);
10329 };
10330
10331 /**
10332 * @param {HTMLElement} container
10333 * @param {HTMLElement} popup
10334 */
10335 const setScrollingVisibility = (container, popup) => {
10336 if (hasCssAnimation(popup)) {
10337 container.style.overflowY = 'hidden';
10338 popup.addEventListener('animationend', swalOpenAnimationFinished);
10339 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10340 } else {
10341 container.style.overflowY = 'auto';
10342 }
10343 };
10344
10345 /**
10346 * @param {HTMLElement} container
10347 * @param {boolean} scrollbarPadding
10348 * @param {string} initialBodyOverflow
10349 */
10350 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10351 iOSfix();
10352 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10353 replaceScrollbarWithPadding(initialBodyOverflow);
10354 }
10355
10356 // sweetalert2/issues/1247
10357 setTimeout(() => {
10358 container.scrollTop = 0;
10359 });
10360 };
10361
10362 /**
10363 * @param {HTMLElement} container
10364 * @param {HTMLElement} popup
10365 * @param {SweetAlertOptions} params
10366 */
10367 const addClasses = (container, popup, params) => {
10368 var _params$showClass;
10369 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10370 addClass(container, params.showClass.backdrop);
10371 }
10372 if (params.animation) {
10373 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10374 popup.style.setProperty('opacity', '0', 'important');
10375 show(popup, 'grid');
10376 setTimeout(() => {
10377 var _params$showClass2;
10378 // Animate popup right after showing it
10379 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10380 addClass(popup, params.showClass.popup);
10381 }
10382 // and remove the opacity workaround
10383 popup.style.removeProperty('opacity');
10384 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10385 } else {
10386 show(popup, 'grid');
10387 }
10388 addClass([document.documentElement, document.body], swalClasses.shown);
10389 if (params.heightAuto && params.backdrop && !params.toast) {
10390 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10391 }
10392 };
10393
10394 var defaultInputValidators = {
10395 /**
10396 * @param {string} string
10397 * @param {string} [validationMessage]
10398 * @returns {Promise<string | void>}
10399 */
10400 email: (string, validationMessage) => {
10401 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10402 },
10403 /**
10404 * @param {string} string
10405 * @param {string} [validationMessage]
10406 * @returns {Promise<string | void>}
10407 */
10408 url: (string, validationMessage) => {
10409 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10410 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');
10411 }
10412 };
10413
10414 /**
10415 * @param {SweetAlertOptions} params
10416 */
10417 function setDefaultInputValidators(params) {
10418 // Use default `inputValidator` for supported input types if not provided
10419 if (params.inputValidator) {
10420 return;
10421 }
10422 if (params.input === 'email') {
10423 params.inputValidator = defaultInputValidators['email'];
10424 }
10425 if (params.input === 'url') {
10426 params.inputValidator = defaultInputValidators['url'];
10427 }
10428 }
10429
10430 /**
10431 * @param {SweetAlertOptions} params
10432 */
10433 function validateCustomTargetElement(params) {
10434 // Determine if the custom target element is valid
10435 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10436 warn('Target parameter is not valid, defaulting to "body"');
10437 params.target = 'body';
10438 }
10439 }
10440
10441 /**
10442 * Set type, text and actions on popup
10443 *
10444 * @param {SweetAlertOptions} params
10445 */
10446 function setParameters(params) {
10447 setDefaultInputValidators(params);
10448
10449 // showLoaderOnConfirm && preConfirm
10450 if (params.showLoaderOnConfirm && !params.preConfirm) {
10451 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');
10452 }
10453 validateCustomTargetElement(params);
10454
10455 // Replace newlines with <br> in title
10456 if (typeof params.title === 'string') {
10457 params.title = params.title.split('\n').join('<br />');
10458 }
10459 init(params);
10460 }
10461
10462 /** @type {SweetAlert} */
10463 let currentInstance;
10464 var _promise = /*#__PURE__*/new WeakMap();
10465 class SweetAlert {
10466 /**
10467 * @param {...(SweetAlertOptions | string)} args
10468 * @this {SweetAlert}
10469 */
10470 constructor(...args) {
10471 /**
10472 * @type {Promise<SweetAlertResult>}
10473 */
10474 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
10475 Promise.resolve({
10476 isConfirmed: false,
10477 isDenied: false,
10478 isDismissed: true
10479 }));
10480 // Prevent run in Node env
10481 if (typeof window === 'undefined') {
10482 return;
10483 }
10484 currentInstance = this;
10485
10486 // @ts-ignore
10487 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10488
10489 /** @type {Readonly<SweetAlertOptions>} */
10490 this.params = outerParams;
10491
10492 /** @type {boolean} */
10493 this.isAwaitingPromise = false;
10494 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10495 }
10496
10497 /**
10498 * @param {any} userParams
10499 * @param {any} mixinParams
10500 */
10501 _main(userParams, mixinParams = {}) {
10502 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10503 if (globalState.currentInstance) {
10504 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10505 const {
10506 isAwaitingPromise
10507 } = globalState.currentInstance;
10508 globalState.currentInstance._destroy();
10509 if (!isAwaitingPromise) {
10510 swalPromiseResolve({
10511 isDismissed: true
10512 });
10513 }
10514 if (isModal()) {
10515 unsetAriaHidden();
10516 }
10517 }
10518 globalState.currentInstance = currentInstance;
10519 const innerParams = prepareParams(userParams, mixinParams);
10520 setParameters(innerParams);
10521 Object.freeze(innerParams);
10522
10523 // clear the previous timer
10524 if (globalState.timeout) {
10525 globalState.timeout.stop();
10526 delete globalState.timeout;
10527 }
10528
10529 // clear the restore focus timeout
10530 clearTimeout(globalState.restoreFocusTimeout);
10531 const domCache = populateDomCache(currentInstance);
10532 render(currentInstance, innerParams);
10533 privateProps.innerParams.set(currentInstance, innerParams);
10534 return swalPromise(currentInstance, domCache, innerParams);
10535 }
10536
10537 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10538 /**
10539 * @param {any} onFulfilled
10540 */
10541 // oxlint-disable-next-line unicorn/no-thenable
10542 then(onFulfilled) {
10543 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10544 }
10545
10546 /**
10547 * @param {any} onFinally
10548 */
10549 finally(onFinally) {
10550 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10551 }
10552 }
10553
10554 /**
10555 * @param {SweetAlert} instance
10556 * @param {DomCache} domCache
10557 * @param {SweetAlertOptions} innerParams
10558 * @returns {Promise<SweetAlertResult>}
10559 */
10560 const swalPromise = (instance, domCache, innerParams) => {
10561 return new Promise((resolve, reject) => {
10562 // functions to handle all closings/dismissals
10563 /**
10564 * @param {DismissReason} dismiss
10565 */
10566 const dismissWith = dismiss => {
10567 instance.close({
10568 isDismissed: true,
10569 dismiss,
10570 isConfirmed: false,
10571 isDenied: false
10572 });
10573 };
10574 privateMethods.swalPromiseResolve.set(instance, resolve);
10575 privateMethods.swalPromiseReject.set(instance, reject);
10576 domCache.confirmButton.onclick = () => {
10577 handleConfirmButtonClick(instance);
10578 };
10579 domCache.denyButton.onclick = () => {
10580 handleDenyButtonClick(instance);
10581 };
10582 domCache.cancelButton.onclick = () => {
10583 handleCancelButtonClick(instance, dismissWith);
10584 };
10585 domCache.closeButton.onclick = () => {
10586 dismissWith(DismissReason.close);
10587 };
10588 handlePopupClick(innerParams, domCache, dismissWith);
10589 addKeydownHandler(globalState, innerParams, dismissWith);
10590 handleInputOptionsAndValue(instance, innerParams);
10591 openPopup(innerParams);
10592 setupTimer(globalState, innerParams, dismissWith);
10593 initFocus(domCache, innerParams);
10594
10595 // Scroll container to top on open (#1247, #1946)
10596 setTimeout(() => {
10597 domCache.container.scrollTop = 0;
10598 });
10599 });
10600 };
10601
10602 /**
10603 * @param {SweetAlertOptions} userParams
10604 * @param {SweetAlertOptions} mixinParams
10605 * @returns {SweetAlertOptions}
10606 */
10607 const prepareParams = (userParams, mixinParams) => {
10608 const templateParams = getTemplateParams(userParams);
10609 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10610 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10611 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10612 if (params.animation === false) {
10613 params.showClass = {
10614 backdrop: 'swal2-noanimation'
10615 };
10616 params.hideClass = {};
10617 }
10618 return params;
10619 };
10620
10621 /**
10622 * @param {SweetAlert} instance
10623 * @returns {DomCache}
10624 */
10625 const populateDomCache = instance => {
10626 const domCache = /** @type {DomCache} */{
10627 popup: (/** @type {HTMLElement} */getPopup()),
10628 container: (/** @type {HTMLElement} */getContainer()),
10629 actions: (/** @type {HTMLElement} */getActions()),
10630 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10631 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10632 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10633 loader: (/** @type {HTMLElement} */getLoader()),
10634 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10635 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10636 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10637 };
10638 privateProps.domCache.set(instance, domCache);
10639 return domCache;
10640 };
10641
10642 /**
10643 * @param {GlobalState} globalState
10644 * @param {SweetAlertOptions} innerParams
10645 * @param {(dismiss: DismissReason) => void} dismissWith
10646 */
10647 const setupTimer = (globalState, innerParams, dismissWith) => {
10648 const timerProgressBar = getTimerProgressBar();
10649 hide(timerProgressBar);
10650 if (innerParams.timer) {
10651 globalState.timeout = new Timer(() => {
10652 dismissWith('timer');
10653 delete globalState.timeout;
10654 }, innerParams.timer);
10655 if (innerParams.timerProgressBar && timerProgressBar) {
10656 show(timerProgressBar);
10657 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10658 setTimeout(() => {
10659 if (globalState.timeout && globalState.timeout.running) {
10660 // timer can be already stopped or unset at this point
10661 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10662 }
10663 });
10664 }
10665 }
10666 };
10667
10668 /**
10669 * Initialize focus in the popup:
10670 *
10671 * 1. If `toast` is `true`, don't steal focus from the document.
10672 * 2. Else if there is an [autofocus] element, focus it.
10673 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10674 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10675 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10676 * 6. Else focus the first focusable element in a popup (if any).
10677 *
10678 * @param {DomCache} domCache
10679 * @param {SweetAlertOptions} innerParams
10680 */
10681 const initFocus = (domCache, innerParams) => {
10682 if (innerParams.toast) {
10683 return;
10684 }
10685 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10686 if (!callIfFunction(innerParams.allowEnterKey)) {
10687 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
10688 domCache.popup.focus();
10689 return;
10690 }
10691 if (focusAutofocus(domCache)) {
10692 return;
10693 }
10694 if (focusButton(domCache, innerParams)) {
10695 return;
10696 }
10697 setFocus(-1, 1);
10698 };
10699
10700 /**
10701 * @param {DomCache} domCache
10702 * @returns {boolean}
10703 */
10704 const focusAutofocus = domCache => {
10705 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10706 for (const autofocusElement of autofocusElements) {
10707 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10708 autofocusElement.focus();
10709 return true;
10710 }
10711 }
10712 return false;
10713 };
10714
10715 /**
10716 * @param {DomCache} domCache
10717 * @param {SweetAlertOptions} innerParams
10718 * @returns {boolean}
10719 */
10720 const focusButton = (domCache, innerParams) => {
10721 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10722 domCache.denyButton.focus();
10723 return true;
10724 }
10725 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10726 domCache.cancelButton.focus();
10727 return true;
10728 }
10729 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10730 domCache.confirmButton.focus();
10731 return true;
10732 }
10733 return false;
10734 };
10735
10736 // Assign instance methods from src/instanceMethods/*.js to prototype
10737 SweetAlert.prototype.disableButtons = disableButtons;
10738 SweetAlert.prototype.enableButtons = enableButtons;
10739 SweetAlert.prototype.getInput = getInput;
10740 SweetAlert.prototype.disableInput = disableInput;
10741 SweetAlert.prototype.enableInput = enableInput;
10742 SweetAlert.prototype.hideLoading = hideLoading;
10743 SweetAlert.prototype.disableLoading = hideLoading;
10744 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10745 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10746 SweetAlert.prototype.close = close;
10747 SweetAlert.prototype.closePopup = close;
10748 SweetAlert.prototype.closeModal = close;
10749 SweetAlert.prototype.closeToast = close;
10750 SweetAlert.prototype.rejectPromise = rejectPromise;
10751 SweetAlert.prototype.update = update;
10752 SweetAlert.prototype._destroy = _destroy;
10753
10754 // Assign static methods from src/staticMethods/*.js to constructor
10755 Object.assign(SweetAlert, staticMethods);
10756
10757 // Proxy to instance methods to constructor, for now, for backwards compatibility
10758 Object.keys(instanceMethods).forEach(key => {
10759 /**
10760 * @param {...(SweetAlertOptions | string | undefined)} args
10761 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10762 */
10763 // @ts-ignore: Dynamic property assignment for backwards compatibility
10764 SweetAlert[key] = function (...args) {
10765 // @ts-ignore
10766 if (currentInstance && currentInstance[key]) {
10767 // @ts-ignore
10768 return currentInstance[key](...args);
10769 }
10770 return undefined;
10771 };
10772 });
10773 SweetAlert.DismissReason = DismissReason;
10774 SweetAlert.version = '11.26.25';
10775
10776 const Swal = SweetAlert;
10777 // @ts-ignore
10778 Swal.default = Swal;
10779
10780 return Swal;
10781
10782 }));
10783 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10784 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:auto}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:auto}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
10785
10786 /***/ },
10787
10788 /***/ "./node_modules/toastify-js/src/toastify.js"
10789 /*!**************************************************!*\
10790 !*** ./node_modules/toastify-js/src/toastify.js ***!
10791 \**************************************************/
10792 (module) {
10793
10794 /*!
10795 * Toastify js 1.12.0
10796 * https://github.com/apvarun/toastify-js
10797 * @license MIT licensed
10798 *
10799 * Copyright (C) 2018 Varun A P
10800 */
10801 (function(root, factory) {
10802 if ( true && module.exports) {
10803 module.exports = factory();
10804 } else {
10805 root.Toastify = factory();
10806 }
10807 })(this, function(global) {
10808 // Object initialization
10809 var Toastify = function(options) {
10810 // Returning a new init object
10811 return new Toastify.lib.init(options);
10812 },
10813 // Library version
10814 version = "1.12.0";
10815
10816 // Set the default global options
10817 Toastify.defaults = {
10818 oldestFirst: true,
10819 text: "Toastify is awesome!",
10820 node: undefined,
10821 duration: 3000,
10822 selector: undefined,
10823 callback: function () {
10824 },
10825 destination: undefined,
10826 newWindow: false,
10827 close: false,
10828 gravity: "toastify-top",
10829 positionLeft: false,
10830 position: '',
10831 backgroundColor: '',
10832 avatar: "",
10833 className: "",
10834 stopOnFocus: true,
10835 onClick: function () {
10836 },
10837 offset: {x: 0, y: 0},
10838 escapeMarkup: true,
10839 ariaLive: 'polite',
10840 style: {background: ''}
10841 };
10842
10843 // Defining the prototype of the object
10844 Toastify.lib = Toastify.prototype = {
10845 toastify: version,
10846
10847 constructor: Toastify,
10848
10849 // Initializing the object with required parameters
10850 init: function(options) {
10851 // Verifying and validating the input object
10852 if (!options) {
10853 options = {};
10854 }
10855
10856 // Creating the options object
10857 this.options = {};
10858
10859 this.toastElement = null;
10860
10861 // Validating the options
10862 this.options.text = options.text || Toastify.defaults.text; // Display message
10863 this.options.node = options.node || Toastify.defaults.node; // Display content as node
10864 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
10865 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
10866 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
10867 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
10868 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
10869 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
10870 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
10871 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
10872 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
10873 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
10874 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
10875 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
10876 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
10877 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
10878 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
10879 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
10880 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
10881 this.options.style = options.style || Toastify.defaults.style;
10882 if(options.backgroundColor) {
10883 this.options.style.background = options.backgroundColor;
10884 }
10885
10886 // Returning the current object for chaining functions
10887 return this;
10888 },
10889
10890 // Building the DOM element
10891 buildToast: function() {
10892 // Validating if the options are defined
10893 if (!this.options) {
10894 throw "Toastify is not initialized";
10895 }
10896
10897 // Creating the DOM object
10898 var divElement = document.createElement("div");
10899 divElement.className = "toastify on " + this.options.className;
10900
10901 // Positioning toast to left or right or center
10902 if (!!this.options.position) {
10903 divElement.className += " toastify-" + this.options.position;
10904 } else {
10905 // To be depreciated in further versions
10906 if (this.options.positionLeft === true) {
10907 divElement.className += " toastify-left";
10908 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
10909 } else {
10910 // Default position
10911 divElement.className += " toastify-right";
10912 }
10913 }
10914
10915 // Assigning gravity of element
10916 divElement.className += " " + this.options.gravity;
10917
10918 if (this.options.backgroundColor) {
10919 // This is being deprecated in favor of using the style HTML DOM property
10920 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
10921 }
10922
10923 // Loop through our style object and apply styles to divElement
10924 for (var property in this.options.style) {
10925 divElement.style[property] = this.options.style[property];
10926 }
10927
10928 // Announce the toast to screen readers
10929 if (this.options.ariaLive) {
10930 divElement.setAttribute('aria-live', this.options.ariaLive)
10931 }
10932
10933 // Adding the toast message/node
10934 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
10935 // If we have a valid node, we insert it
10936 divElement.appendChild(this.options.node)
10937 } else {
10938 if (this.options.escapeMarkup) {
10939 divElement.innerText = this.options.text;
10940 } else {
10941 divElement.innerHTML = this.options.text;
10942 }
10943
10944 if (this.options.avatar !== "") {
10945 var avatarElement = document.createElement("img");
10946 avatarElement.src = this.options.avatar;
10947
10948 avatarElement.className = "toastify-avatar";
10949
10950 if (this.options.position == "left" || this.options.positionLeft === true) {
10951 // Adding close icon on the left of content
10952 divElement.appendChild(avatarElement);
10953 } else {
10954 // Adding close icon on the right of content
10955 divElement.insertAdjacentElement("afterbegin", avatarElement);
10956 }
10957 }
10958 }
10959
10960 // Adding a close icon to the toast
10961 if (this.options.close === true) {
10962 // Create a span for close element
10963 var closeElement = document.createElement("button");
10964 closeElement.type = "button";
10965 closeElement.setAttribute("aria-label", "Close");
10966 closeElement.className = "toast-close";
10967 closeElement.innerHTML = "&#10006;";
10968
10969 // Triggering the removal of toast from DOM on close click
10970 closeElement.addEventListener(
10971 "click",
10972 function(event) {
10973 event.stopPropagation();
10974 this.removeElement(this.toastElement);
10975 window.clearTimeout(this.toastElement.timeOutValue);
10976 }.bind(this)
10977 );
10978
10979 //Calculating screen width
10980 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
10981
10982 // Adding the close icon to the toast element
10983 // Display on the right if screen width is less than or equal to 360px
10984 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
10985 // Adding close icon on the left of content
10986 divElement.insertAdjacentElement("afterbegin", closeElement);
10987 } else {
10988 // Adding close icon on the right of content
10989 divElement.appendChild(closeElement);
10990 }
10991 }
10992
10993 // Clear timeout while toast is focused
10994 if (this.options.stopOnFocus && this.options.duration > 0) {
10995 var self = this;
10996 // stop countdown
10997 divElement.addEventListener(
10998 "mouseover",
10999 function(event) {
11000 window.clearTimeout(divElement.timeOutValue);
11001 }
11002 )
11003 // add back the timeout
11004 divElement.addEventListener(
11005 "mouseleave",
11006 function() {
11007 divElement.timeOutValue = window.setTimeout(
11008 function() {
11009 // Remove the toast from DOM
11010 self.removeElement(divElement);
11011 },
11012 self.options.duration
11013 )
11014 }
11015 )
11016 }
11017
11018 // Adding an on-click destination path
11019 if (typeof this.options.destination !== "undefined") {
11020 divElement.addEventListener(
11021 "click",
11022 function(event) {
11023 event.stopPropagation();
11024 if (this.options.newWindow === true) {
11025 window.open(this.options.destination, "_blank");
11026 } else {
11027 window.location = this.options.destination;
11028 }
11029 }.bind(this)
11030 );
11031 }
11032
11033 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11034 divElement.addEventListener(
11035 "click",
11036 function(event) {
11037 event.stopPropagation();
11038 this.options.onClick();
11039 }.bind(this)
11040 );
11041 }
11042
11043 // Adding offset
11044 if(typeof this.options.offset === "object") {
11045
11046 var x = getAxisOffsetAValue("x", this.options);
11047 var y = getAxisOffsetAValue("y", this.options);
11048
11049 var xOffset = this.options.position == "left" ? x : "-" + x;
11050 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11051
11052 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11053
11054 }
11055
11056 // Returning the generated element
11057 return divElement;
11058 },
11059
11060 // Displaying the toast
11061 showToast: function() {
11062 // Creating the DOM object for the toast
11063 this.toastElement = this.buildToast();
11064
11065 // Getting the root element to with the toast needs to be added
11066 var rootElement;
11067 if (typeof this.options.selector === "string") {
11068 rootElement = document.getElementById(this.options.selector);
11069 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11070 rootElement = this.options.selector;
11071 } else {
11072 rootElement = document.body;
11073 }
11074
11075 // Validating if root element is present in DOM
11076 if (!rootElement) {
11077 throw "Root element is not defined";
11078 }
11079
11080 // Adding the DOM element
11081 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11082 rootElement.insertBefore(this.toastElement, elementToInsert);
11083
11084 // Repositioning the toasts in case multiple toasts are present
11085 Toastify.reposition();
11086
11087 if (this.options.duration > 0) {
11088 this.toastElement.timeOutValue = window.setTimeout(
11089 function() {
11090 // Remove the toast from DOM
11091 this.removeElement(this.toastElement);
11092 }.bind(this),
11093 this.options.duration
11094 ); // Binding `this` for function invocation
11095 }
11096
11097 // Supporting function chaining
11098 return this;
11099 },
11100
11101 hideToast: function() {
11102 if (this.toastElement.timeOutValue) {
11103 clearTimeout(this.toastElement.timeOutValue);
11104 }
11105 this.removeElement(this.toastElement);
11106 },
11107
11108 // Removing the element from the DOM
11109 removeElement: function(toastElement) {
11110 // Hiding the element
11111 // toastElement.classList.remove("on");
11112 toastElement.className = toastElement.className.replace(" on", "");
11113
11114 // Removing the element from DOM after transition end
11115 window.setTimeout(
11116 function() {
11117 // remove options node if any
11118 if (this.options.node && this.options.node.parentNode) {
11119 this.options.node.parentNode.removeChild(this.options.node);
11120 }
11121
11122 // Remove the element from the DOM, only when the parent node was not removed before.
11123 if (toastElement.parentNode) {
11124 toastElement.parentNode.removeChild(toastElement);
11125 }
11126
11127 // Calling the callback function
11128 this.options.callback.call(toastElement);
11129
11130 // Repositioning the toasts again
11131 Toastify.reposition();
11132 }.bind(this),
11133 400
11134 ); // Binding `this` for function invocation
11135 },
11136 };
11137
11138 // Positioning the toasts on the DOM
11139 Toastify.reposition = function() {
11140
11141 // Top margins with gravity
11142 var topLeftOffsetSize = {
11143 top: 15,
11144 bottom: 15,
11145 };
11146 var topRightOffsetSize = {
11147 top: 15,
11148 bottom: 15,
11149 };
11150 var offsetSize = {
11151 top: 15,
11152 bottom: 15,
11153 };
11154
11155 // Get all toast messages on the DOM
11156 var allToasts = document.getElementsByClassName("toastify");
11157
11158 var classUsed;
11159
11160 // Modifying the position of each toast element
11161 for (var i = 0; i < allToasts.length; i++) {
11162 // Getting the applied gravity
11163 if (containsClass(allToasts[i], "toastify-top") === true) {
11164 classUsed = "toastify-top";
11165 } else {
11166 classUsed = "toastify-bottom";
11167 }
11168
11169 var height = allToasts[i].offsetHeight;
11170 classUsed = classUsed.substr(9, classUsed.length-1)
11171 // Spacing between toasts
11172 var offset = 15;
11173
11174 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11175
11176 // Show toast in center if screen with less than or equal to 360px
11177 if (width <= 360) {
11178 // Setting the position
11179 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11180
11181 offsetSize[classUsed] += height + offset;
11182 } else {
11183 if (containsClass(allToasts[i], "toastify-left") === true) {
11184 // Setting the position
11185 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11186
11187 topLeftOffsetSize[classUsed] += height + offset;
11188 } else {
11189 // Setting the position
11190 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11191
11192 topRightOffsetSize[classUsed] += height + offset;
11193 }
11194 }
11195 }
11196
11197 // Supporting function chaining
11198 return this;
11199 };
11200
11201 // Helper function to get offset.
11202 function getAxisOffsetAValue(axis, options) {
11203
11204 if(options.offset[axis]) {
11205 if(isNaN(options.offset[axis])) {
11206 return options.offset[axis];
11207 }
11208 else {
11209 return options.offset[axis] + 'px';
11210 }
11211 }
11212
11213 return '0px';
11214
11215 }
11216
11217 function containsClass(elem, yourClass) {
11218 if (!elem || typeof yourClass !== "string") {
11219 return false;
11220 } else if (
11221 elem.className &&
11222 elem.className
11223 .trim()
11224 .split(/\s+/gi)
11225 .indexOf(yourClass) > -1
11226 ) {
11227 return true;
11228 } else {
11229 return false;
11230 }
11231 }
11232
11233 // Setting up the prototype for the init object
11234 Toastify.lib.init.prototype = Toastify.lib;
11235
11236 // Returning the Toastify function to be assigned to the window object/module
11237 return Toastify;
11238 });
11239
11240
11241 /***/ }
11242
11243 /******/ });
11244 /************************************************************************/
11245 /******/ // The module cache
11246 /******/ const __webpack_module_cache__ = {};
11247 /******/
11248 /******/ // The require function
11249 /******/ function __webpack_require__(moduleId) {
11250 /******/ // Check if module is in cache
11251 /******/ const cachedModule = __webpack_module_cache__[moduleId];
11252 /******/ if (cachedModule !== undefined) {
11253 /******/ return cachedModule.exports;
11254 /******/ }
11255 /******/ // Create a new module (and put it into the cache)
11256 /******/ const module = __webpack_module_cache__[moduleId] = {
11257 /******/ id: moduleId,
11258 /******/ // no module.loaded needed
11259 /******/ exports: {}
11260 /******/ };
11261 /******/
11262 /******/ // Execute the module function
11263 /******/ if (!(moduleId in __webpack_modules__)) {
11264 /******/ delete __webpack_module_cache__[moduleId];
11265 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
11266 /******/ e.code = 'MODULE_NOT_FOUND';
11267 /******/ throw e;
11268 /******/ }
11269 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11270 /******/
11271 /******/ // Return the exports of the module
11272 /******/ return module.exports;
11273 /******/ }
11274 /******/
11275 /************************************************************************/
11276 /******/ /* webpack/runtime/compat get default export */
11277 /******/ (() => {
11278 /******/ // getDefaultExport function for compatibility with non-harmony modules
11279 /******/ __webpack_require__.n = (module) => {
11280 /******/ const getter = module && module.__esModule ?
11281 /******/ () => (module['default']) :
11282 /******/ () => (module);
11283 /******/ __webpack_require__.d(getter, { a: getter });
11284 /******/ return getter;
11285 /******/ };
11286 /******/ })();
11287 /******/
11288 /******/ /* webpack/runtime/define property getters */
11289 /******/ (() => {
11290 /******/ // define getter/value functions for harmony exports
11291 /******/ __webpack_require__.d = (exports, definition) => {
11292 /******/ if(Array.isArray(definition)) {
11293 /******/ var i = 0;
11294 /******/ while(i < definition.length) {
11295 /******/ var key = definition[i++];
11296 /******/ var binding = definition[i++];
11297 /******/ if(!__webpack_require__.o(exports, key)) {
11298 /******/ if(binding === 0) {
11299 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
11300 /******/ } else {
11301 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
11302 /******/ }
11303 /******/ } else if(binding === 0) { i++; }
11304 /******/ }
11305 /******/ } else {
11306 /******/ for(var key in definition) {
11307 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11308 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11309 /******/ }
11310 /******/ }
11311 /******/ }
11312 /******/ };
11313 /******/ })();
11314 /******/
11315 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11316 /******/ (() => {
11317 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
11318 /******/ })();
11319 /******/
11320 /******/ /* webpack/runtime/make namespace object */
11321 /******/ (() => {
11322 /******/ // define __esModule on exports
11323 /******/ __webpack_require__.r = (exports) => {
11324 /******/ if(Symbol.toStringTag) {
11325 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11326 /******/ }
11327 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11328 /******/ };
11329 /******/ })();
11330 /******/
11331 /******/ /* webpack/runtime/nonce */
11332 /******/ (() => {
11333 /******/ __webpack_require__.nc = undefined;
11334 /******/ })();
11335 /******/
11336 /************************************************************************/
11337 let __webpack_exports__ = {};
11338 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11339 (() => {
11340 "use strict";
11341 /*!******************************************!*\
11342 !*** ./assets/src/js/admin/edit-quiz.js ***!
11343 \******************************************/
11344 __webpack_require__.r(__webpack_exports__);
11345 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
11346 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
11347 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
11348 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
11349 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
11350 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
11351 /* harmony import */ var _edit_question_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-question.js */ "./assets/src/js/admin/edit-question.js");
11352 /* harmony import */ var lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lpAssetsJsPath/lpPopupSelectItemToAdd.js */ "./assets/src/js/lpPopupSelectItemToAdd.js");
11353 /**
11354 * Edit Quiz JS handler as a class.
11355 *
11356 * @since 4.2.8.6
11357 * @version 1.0.3
11358 */
11359
11360
11361
11362
11363
11364
11365
11366 let editQuestion;
11367 const lpPopupSelectItemToAdd = new lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd();
11368 lpPopupSelectItemToAdd.init();
11369 class EditQuiz {
11370 constructor() {
11371 this.idUrlHandle = 'edit-quiz-questions';
11372 this.elEditQuizWrap = null;
11373 this.elEditListQuestions = null;
11374 this.quizID = null;
11375 }
11376 static selectors = {
11377 elEditQuizWrap: '.lp-edit-quiz-wrap',
11378 elQuestionEditMain: '.lp-question-edit-main',
11379 elQuestionToggleAll: '.lp-question-toggle-all',
11380 elEditListQuestions: '.lp-edit-list-questions',
11381 elQuestionItem: '.lp-question-item',
11382 elQuestionToggle: '.lp-question-toggle',
11383 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
11384 elBtnAddQuestion: '.lp-btn-add-question',
11385 elBtnRemoveQuestion: '.lp-btn-remove-question',
11386 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
11387 elBtnCancelUpdateQuestionTitle: '.lp-btn-cancel-update-question-title',
11388 elQuestionTitleNewInput: '.lp-question-title-new-input',
11389 elQuestionTitleInput: '.lp-question-title-input',
11390 elQuestionTypeLabel: '.lp-question-type-label',
11391 elQuestionTypeNew: '.lp-question-type-new',
11392 elAddNewQuestion: 'add-new-question',
11393 elQuestionClone: '.lp-question-item.clone',
11394 LPTarget: '.lp-target',
11395 elCollapse: 'lp-collapse'
11396 };
11397 init() {
11398 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuiz.selectors.elEditQuizWrap, elEditQuizWrapFound => {
11399 this.elEditQuizWrap = elEditQuizWrapFound;
11400 this.elEditListQuestions = this.elEditQuizWrap.querySelector(EditQuiz.selectors.elEditListQuestions);
11401 const elLPTarget = this.elEditQuizWrap.closest(EditQuiz.selectors.LPTarget);
11402 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
11403 this.quizID = dataSend.args.quiz_id;
11404 this.sortAbleQuestion();
11405 editQuestion = new _edit_question_js__WEBPACK_IMPORTED_MODULE_5__.EditQuestion();
11406 editQuestion.init();
11407 const elQuestionEditMains = elEditQuizWrapFound.querySelectorAll(`${EditQuiz.selectors.elQuestionEditMain}`);
11408 elQuestionEditMains.forEach(elQuestionEditMain => {
11409 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11410 });
11411 this.events();
11412 });
11413 }
11414 events() {
11415 if (EditQuiz._loadedEvents) {
11416 return;
11417 }
11418 EditQuiz._loadedEvents = true;
11419 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
11420 selector: EditQuiz.selectors.elQuestionToggleAll,
11421 class: this,
11422 callBack: this.toggleQuestionAll.name
11423 }, {
11424 selector: EditQuiz.selectors.elBtnAddQuestion,
11425 class: this,
11426 callBack: this.addQuestion.name
11427 }, {
11428 selector: EditQuiz.selectors.elBtnRemoveQuestion,
11429 class: this,
11430 callBack: this.removeQuestion.name
11431 }, {
11432 selector: EditQuiz.selectors.elBtnUpdateQuestionTitle,
11433 class: this,
11434 callBack: this.updateQuestionTitle.name
11435 }, {
11436 selector: EditQuiz.selectors.elBtnCancelUpdateQuestionTitle,
11437 class: this,
11438 callBack: this.cancelChangeTitleQuestion.name
11439 }, {
11440 selector: lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
11441 class: lpPopupSelectItemToAdd,
11442 callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
11443 callBackHandle: this.addQuestionsSelectedToQuiz.bind(this)
11444 }]);
11445
11446 // Keydown
11447 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
11448 selector: EditQuiz.selectors.elQuestionTitleInput,
11449 class: this,
11450 callBack: this.updateQuestionTitle.name,
11451 checkIsEventEnter: true
11452 }, {
11453 selector: EditQuiz.selectors.elQuestionTitleNewInput,
11454 class: this,
11455 callBack: this.addQuestion.name,
11456 checkIsEventEnter: true
11457 }]);
11458
11459 // Keyup
11460 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
11461 selector: EditQuiz.selectors.elQuestionTitleInput,
11462 class: this,
11463 callBack: this.changeTitleQuestion.name
11464 }, {
11465 selector: `${EditQuiz.selectors.elQuestionTitleNewInput}, ${EditQuiz.selectors.elQuestionTypeNew}`,
11466 class: this,
11467 callBack: this.checkCanAddQuestion.name
11468 }]);
11469
11470 // Change
11471 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
11472 selector: EditQuiz.selectors.elQuestionTypeNew,
11473 class: this,
11474 callBack: this.checkCanAddQuestion.name
11475 }]);
11476
11477 // Click
11478 document.addEventListener('click', e => {
11479 const target = e.target;
11480 _utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuiz.selectors.elQuestionToggle, [], () => this.checkAllQuestionsCollapsed());
11481 });
11482 }
11483
11484 // Toggle all questions
11485 toggleQuestionAll(args) {
11486 const {
11487 e,
11488 target
11489 } = args;
11490 const elQuestionToggleAll = target.closest(`${EditQuiz.selectors.elQuestionToggleAll}`);
11491 if (!elQuestionToggleAll) {
11492 return;
11493 }
11494 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11495 elQuestionToggleAll.classList.toggle(`${EditQuiz.selectors.elCollapse}`);
11496 elQuestionItems.forEach(el => {
11497 const shouldCollapse = elQuestionToggleAll.classList.contains(`${EditQuiz.selectors.elCollapse}`);
11498 el.classList.toggle(`${EditQuiz.selectors.elCollapse}`, shouldCollapse);
11499 });
11500 }
11501 checkAllQuestionsCollapsed() {
11502 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11503 const elQuestionToggleAll = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionToggleAll}`);
11504 let isAllExpand = true;
11505 elQuestionItems.forEach(el => {
11506 if (el.classList.contains(`${EditQuiz.selectors.elCollapse}`)) {
11507 isAllExpand = false;
11508 return false; // Break
11509 }
11510 });
11511 if (isAllExpand) {
11512 elQuestionToggleAll.classList.remove(`${EditQuiz.selectors.elCollapse}`);
11513 } else {
11514 elQuestionToggleAll.classList.add(`${EditQuiz.selectors.elCollapse}`);
11515 }
11516 }
11517 updateCountItems() {
11518 const elCountItemsAll = this.elEditQuizWrap.querySelector('.total-items');
11519 const elItemsAll = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11520 const itemsAllCount = elItemsAll.length;
11521 elCountItemsAll.dataset.count = itemsAllCount;
11522 elCountItemsAll.querySelector('.count').textContent = itemsAllCount;
11523 }
11524
11525 // Add question to quiz
11526 addQuestion(args) {
11527 const {
11528 e,
11529 target,
11530 callBackNest
11531 } = args;
11532 e.preventDefault();
11533 const elAddNewQuestion = target.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11534 if (!elAddNewQuestion) {
11535 return;
11536 }
11537 const elQuestionTitleNewInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11538 const questionTitle = elQuestionTitleNewInput.value.trim();
11539 if (!questionTitle) {
11540 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionTitleNewInput.dataset.messEmptyTitle, 'error');
11541 return;
11542 }
11543 const elQuestionType = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11544 const questionType = elQuestionType.value;
11545 if (!questionType) {
11546 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionType.dataset.messEmptyType, 'error');
11547 return;
11548 }
11549 const elQuestionClone = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11550 const newQuestionItem = elQuestionClone.cloneNode(true);
11551 const elQuestionTitleInput = newQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11552 elQuestionTitleInput.value = questionTitle;
11553 elQuestionTitleNewInput.value = '';
11554 newQuestionItem.classList.remove('clone');
11555 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(newQuestionItem, 1);
11556 elQuestionClone.insertAdjacentElement('beforebegin', newQuestionItem);
11557 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 1);
11558 const callBack = {
11559 success: response => {
11560 const {
11561 message,
11562 status,
11563 data
11564 } = response;
11565 const {
11566 question,
11567 html_edit_question
11568 } = data;
11569 if (status === 'error') {
11570 throw `Error: ${message}`;
11571 } else if (status === 'success') {
11572 newQuestionItem.dataset.questionId = question.ID;
11573 newQuestionItem.dataset.questionType = question.meta_data._lp_type;
11574 newQuestionItem.outerHTML = html_edit_question;
11575 const elQuestionItemCreated = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question.ID}"]`);
11576 elQuestionItemCreated.classList.remove(EditQuiz.selectors.elCollapse);
11577 this.updateCountItems();
11578 editQuestion.initTinyMCE();
11579 const elQuestionEditMain = elQuestionItemCreated.querySelector(`${EditQuiz.selectors.elQuestionEditMain}`);
11580 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11581
11582 // Callback nest
11583 if (callBackNest && typeof callBackNest.success === 'function') {
11584 callBackNest.success({
11585 response,
11586 elQuestionItemCreated
11587 });
11588 }
11589 }
11590 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11591 },
11592 error: error => {
11593 newQuestionItem.remove();
11594 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11595 if (callBackNest && typeof callBackNest.error === 'function') {
11596 callBackNest.error({
11597 error,
11598 newQuestionItem
11599 });
11600 }
11601 },
11602 completed: () => {
11603 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 0);
11604 this.checkCanAddQuestion({
11605 e,
11606 target: elQuestionTitleNewInput
11607 });
11608 if (callBackNest && typeof callBackNest.completed === 'function') {
11609 callBackNest.completed({
11610 newQuestionItem
11611 });
11612 }
11613 }
11614 };
11615 let dataSend = JSON.parse(elQuestionTitleNewInput.dataset.send);
11616 dataSend = {
11617 ...dataSend,
11618 question_title: questionTitle,
11619 question_type: questionType
11620 };
11621 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11622 }
11623
11624 // Add questions selected from popup to quiz
11625 addQuestionsSelectedToQuiz(itemsSelected) {
11626 const questionIds = [];
11627 itemsSelected.forEach(item => {
11628 const elQuestionItemClone = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11629 if (!elQuestionItemClone) {
11630 return;
11631 }
11632 questionIds.push(item.id);
11633 const elQuestionItemNew = elQuestionItemClone.cloneNode(true);
11634 const elQuestionItemTitleInput = elQuestionItemNew.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11635 elQuestionItemNew.classList.remove('clone');
11636 elQuestionItemNew.dataset.questionId = item.id;
11637 elQuestionItemTitleInput.value = item.titleSelected;
11638 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11639 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionItemNew, 1);
11640 elQuestionItemClone.insertAdjacentElement('beforebegin', elQuestionItemNew);
11641 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11642 });
11643 const callBack = {
11644 success: response => {
11645 const {
11646 message,
11647 status,
11648 data
11649 } = response;
11650 if (status === 'success') {
11651 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11652 const {
11653 html_edit_question
11654 } = data;
11655 if (html_edit_question) {
11656 Object.entries(html_edit_question).forEach(([question_id, item_html]) => {
11657 const elQuestionItemNew = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question_id}"]`);
11658 elQuestionItemNew.outerHTML = item_html;
11659 });
11660 }
11661 this.updateCountItems();
11662 editQuestion.initTinyMCE();
11663 } else {
11664 throw `Error: ${message}`;
11665 }
11666 },
11667 error: error => {
11668 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11669 },
11670 completed: () => {
11671 // completed handler intentionally empty
11672 }
11673 };
11674 const dataSend = {
11675 action: 'add_questions_to_quiz',
11676 quiz_id: this.quizID,
11677 question_ids: questionIds,
11678 args: {
11679 id_url: this.idUrlHandle
11680 }
11681 };
11682 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11683 }
11684 checkCanAddQuestion(args) {
11685 const {
11686 e,
11687 target
11688 } = args;
11689 const elTrigger = target.closest(EditQuiz.selectors.elQuestionTitleNewInput) || target.closest(EditQuiz.selectors.elQuestionTypeNew);
11690 if (!elTrigger) {
11691 return;
11692 }
11693 const elAddNewQuestion = elTrigger.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11694 if (!elAddNewQuestion) {
11695 return;
11696 }
11697 const elBtnAddQuestion = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elBtnAddQuestion}`);
11698 if (!elBtnAddQuestion) {
11699 return;
11700 }
11701 const elQuestionTitleInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11702 const elQuestionTypeNew = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11703 const questionTitle = elQuestionTitleInput.value.trim();
11704 const questionType = elQuestionTypeNew.value;
11705 if (questionTitle && questionType) {
11706 elBtnAddQuestion.classList.add('active');
11707 } else {
11708 elBtnAddQuestion.classList.remove('active');
11709 }
11710 }
11711 removeQuestion(args) {
11712 const {
11713 e,
11714 target
11715 } = args;
11716 const elBtnRemoveQuestion = target.closest(`${EditQuiz.selectors.elBtnRemoveQuestion}`);
11717 if (!elBtnRemoveQuestion) {
11718 return;
11719 }
11720 const elQuestionItem = elBtnRemoveQuestion.closest(`${EditQuiz.selectors.elQuestionItem}`);
11721 if (!elQuestionItem) {
11722 return;
11723 }
11724 const questionId = elQuestionItem.dataset.questionId;
11725 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
11726 title: elBtnRemoveQuestion.dataset.title,
11727 text: elBtnRemoveQuestion.dataset.content,
11728 icon: 'warning',
11729 showCloseButton: true,
11730 showCancelButton: true,
11731 cancelButtonText: lpDataAdmin.i18n.cancel,
11732 confirmButtonText: lpDataAdmin.i18n.yes,
11733 reverseButtons: true
11734 }).then(result => {
11735 if (result.isConfirmed) {
11736 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11737 const callBack = {
11738 success: response => {
11739 const {
11740 message,
11741 status
11742 } = response;
11743 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11744 if (status === 'success') {
11745 elQuestionItem.remove();
11746 this.updateCountItems();
11747 }
11748 },
11749 error: error => {
11750 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11751 },
11752 completed: () => {
11753 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11754 }
11755 };
11756 const dataSend = {
11757 quiz_id: this.quizID,
11758 action: 'remove_question_from_quiz',
11759 question_id: questionId,
11760 args: {
11761 id_url: this.idUrlHandle
11762 }
11763 };
11764 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11765 }
11766 });
11767 }
11768 updateQuestionTitle(args) {
11769 const {
11770 e,
11771 target
11772 } = args;
11773 let canHandle = false;
11774 if (target.closest(`${EditQuiz.selectors.elBtnUpdateQuestionTitle}`)) {
11775 canHandle = true;
11776 } else if (target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`) && e.key === 'Enter') {
11777 canHandle = true;
11778 }
11779 if (!canHandle) {
11780 return;
11781 }
11782 e.preventDefault();
11783 const elQuestionItem = target.closest(`${EditQuiz.selectors.elQuestionItem}`);
11784 if (!elQuestionItem) {
11785 return;
11786 }
11787 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11788 if (!elQuestionTitleInput) {
11789 return;
11790 }
11791 const questionId = elQuestionItem.dataset.questionId;
11792 const questionTitleValue = elQuestionTitleInput.value.trim();
11793 const titleOld = elQuestionTitleInput.dataset.old;
11794 const message = elQuestionTitleInput.dataset.messEmptyTitle;
11795 if (questionTitleValue.length === 0) {
11796 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
11797 return;
11798 }
11799 if (questionTitleValue === titleOld) {
11800 return;
11801 }
11802 elQuestionTitleInput.blur();
11803 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11804 const callBack = {
11805 success: response => {
11806 const {
11807 message,
11808 status
11809 } = response;
11810 if (status === 'success') {
11811 elQuestionTitleInput.dataset.old = questionTitleValue;
11812 } else {
11813 elQuestionTitleInput.value = titleOld;
11814 }
11815 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11816 },
11817 error: error => {
11818 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11819 },
11820 completed: () => {
11821 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11822 elQuestionItem.classList.remove('editing');
11823 }
11824 };
11825 const dataSend = {
11826 quiz_id: this.quizID,
11827 action: 'update_question',
11828 question_id: questionId,
11829 question_title: questionTitleValue,
11830 args: {
11831 id_url: this.idUrlHandle
11832 }
11833 };
11834 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11835 }
11836 changeTitleQuestion(args) {
11837 const {
11838 e,
11839 target
11840 } = args;
11841 const elQuestionTitleInput = target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`);
11842 if (!elQuestionTitleInput) {
11843 return;
11844 }
11845 const elQuestionItem = elQuestionTitleInput.closest(`${EditQuiz.selectors.elQuestionItem}`);
11846 const titleValue = elQuestionTitleInput.value.trim();
11847 const titleValueOld = elQuestionTitleInput.dataset.old || '';
11848 if (titleValue === titleValueOld) {
11849 elQuestionItem.classList.remove('editing');
11850 } else {
11851 elQuestionItem.classList.add('editing');
11852 }
11853 }
11854 cancelChangeTitleQuestion(args) {
11855 const {
11856 e,
11857 target
11858 } = args;
11859 const elBtnCancelUpdateQuestionTitle = target.closest(`${EditQuiz.selectors.elBtnCancelUpdateQuestionTitle}`);
11860 if (!elBtnCancelUpdateQuestionTitle) {
11861 return;
11862 }
11863 const elQuestionItem = elBtnCancelUpdateQuestionTitle.closest(`${EditQuiz.selectors.elQuestionItem}`);
11864 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11865 elQuestionTitleInput.value = elQuestionTitleInput.dataset.old || '';
11866 elQuestionItem.classList.remove('editing');
11867 }
11868 sortAbleQuestion() {
11869 let isUpdateSectionPosition = 0;
11870 let timeout;
11871 new sortablejs__WEBPACK_IMPORTED_MODULE_2__["default"](this.elEditListQuestions, {
11872 handle: '.drag',
11873 animation: 150,
11874 onEnd: evt => {
11875 const elQuestionItem = evt.item;
11876 if (!isUpdateSectionPosition) {
11877 return;
11878 }
11879 clearTimeout(timeout);
11880 timeout = setTimeout(() => {
11881 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11882 const questionIds = [];
11883 const elQuestionItems = this.elEditListQuestions.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11884 elQuestionItems.forEach(elItem => {
11885 const questionId = elItem.dataset.questionId;
11886 if (questionId) {
11887 questionIds.push(questionId);
11888 }
11889 });
11890 const callBack = {
11891 success: response => {
11892 const {
11893 message,
11894 status
11895 } = response;
11896 if (status === 'success') {
11897 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11898 editQuestion.initTinyMCE();
11899 } else {
11900 throw `Error: ${message}`;
11901 }
11902 },
11903 error: error => {
11904 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11905 },
11906 completed: () => {
11907 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11908 isUpdateSectionPosition = 0;
11909 }
11910 };
11911 const dataSend = {
11912 quiz_id: this.quizID,
11913 action: 'update_questions_position',
11914 question_ids: questionIds,
11915 args: {
11916 id_url: this.idUrlHandle
11917 }
11918 };
11919 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11920 }, 1000);
11921 },
11922 onMove: () => {
11923 clearTimeout(timeout);
11924 },
11925 onUpdate: () => {
11926 isUpdateSectionPosition = 1;
11927 }
11928 });
11929 }
11930 }
11931 const editQuiz = new EditQuiz();
11932 editQuiz.init();
11933 })();
11934
11935 /******/ })()
11936 ;
11937 //# sourceMappingURL=edit-quiz.js.map