PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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 4.2.0 All 139 releases
learnpress / assets / js / dist / frontend / profile.js

profile.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at assets/js/dist/frontend/profile.js

11,581 lines 416.6 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/courses/view-students-modal.js"
5 /*!************************************************************!*\
6 !*** ./assets/src/js/admin/courses/view-students-modal.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 */ ViewStudentsModal: () => (/* binding */ ViewStudentsModal)
14 /* harmony export */ });
15 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
16 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
17 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
18
19
20 class ViewStudentsModal {
21 constructor() {
22 this.isRequesting = false;
23 this.activeCourseId = 0;
24 this.init();
25 }
26 static selectors = {
27 wrap: '#lp-modal-enrolled-wrap',
28 form: '#lp-modal-enrolled-form',
29 toolbarTemplate: '#lp-tmpl-enrolled-students-toolbar-modal',
30 targetTemplate: '#lp-tmpl-enrolled-students-target-modal',
31 toolbar: '.lp-enrolled-students-table-toolbar--modal',
32 courseTrigger: '.lp-btn-view-students',
33 searchInput: '#lp-modal-enrolled-search-input',
34 startDateInput: '#lp-modal-enrolled-filter-start-date',
35 endDateInput: '#lp-modal-enrolled-filter-end-date',
36 searchBtn: '.lp-enrolled-btn-search-modal',
37 clearBtn: '.lp-enrolled-btn-clear-modal',
38 modalSearchFields: '#lp-modal-enrolled-search-input, #lp-modal-enrolled-filter-start-date, #lp-modal-enrolled-filter-end-date'
39 };
40 setButtonLoadingState(btn, isLoading) {
41 if (!btn) {
42 return;
43 }
44 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(btn, isLoading ? 1 : 0);
45 }
46 init() {
47 if (ViewStudentsModal._loadedEvents) {
48 return;
49 }
50 ViewStudentsModal._loadedEvents = true;
51 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('click', [{
52 selector: ViewStudentsModal.selectors.courseTrigger,
53 class: this,
54 callBack: this.handleOpenModal.name
55 }, {
56 selector: ViewStudentsModal.selectors.searchBtn,
57 class: this,
58 callBack: this.handleModalSearch.name
59 }, {
60 selector: ViewStudentsModal.selectors.clearBtn,
61 class: this,
62 callBack: this.handleModalClear.name
63 }]);
64 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('keydown', [{
65 selector: ViewStudentsModal.selectors.modalSearchFields,
66 class: this,
67 callBack: this.handleModalSearchOnEnter.name,
68 checkIsEventEnter: true
69 }]);
70 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('change', [{
71 selector: ViewStudentsModal.selectors.startDateInput,
72 class: this,
73 callBack: this.checkDatesRange.name
74 }, {
75 selector: ViewStudentsModal.selectors.endDateInput,
76 class: this,
77 callBack: this.checkDatesRange.name
78 }]);
79 }
80 handleOpenModal(args) {
81 const btn = args?.target?.closest(ViewStudentsModal.selectors.courseTrigger);
82 if (!btn || this.isRequesting || btn.classList.contains('loading')) {
83 return;
84 }
85 const courseId = parseInt(btn.dataset.courseId, 10) || 0;
86 if (!courseId) {
87 return;
88 }
89 const courseTitle = btn.dataset.courseTitle || '';
90 this.activeCourseId = courseId;
91 this.setButtonLoadingState(btn, true);
92 this.openModal(courseId, courseTitle, btn);
93 }
94 handleModalSearch(args) {
95 const btn = args?.target?.closest(ViewStudentsModal.selectors.searchBtn);
96 if (!btn || !this.activeCourseId) {
97 return;
98 }
99 if (args?.e) {
100 args.e.preventDefault();
101 }
102 if (this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
103 return;
104 }
105 this.setButtonLoadingState(btn, true);
106 this.loadEnrolledStudents(this.activeCourseId, 1, btn);
107 }
108 handleModalSearchOnEnter(args) {
109 if (args?.e) {
110 args.e.preventDefault();
111 }
112 const form = this.getModalForm();
113 if (!form) {
114 return;
115 }
116 const btn = form.querySelector(ViewStudentsModal.selectors.searchBtn);
117 if (!btn) {
118 return;
119 }
120 this.handleModalSearch({
121 ...args,
122 target: btn
123 });
124 }
125 handleModalClear(args) {
126 const btn = args?.target?.closest(ViewStudentsModal.selectors.clearBtn);
127 const form = this.getModalForm();
128 if (!btn || !form || !this.activeCourseId) {
129 return;
130 }
131 if (args?.e) {
132 args.e.preventDefault();
133 }
134 if (this.isRequesting || btn.classList.contains('loading')) {
135 return;
136 }
137 form.reset();
138 this.setButtonLoadingState(btn, true);
139 this.loadEnrolledStudents(this.activeCourseId, 1, btn);
140 }
141 getModalPopup() {
142 return (sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().getPopup) ? sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().getPopup() : null;
143 }
144 getModalToolbarHtml() {
145 const template = document.querySelector(ViewStudentsModal.selectors.toolbarTemplate);
146 return template ? template.innerHTML : '';
147 }
148 getModalTargetHtml() {
149 const template = document.querySelector(ViewStudentsModal.selectors.targetTemplate);
150 return template ? template.innerHTML : '';
151 }
152 getAjaxHandle() {
153 const ajaxHandle = window.lpAJAXG;
154 if (!ajaxHandle || typeof ajaxHandle.getDataSetCurrent !== 'function' || typeof ajaxHandle.setDataSetCurrent !== 'function' || typeof ajaxHandle.showHideLoading !== 'function' || typeof ajaxHandle.fetchAJAX !== 'function') {
155 return null;
156 }
157 return ajaxHandle;
158 }
159 getModalForm() {
160 const popup = this.getModalPopup();
161 if (!popup) {
162 return null;
163 }
164 return popup.querySelector(ViewStudentsModal.selectors.form);
165 }
166 getModalFilterArgs(dataArgs = {}) {
167 const form = this.getModalForm();
168 if (!form) {
169 return dataArgs;
170 }
171 return lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.mergeDataWithDatForm(form, dataArgs);
172 }
173 loadEnrolledStudents(courseId, paged, elLoading = null) {
174 const wrap = document.querySelector(ViewStudentsModal.selectors.wrap);
175 const elTarget = wrap?.querySelector('.lp-target');
176 const ajaxHandle = this.getAjaxHandle();
177 if (!wrap || !elTarget || !ajaxHandle || this.isRequesting) {
178 return;
179 }
180 this.isRequesting = true;
181 if (elLoading) {
182 this.setButtonLoadingState(elLoading, true);
183 }
184 const dataSend = ajaxHandle.getDataSetCurrent(elTarget);
185 dataSend.args = this.getModalFilterArgs(dataSend.args || {});
186 dataSend.args.course_id = parseInt(courseId, 10) || 0;
187 dataSend.args.paged = paged;
188 ajaxHandle.setDataSetCurrent(elTarget, dataSend);
189 ajaxHandle.showHideLoading(elTarget, 1);
190 const callBack = {
191 success: response => {
192 elTarget.innerHTML = response.data.content;
193 },
194 error: err => {
195 console.error(err);
196 },
197 completed: () => {
198 this.isRequesting = false;
199 ajaxHandle.showHideLoading(elTarget, 0);
200 if (elLoading) {
201 this.setButtonLoadingState(elLoading, false);
202 }
203 }
204 };
205 ajaxHandle.fetchAJAX(dataSend, callBack);
206 }
207 openModal(courseId, courseTitle, elTrigger = null) {
208 const modalToolbarHtml = this.getModalToolbarHtml();
209 const modalTargetHtml = this.getModalTargetHtml();
210 if (!modalToolbarHtml || !modalTargetHtml) {
211 if (elTrigger) {
212 this.setButtonLoadingState(elTrigger, false);
213 }
214 return;
215 }
216 this.activeCourseId = parseInt(courseId, 10) || 0;
217 sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
218 title: `${courseTitle}`,
219 html: modalToolbarHtml + modalTargetHtml,
220 width: '80%',
221 showConfirmButton: false,
222 showCloseButton: true,
223 didOpen: () => {
224 this.loadEnrolledStudents(this.activeCourseId, 1, elTrigger);
225 },
226 didClose: () => {
227 this.activeCourseId = 0;
228 if (elTrigger) {
229 this.setButtonLoadingState(elTrigger, false);
230 }
231 }
232 });
233 }
234
235 // Ensure start date is not after end date and vice versa. If invalid, adjust the other date to match.
236 checkDatesRange(args) {
237 const {
238 e
239 } = args;
240 const elInput = e?.target;
241 if (!elInput) {
242 return;
243 }
244 const elForm = elInput.closest(ViewStudentsModal.selectors.form);
245 if (!elForm) {
246 return;
247 }
248 const startDateInput = elForm.querySelector(ViewStudentsModal.selectors.startDateInput);
249 const endDateInput = elForm.querySelector(ViewStudentsModal.selectors.endDateInput);
250 if (elInput === startDateInput) {
251 if (startDateInput.value) {
252 endDateInput.min = startDateInput.value;
253 if (endDateInput.value && endDateInput.value < startDateInput.value) {
254 endDateInput.value = startDateInput.value;
255 }
256 } else {
257 endDateInput.min = '';
258 }
259 } else if (elInput === endDateInput) {
260 if (endDateInput.value) {
261 startDateInput.max = endDateInput.value;
262 if (startDateInput.value && startDateInput.value > endDateInput.value) {
263 startDateInput.value = endDateInput.value;
264 }
265 } else {
266 startDateInput.max = '';
267 }
268 }
269 }
270 }
271
272 /***/ },
273
274 /***/ "./assets/src/js/api.js"
275 /*!******************************!*\
276 !*** ./assets/src/js/api.js ***!
277 \******************************/
278 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
279
280 "use strict";
281 __webpack_require__.r(__webpack_exports__);
282 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
283 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
284 /* harmony export */ });
285 /**
286 * List API on backend
287 *
288 * @since 4.2.6
289 * @version 1.0.2
290 */
291
292 const lplistAPI = {};
293 let lp_rest_url;
294 if ('undefined' !== typeof lpDataAdmin) {
295 lp_rest_url = lpDataAdmin.lp_rest_url;
296 lplistAPI.admin = {
297 apiAdminNotice: lp_rest_url + 'lp/v1/admin/tools/admin-notices',
298 apiAddons: lp_rest_url + 'lp/v1/addon/all',
299 apiAddonAction: lp_rest_url + 'lp/v1/addon/action-n',
300 apiAddonsPurchase: lp_rest_url + 'lp/v1/addon/info-addons-purchase',
301 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
302 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
303 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
304 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
305 };
306 }
307 if ('undefined' !== typeof lpData) {
308 lp_rest_url = lpData.lp_rest_url;
309 lplistAPI.frontend = {
310 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
311 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
312 // Deprecated API, don't load from v4.3.7
313 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
314 // Deprecated since 4.3.0
315 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
316 };
317 }
318 if (lp_rest_url) {
319 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
320 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
321 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
322 }
323 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
324
325 /***/ },
326
327 /***/ "./assets/src/js/frontend/profile/avatar.js"
328 /*!**************************************************!*\
329 !*** ./assets/src/js/frontend/profile/avatar.js ***!
330 \**************************************************/
331 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
332
333 "use strict";
334 __webpack_require__.r(__webpack_exports__);
335 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
336 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
337 /* harmony export */ });
338 /* harmony import */ var cropperjs_dist_cropper_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! cropperjs/dist/cropper.css */ "./node_modules/cropperjs/dist/cropper.css");
339 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! cropperjs */ "./node_modules/cropperjs/dist/cropper.js");
340 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cropperjs__WEBPACK_IMPORTED_MODULE_1__);
341 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
342 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
343 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_3__);
344 /* 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");
345
346
347
348 // import API from '../../api.js';
349
350
351 const profileAvatarImage = () => {
352 const lpAvatarWrapper = document.querySelector('#learnpress-avatar-upload');
353 if (!lpAvatarWrapper) {
354 return;
355 }
356 let cropper, avatarPreviewSrc, imgUrlOriginal;
357 let avatarForm = lpAvatarWrapper.querySelector('.lp_avatar__form');
358 const btnRemove = lpAvatarWrapper.querySelector('.lp-btn-remove-avatar'),
359 btnReplace = lpAvatarWrapper.querySelector('.lp-btn-choose-avatar'),
360 btnSave = lpAvatarWrapper.querySelector('.lp-btn-save-avatar'),
361 btnCancel = lpAvatarWrapper.querySelector('.lp-btn-cancel-avatar'),
362 avatarPreviewImage = lpAvatarWrapper.querySelector('.lp-avatar-image'),
363 avatarInputFile = lpAvatarWrapper.querySelector('#avatar-file'),
364 profileAvatar = document.querySelector('.wrapper-profile-header .user-avatar img');
365 const avatarRatio = parseFloat((lpProfileSettings.avatar_dimensions.width / lpProfileSettings.avatar_dimensions.height).toFixed(2));
366 lpAvatarWrapper.addEventListener('click', e => {
367 const target = e.target;
368 if (target === btnReplace) {
369 e.preventDefault();
370 avatarInputFile.click();
371 } else if (target === btnSave) {
372 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnSave, 1);
373 btnSave.disabled = true;
374 if (undefined !== cropper) {
375 const canvas = cropper.getCroppedCanvas({
376 width: lpProfileSettings.avatar_dimensions.width,
377 height: lpProfileSettings.avatar_dimensions.height
378 });
379 const newCropSrc = canvas.toDataURL('image/png');
380 if (profileAvatar) {
381 profileAvatar.src = newCropSrc;
382 }
383 avatarPreviewImage.src = newCropSrc;
384 const formData = new FormData();
385 formData.append('file', newCropSrc);
386 uploadAvatar(formData);
387 }
388 } else if (target === btnCancel) {
389 e.preventDefault();
390 cropper.destroy();
391 avatarPreviewImage.src = imgUrlOriginal;
392 if (imgUrlOriginal === window.location.href) {
393 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 1);
394 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 0);
395 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 0);
396 } else {
397 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 1);
398 }
399 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 0);
400 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 0);
401 } else if (target === btnRemove) {
402 btnRemove.disabled = true;
403 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnRemove, 1);
404 removeAvatar();
405 }
406 });
407 lpAvatarWrapper.addEventListener('change', e => {
408 const target = e.target;
409 if (target === avatarInputFile) {
410 const file = avatarInputFile.files[0];
411 if (!file) {
412 return;
413 }
414 const allowType = ['image/png', 'image/jpeg', 'image/webp'];
415 if (allowType.indexOf(file.type) < 0) {
416 return;
417 }
418 const reader = new FileReader();
419 reader.onload = function (e) {
420 avatarPreviewImage.src = e.target.result;
421 // Destroy previous cropper instance if any
422 if (cropper) {
423 cropper.destroy();
424 }
425 // Initialize cropper
426 cropper = new (cropperjs__WEBPACK_IMPORTED_MODULE_1___default())(avatarPreviewImage, {
427 aspectRatio: avatarRatio,
428 viewMode: 1,
429 zoomOnWheel: false
430 });
431 };
432 reader.readAsDataURL(file);
433 if (!avatarPreviewImage.classList.contains('lp-hidden')) {
434 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 1);
435 }
436 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 0);
437 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 1);
438 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 1);
439 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 1);
440 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 0);
441 }
442 });
443 const uploadAvatar = formData => {
444 fetch(`${lpData.lp_rest_url}lp/v1/profile/upload-avatar`, {
445 method: 'POST',
446 headers: {
447 'X-WP-Nonce': lpData.nonce
448 },
449 body: formData
450 }) // wrapped
451 .then(res => res.json()).then(res => {
452 if (res.status === 'error') {
453 throw new Error(res.message);
454 }
455 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 1);
456 showMessage('success', res.message);
457 if (undefined !== cropper) {
458 cropper.destroy();
459 }
460 imgUrlOriginal = avatarPreviewImage.src;
461 }).finally(() => {
462 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 0);
463 btnSave.disabled = false;
464 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnSave, 0);
465 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 0);
466 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 1);
467 }).catch(err => console.log(err));
468 };
469 const removeAvatar = () => {
470 fetch(`${lpData.lp_rest_url}lp/v1/profile/remove-avatar`, {
471 method: 'POST',
472 headers: {
473 'X-WP-Nonce': lpData.nonce
474 }
475 }) // wrapped
476 .then(res => res.json()).then(res => {
477 if (res.status === 'error') {
478 throw new Error(res.message);
479 }
480 showMessage('success', res.message);
481 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 0);
482 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 1);
483 imgUrlOriginal = avatarPreviewSrc = '';
484 profileAvatar.src = lpProfileSettings.default_avatar;
485 // window.location.href = window.location.href;
486 }).finally(() => {
487 btnRemove.disabled = false;
488 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 0);
489 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnRemove, 0);
490 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 0);
491 }).catch(err => console.log(err));
492 };
493 const showMessage = (status, message) => {
494 toastify_js__WEBPACK_IMPORTED_MODULE_3___default()({
495 text: message,
496 gravity: lpData.toast.gravity,
497 // `top` or `bottom`
498 position: lpData.toast.position,
499 // `left`, `center` or `right`
500 className: `${lpData.toast.classPrefix} ${status}`,
501 close: lpData.toast.close == 1,
502 stopOnFocus: lpData.toast.stopOnFocus == 1,
503 duration: lpData.toast.duration
504 }).showToast();
505 };
506 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady('.lp-avatar-image', () => {
507 imgUrlOriginal = avatarPreviewImage.src;
508 });
509 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady('#learnpress-avatar-upload', e => {
510 e.scrollIntoView({
511 behavior: 'smooth',
512 block: 'center'
513 });
514 });
515 };
516 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileAvatarImage);
517
518 /***/ },
519
520 /***/ "./assets/src/js/frontend/profile/course-tab.js"
521 /*!******************************************************!*\
522 !*** ./assets/src/js/frontend/profile/course-tab.js ***!
523 \******************************************************/
524 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
525
526 "use strict";
527 __webpack_require__.r(__webpack_exports__);
528 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
529 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
530 /* harmony export */ });
531 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
532
533
534 // Rest API load content course enrolled, created - Nhamdv.
535 const courseTab = () => {
536 const elements = document.querySelectorAll('.learn-press-course-tab__filter__content');
537 const getResponse = (ele, dataset, append = false, viewMoreEle = false) => {
538 let url = lpData.lp_rest_url + 'lp/v1/profile/course-tab';
539 url = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpAddQueryArgs)(url, dataset);
540 const callBack = {
541 success: response => {
542 const skeleton = ele.querySelector('.lp-skeleton-animation');
543 skeleton && skeleton.remove();
544 if (response.status === 'success' && response.data) {
545 if (append) {
546 ele.innerHTML += response.data;
547 } else {
548 ele.innerHTML = response.data;
549 }
550 } else if (append) {
551 ele.innerHTML += `<div class="lp-ajax-message" style="display:block">${response.message && response.message}</div>`;
552 } else {
553 ele.innerHTML = `<div class="lp-ajax-message" style="display:block">${response.message && response.message}</div>`;
554 }
555 if (viewMoreEle) {
556 viewMoreEle.classList.remove('loading');
557 const paged = parseInt(viewMoreEle.dataset.paged);
558 const numberPage = parseInt(viewMoreEle.dataset.number);
559 if (numberPage <= paged) {
560 viewMoreEle.remove();
561 }
562 viewMoreEle.dataset.paged = paged + 1;
563 }
564 viewMore(ele, dataset);
565 },
566 error: error => {
567 console.log(error);
568 },
569 completed: () => {}
570 };
571 let paramsFetch = {};
572 if (0 !== parseInt(lpData.user_id)) {
573 paramsFetch = {
574 headers: {
575 'X-WP-Nonce': lpData.nonce
576 }
577 };
578 }
579 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI)(url, paramsFetch, callBack);
580 };
581 if ('IntersectionObserver' in window) {
582 const eleObserver = new IntersectionObserver((entries, observer) => {
583 entries.forEach(entry => {
584 if (entry.isIntersecting) {
585 const ele = entry.target;
586 const params = ele.parentNode.querySelector('.lp_profile_tab_input_param');
587 const data = {
588 ...JSON.parse(params.value),
589 status: ele.dataset.tab || ''
590 };
591 getResponse(ele, data);
592 eleObserver.unobserve(ele);
593 }
594 });
595 });
596 [...elements].map(ele => {
597 if (ele.dataset.tab !== 'all') {
598 eleObserver.observe(ele);
599 } else {
600 const params = ele.parentNode.querySelector('.lp_profile_tab_input_param');
601 const data = {
602 ...JSON.parse(params.value),
603 status: ele.dataset.tab === 'all' ? '' : ele.dataset.tab || ''
604 };
605 getResponse(ele, data);
606 }
607 });
608 }
609 const changeFilter = () => {
610 const tabs = document.querySelectorAll('.learn-press-course-tab-filters');
611 tabs.forEach(tab => {
612 const filters = tab.querySelectorAll('.learn-press-filters a');
613 filters.forEach(filter => {
614 filter.addEventListener('click', e => {
615 e.preventDefault();
616 const tabName = filter.dataset.tab;
617 [...filters].map(ele => {
618 ele.classList.remove('active');
619 });
620 filter.classList.add('active');
621 [...tab.querySelectorAll('.learn-press-course-tab__filter__content')].map(ele => {
622 ele.style.display = 'none';
623 if (ele.dataset.tab === tabName) {
624 ele.style.display = '';
625 }
626 });
627 });
628 });
629 });
630 };
631 changeFilter();
632 const viewMore = (ele, dataset) => {
633 const viewMoreEle = ele.querySelector('button[data-paged]');
634 if (viewMoreEle) {
635 viewMoreEle.addEventListener('click', e => {
636 e.preventDefault();
637 const paged = viewMoreEle && viewMoreEle.dataset.paged;
638 viewMoreEle.classList.add('loading');
639 const element = dataset.layout === 'list' ? '.lp_profile_course_progress' : '.learn-press-courses';
640 getResponse(ele.querySelector(element), {
641 ...dataset,
642 ...{
643 paged
644 }
645 }, true, viewMoreEle);
646 });
647 }
648 };
649 };
650 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (courseTab);
651
652 /***/ },
653
654 /***/ "./assets/src/js/frontend/profile/cover-image.js"
655 /*!*******************************************************!*\
656 !*** ./assets/src/js/frontend/profile/cover-image.js ***!
657 \*******************************************************/
658 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
659
660 "use strict";
661 __webpack_require__.r(__webpack_exports__);
662 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
663 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
664 /* harmony export */ });
665 /* harmony import */ var cropperjs_dist_cropper_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! cropperjs/dist/cropper.css */ "./node_modules/cropperjs/dist/cropper.css");
666 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! cropperjs */ "./node_modules/cropperjs/dist/cropper.js");
667 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cropperjs__WEBPACK_IMPORTED_MODULE_1__);
668 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
669 /* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../api.js */ "./assets/src/js/api.js");
670 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
671 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_4__);
672 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
673
674
675
676
677
678
679 const profileCoverImage = () => {
680 const lpSet = new Set();
681 let cropper;
682 let elBtnSave, elBtnRemove, elBtnChoose, elBtnCancel, elImagePreview, elCoverImageBackground, elImgCoverImageBackground, elImageEmpty, formCoverImage, elInputFile, elAction, imgUrlOriginal;
683 const className = {
684 formCoverImage: 'lp-user-cover-image',
685 BtnChooseCoverImage: 'lp-btn-choose-cover-image',
686 BtnSaveCoverImage: 'lp-btn-save-cover-image',
687 BtnRemoveCoverImage: 'lp-btn-remove-cover-image',
688 BtnCancelCoverImage: 'lp-btn-cancel-cover-image',
689 BtnToEditCoverImage: 'lp-btn-to-edit-cover-image',
690 CoverImagePreview: 'lp-cover-image-preview',
691 CoverImageEmpty: 'lp-cover-image-empty',
692 CoverImageBackground: 'lp-user-cover-image_background',
693 InputFile: 'lp-cover-image-file',
694 loading: 'loading',
695 hidden: 'lp-hidden'
696 };
697
698 /**
699 * Get elements to use.
700 */
701 const getElements = () => {
702 elBtnSave = formCoverImage.querySelector(`.${className.BtnSaveCoverImage}`);
703 elBtnChoose = formCoverImage.querySelector(`.${className.BtnChooseCoverImage}`);
704 elBtnRemove = formCoverImage.querySelector(`.${className.BtnRemoveCoverImage}`);
705 elBtnCancel = formCoverImage.querySelector(`.${className.BtnCancelCoverImage}`);
706 elImagePreview = formCoverImage.querySelector(`.${className.CoverImagePreview}`);
707 elCoverImageBackground = document.querySelector(`.${className.CoverImageBackground}`);
708 elImgCoverImageBackground = elCoverImageBackground.querySelector(`img`);
709 elImageEmpty = formCoverImage.querySelector(`.${className.CoverImageEmpty}`);
710 elAction = formCoverImage.querySelector('input[name=action]');
711 elInputFile = formCoverImage.querySelector('input[name=lp-cover-image-file]');
712 if (!lpSet.has('everClick')) {
713 imgUrlOriginal = elImagePreview.src;
714 lpSet.add('everClick');
715 }
716 };
717 const fetchAPI = formData => {
718 const callBack = {
719 success: response => {
720 const {
721 status,
722 message,
723 data
724 } = response;
725 toastify_js__WEBPACK_IMPORTED_MODULE_4___default()({
726 text: message,
727 gravity: lpData.toast.gravity,
728 // `top` or `bottom`
729 position: lpData.toast.position,
730 // `left`, `center` or `right`
731 className: `${lpData.toast.classPrefix} ${status}`,
732 close: lpData.toast.close == 1,
733 stopOnFocus: lpData.toast.stopOnFocus == 1,
734 duration: lpData.toast.duration
735 }).showToast();
736 if ('remove' === data.action) {
737 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
738 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 0);
739 elImagePreview.src = '';
740 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 0);
741 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 1);
742 if (elCoverImageBackground) {
743 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elCoverImageBackground, 0);
744 }
745 } else if ('upload' === data.action) {
746 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 1);
747 elImagePreview.src = data.url;
748 imgUrlOriginal = data.url;
749 cropper.destroy();
750 }
751 imgUrlOriginal = elImagePreview.src;
752 },
753 error: error => {
754 console.log(error);
755 },
756 completed: () => {
757 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 0);
758 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnSave, 0);
759 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnRemove, 0);
760 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 0);
761 if (!elImagePreview.src || elImagePreview.src === window.location.href) {
762 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
763 } else {
764 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 1);
765 }
766 }
767 };
768 const url = _api_js__WEBPACK_IMPORTED_MODULE_3__["default"].frontend.apiProfileCoverImage;
769 const option = {
770 headers: {}
771 };
772 if (0 !== parseInt(lpData.user_id)) {
773 option.headers['X-WP-Nonce'] = lpData.nonce;
774 }
775 option.method = 'POST';
776 option.body = formData;
777 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpFetchAPI(url, option, callBack);
778 };
779
780 // Events
781 document.addEventListener('click', e => {
782 const target = e.target;
783 if (target.classList.contains(className.BtnToEditCoverImage)) {
784 formCoverImage = document.querySelector(`.${className.formCoverImage}`);
785 if (!formCoverImage) {
786 return;
787 }
788 const isCorrectSection = target.dataset.sectionCorrect == 1;
789 if (isCorrectSection) {
790 e.preventDefault();
791 formCoverImage.scrollIntoView({
792 behavior: 'smooth',
793 block: 'center'
794 });
795 }
796 }
797 formCoverImage = target.closest(`.${className.formCoverImage}`);
798 if (!formCoverImage) {
799 return;
800 }
801 getElements();
802 if (target.classList.contains(className.BtnChooseCoverImage)) {
803 e.preventDefault();
804 elInputFile.click();
805 }
806 if (target.classList.contains(className.BtnSaveCoverImage)) {
807 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnSave, 1);
808 }
809 if (target.classList.contains(className.BtnCancelCoverImage)) {
810 e.preventDefault();
811 cropper.destroy();
812 elImagePreview.src = imgUrlOriginal;
813 if (imgUrlOriginal === window.location.href) {
814 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 1);
815 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 0);
816 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 0);
817 } else {
818 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 1);
819 }
820 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 0);
821 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 0);
822 }
823 if (target.classList.contains(className.BtnRemoveCoverImage)) {
824 e.preventDefault();
825 target.classList.add('loading');
826 if (cropper) {
827 cropper.destroy();
828 cropper = undefined;
829 }
830 elAction.value = 'remove';
831 elBtnSave.click();
832 }
833 if (target.classList.contains(className.CoverImageEmpty)) {
834 e.preventDefault();
835 elInputFile.click();
836 }
837 });
838 document.addEventListener('change', e => {
839 const target = e.target;
840 formCoverImage = target.closest(`.${className.formCoverImage}`);
841 if (!formCoverImage) {
842 return;
843 }
844 getElements();
845 if (target.classList.contains(className.InputFile)) {
846 e.preventDefault();
847 const file = target.files[0];
848 if (!file) {
849 return;
850 }
851 const allowType = ['image/png', 'image/jpeg', 'image/webp'];
852 if (allowType.indexOf(file.type) < 0) {
853 return;
854 }
855 elAction.value = 'upload';
856 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 1);
857 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 0);
858 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
859 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 1);
860 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 1);
861 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 1);
862 const reader = new FileReader();
863 reader.onload = function (e) {
864 elImagePreview.src = e.target.result;
865 // Destroy previous cropper instance if any
866 if (cropper) {
867 cropper.destroy();
868 }
869 // Initialize cropper
870 cropper = new (cropperjs__WEBPACK_IMPORTED_MODULE_1___default())(elImagePreview, {
871 aspectRatio: lpData.coverImageRatio,
872 viewMode: 1,
873 zoomOnWheel: false
874 });
875 };
876 reader.readAsDataURL(file);
877 }
878 });
879 document.addEventListener('submit', e => {
880 const target = e.target;
881 if (target.classList.contains(className.formCoverImage)) {
882 e.preventDefault();
883 const formData = new FormData(target);
884 if (undefined !== cropper) {
885 const canvas = cropper.getCroppedCanvas({});
886 if (elCoverImageBackground) {
887 const dataUrl = canvas.toDataURL('image/png');
888 elCoverImageBackground.style.backgroundImage = `url(${dataUrl})`;
889 elImgCoverImageBackground.src = dataUrl;
890 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elCoverImageBackground, 1);
891 }
892 canvas.toBlob(blob => {
893 formData.append('image', blob, 'cover.png');
894 fetchAPI(formData);
895 }, 'image/png');
896 } else {
897 fetchAPI(formData);
898 }
899 }
900 });
901 document.addEventListener('DOMContentLoaded', e => {
902 const elBtnToEditCoverImage = document.querySelector(`.${className.BtnToEditCoverImage}`);
903 const formCoverImage = document.querySelector(`.${className.formCoverImage}`);
904 if (elBtnToEditCoverImage && formCoverImage) {
905 const isCorrectSection = elBtnToEditCoverImage.dataset.sectionCorrect == 1;
906 if (isCorrectSection) {
907 formCoverImage.scrollIntoView({
908 behavior: 'smooth',
909 block: 'center'
910 });
911 }
912 }
913 });
914 };
915 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileCoverImage);
916
917 /***/ },
918
919 /***/ "./assets/src/js/frontend/profile/order-recover.js"
920 /*!*********************************************************!*\
921 !*** ./assets/src/js/frontend/profile/order-recover.js ***!
922 \*********************************************************/
923 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
924
925 "use strict";
926 __webpack_require__.r(__webpack_exports__);
927 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
928 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
929 /* harmony export */ });
930 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
931 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
932 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_1__);
933
934
935
936 /**
937 * JS Recover order
938 *
939 * @since 4.0.0
940 * @version 1.0.1
941 */
942 const recoverOrder = () => {
943 const toastify = toastify_js__WEBPACK_IMPORTED_MODULE_1___default()({
944 gravity: lpData.toast.gravity,
945 // `top` or `bottom`
946 position: lpData.toast.position,
947 // `left`, `center` or `right`
948 close: lpData.toast.close == 1,
949 className: `${lpData.toast.classPrefix}`,
950 stopOnFocus: lpData.toast.stopOnFocus == 1,
951 duration: lpData.toast.duration
952 });
953
954 // Events
955 document.addEventListener('submit', e => {
956 const target = e.target;
957 if (target.classList.contains('lp-order-recover')) {
958 e.preventDefault();
959 ajaxRecover(target);
960 }
961 });
962 const ajaxRecover = form => {
963 const status = 'error';
964 const btnSubmit = form.querySelector('.button-recover-order');
965 if (!btnSubmit) {
966 return;
967 }
968 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl)(btnSubmit, 1);
969 const url = new URL(window.location.href);
970 fetch(url, {
971 method: 'POST',
972 body: new FormData(form)
973 }).then(response => {
974 return response.json();
975 }).then(res => {
976 const {
977 status,
978 data: {
979 redirect
980 },
981 message
982 } = res;
983 if (status === 'success') {
984 toastify.options.text = message;
985 toastify.options.className += ` ${status}`;
986 toastify.showToast();
987 if (redirect) {
988 window.location.href = redirect;
989 }
990 btnSubmit.remove();
991 } else {
992 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl)(btnSubmit, 0);
993 throw new Error(message);
994 }
995 }).finally(() => {}).catch(err => {
996 toastify.options.text = err.message;
997 toastify.options.className += ` ${status}`;
998 toastify.showToast();
999 });
1000 };
1001 };
1002 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (recoverOrder);
1003
1004 /***/ },
1005
1006 /***/ "./assets/src/js/frontend/profile/order-refund.js"
1007 /*!********************************************************!*\
1008 !*** ./assets/src/js/frontend/profile/order-refund.js ***!
1009 \********************************************************/
1010 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1011
1012 "use strict";
1013 __webpack_require__.r(__webpack_exports__);
1014 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1015 /* harmony export */ OrderRefund: () => (/* binding */ OrderRefund),
1016 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1017 /* harmony export */ });
1018 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1019 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
1020 /* harmony import */ var _lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../lpToastify */ "./assets/src/js/lpToastify.js");
1021 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
1022
1023
1024
1025
1026 /**
1027 * Order Refund Script
1028 *
1029 * Handle refund action on profile orders list.
1030 *
1031 * @since 4.3.5
1032 * @version 1.0.0
1033 */
1034 class OrderRefund {
1035 constructor() {
1036 this.isRequesting = false;
1037 }
1038 static selectors = {
1039 actionRefund: '.lp-refund-order-action'
1040 };
1041 init() {
1042 this.events();
1043 }
1044 events() {
1045 if (OrderRefund._loadedEvents) {
1046 return;
1047 }
1048 OrderRefund._loadedEvents = this;
1049 _utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('click', [{
1050 selector: OrderRefund.selectors.actionRefund,
1051 class: this,
1052 callBack: this.handleRefundClick.name
1053 }]);
1054 }
1055 getAjaxHandle() {
1056 const ajaxHandle = window.lpAJAXG;
1057 if (!ajaxHandle || typeof ajaxHandle.fetchAJAX !== 'function') {
1058 return null;
1059 }
1060 return ajaxHandle;
1061 }
1062 setActionLoadingState(actionLink, isLoading) {
1063 if (!actionLink) {
1064 return;
1065 }
1066 if (isLoading) {
1067 actionLink.dataset.refundSubmitting = 'yes';
1068 } else {
1069 delete actionLink.dataset.refundSubmitting;
1070 }
1071 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(actionLink, isLoading ? 1 : 0);
1072 }
1073 getActionData(actionLink) {
1074 const reasonMin = parseInt(actionLink.dataset.reasonMin || '10', 10);
1075 return {
1076 orderId: parseInt(actionLink.dataset.orderId || '0', 10),
1077 requireReason: actionLink.dataset.requireReason === 'yes',
1078 reasonMin: Number.isNaN(reasonMin) ? 10 : reasonMin,
1079 reasonPrompt: actionLink.dataset.reasonPrompt || '',
1080 reasonPlaceholder: actionLink.dataset.reasonPlaceholder || '',
1081 reasonRequired: actionLink.dataset.reasonRequired || '',
1082 confirmTitle: actionLink.dataset.confirmTitle || '',
1083 confirmText: actionLink.dataset.confirmText || '',
1084 confirmButton: actionLink.dataset.confirmButton || '',
1085 cancelButton: actionLink.dataset.cancelButton || ''
1086 };
1087 }
1088 openReasonModal(data) {
1089 return sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
1090 title: data.reasonPrompt,
1091 input: 'textarea',
1092 inputPlaceholder: data.reasonPlaceholder,
1093 inputAutoTrim: true,
1094 showCancelButton: true,
1095 confirmButtonText: data.confirmButton,
1096 cancelButtonText: data.cancelButton,
1097 inputValidator: value => {
1098 const reason = (value || '').trim();
1099 if (!reason.length) {
1100 return data.reasonRequired;
1101 }
1102 return undefined;
1103 }
1104 });
1105 }
1106 openConfirmModal(data) {
1107 return sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
1108 icon: 'warning',
1109 title: data.confirmTitle,
1110 text: data.confirmText,
1111 showCancelButton: true,
1112 confirmButtonText: data.confirmButton,
1113 cancelButtonText: data.cancelButton
1114 });
1115 }
1116 sendRefundRequest(actionLink, data, reason = '') {
1117 const ajaxHandle = this.getAjaxHandle();
1118 if (!ajaxHandle) {
1119 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Refund action is unavailable right now.', 'error');
1120 return;
1121 }
1122 if (!data.orderId) {
1123 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Invalid order.', 'error');
1124 return;
1125 }
1126 this.isRequesting = true;
1127 this.setActionLoadingState(actionLink, true);
1128 const dataSend = {
1129 action: 'request_refund_order',
1130 order_id: data.orderId,
1131 reason
1132 };
1133 ajaxHandle.fetchAJAX(dataSend, {
1134 success: response => {
1135 const {
1136 status,
1137 message,
1138 data
1139 } = response;
1140 if (status !== 'success') {
1141 throw new Error(message);
1142 }
1143 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'success');
1144 setTimeout(() => {
1145 window.location.reload();
1146 }, 1200);
1147 },
1148 error: error => {
1149 const message = error?.message || error || 'Refund request failed.';
1150 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
1151 },
1152 completed: () => {
1153 this.isRequesting = false;
1154 this.setActionLoadingState(actionLink, false);
1155 }
1156 });
1157 }
1158 async handleRefundClick(args) {
1159 const {
1160 e,
1161 target
1162 } = args;
1163 e.preventDefault();
1164 const actionLink = target.closest(OrderRefund.selectors.actionRefund);
1165 if (!actionLink) {
1166 return;
1167 }
1168 if (this.isRequesting || actionLink.dataset.refundSubmitting === 'yes' || actionLink.classList.contains('loading')) {
1169 return;
1170 }
1171 const actionData = this.getActionData(actionLink);
1172 let reason = '';
1173 if (actionData.requireReason) {
1174 const reasonResult = await this.openReasonModal(actionData);
1175 if (!reasonResult.isConfirmed) {
1176 return;
1177 }
1178 reason = (reasonResult.value || '').trim();
1179 }
1180 const confirmResult = await this.openConfirmModal(actionData);
1181 if (!confirmResult.isConfirmed) {
1182 return;
1183 }
1184 this.sendRefundRequest(actionLink, actionData, reason);
1185 }
1186 }
1187 const orderRefund = () => {
1188 const orderRefundHandle = new OrderRefund();
1189 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady(OrderRefund.selectors.actionRefund, () => {
1190 orderRefundHandle.init();
1191 });
1192 };
1193 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (orderRefund);
1194
1195 /***/ },
1196
1197 /***/ "./assets/src/js/frontend/profile/quiz.js"
1198 /*!************************************************!*\
1199 !*** ./assets/src/js/frontend/profile/quiz.js ***!
1200 \************************************************/
1201 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1202
1203 "use strict";
1204 __webpack_require__.r(__webpack_exports__);
1205 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1206 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1207 /* harmony export */ });
1208 /**
1209 * Handle click tab call API
1210 *
1211 * @since 4.2.8.2
1212 * @version 1.0.0
1213 */
1214 const profileQuizTab = () => {
1215 const handleClickTab = (e, target) => {
1216 if (target.closest('span')) {
1217 const elParent = target.closest('#profile-content-quizzes');
1218 if (!elParent) {
1219 return;
1220 }
1221 const elLPTarget = target.closest('.lp-target');
1222 if (!elLPTarget) {
1223 return;
1224 }
1225 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1226 const dataSendJson = elLPTarget?.dataset?.send || {};
1227 const dataSend = JSON.parse(dataSendJson);
1228 const elTabChoice = target?.dataset?.filter || 'all';
1229 const liActive = elParent.querySelector('li.active');
1230 if (liActive.classList.contains(elTabChoice)) {
1231 return;
1232 }
1233 liActive.classList.remove('active');
1234 const liTarget = target.closest('li');
1235 liTarget.classList.add('active');
1236 dataSend.args.type = elTabChoice;
1237
1238 // Load list courses by AJAX.
1239 const callBack = {
1240 success: response => {
1241 const {
1242 data,
1243 message,
1244 status
1245 } = response;
1246 if ('success' === status) {
1247 elLPTarget.innerHTML = data.content || '';
1248 }
1249 },
1250 error: error => {
1251 console.log(error);
1252 },
1253 completed: () => {
1254 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1255 }
1256 };
1257 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1258 }
1259 };
1260 document.addEventListener('click', e => {
1261 const target = e.target;
1262 handleClickTab(e, target);
1263 });
1264 };
1265 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileQuizTab);
1266
1267 /***/ },
1268
1269 /***/ "./assets/src/js/frontend/profile/statistic.js"
1270 /*!*****************************************************!*\
1271 !*** ./assets/src/js/frontend/profile/statistic.js ***!
1272 \*****************************************************/
1273 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1274
1275 "use strict";
1276 __webpack_require__.r(__webpack_exports__);
1277 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1278 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1279 /* harmony export */ });
1280 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
1281
1282
1283 // Rest API load content course progress - Nhamdv.
1284 const courseStatistics = () => {
1285 const loadAPICourseStatistic = elCourseStatistic => {
1286 let apiUrl = 'lp/v1/profile/student/statistic';
1287 const tabActive = document.querySelector('.lp-profile-nav-tabs li.active');
1288 if (!tabActive) {
1289 return;
1290 }
1291 if (tabActive.classList.contains('courses')) {
1292 apiUrl = 'lp/v1/profile/instructor/statistic';
1293 }
1294 const elArgStatistic = elCourseStatistic.querySelector('[name="args_query_user_courses_statistic"]');
1295 if (!elArgStatistic) {
1296 return;
1297 }
1298 const data = JSON.parse(elArgStatistic.value);
1299 const callBack = {
1300 success: response => {
1301 if (response.status === 'success' && response.data) {
1302 elCourseStatistic.innerHTML = response.data;
1303 } else {
1304 elCourseStatistic.innerHTML = `<div class="lp-ajax-message error" style="display:block">${response.message && response.message}</div>`;
1305 }
1306 },
1307 error: error => {
1308 console.log(error);
1309 },
1310 completed: () => {}
1311 };
1312 apiUrl = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpAddQueryArgs)(lpData.lp_rest_url + apiUrl, data);
1313 if (0 !== parseInt(lpData.user_id)) {
1314 data.headers = {
1315 'X-WP-Nonce': lpData.nonce
1316 };
1317 }
1318 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI)(apiUrl, data, callBack);
1319 };
1320 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady)('.learn-press-profile-course__statistic', elCourseStatistic => {
1321 loadAPICourseStatistic(elCourseStatistic);
1322 });
1323 };
1324 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (courseStatistics);
1325
1326 /***/ },
1327
1328 /***/ "./assets/src/js/lpToastify.js"
1329 /*!*************************************!*\
1330 !*** ./assets/src/js/lpToastify.js ***!
1331 \*************************************/
1332 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1333
1334 "use strict";
1335 __webpack_require__.r(__webpack_exports__);
1336 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1337 /* harmony export */ show: () => (/* binding */ show)
1338 /* harmony export */ });
1339 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1340 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
1341 /* 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");
1342 /**
1343 * Utils functions
1344 *
1345 * @param url
1346 * @param data
1347 * @param functions
1348 * @since 4.3.0
1349 * @version 1.0.0
1350 */
1351
1352
1353 const argsToastify = {
1354 text: '',
1355 gravity: lpData.toast.gravity,
1356 // `top` or `bottom`
1357 position: lpData.toast.position,
1358 // `left`, `center` or `right`
1359 className: `${lpData.toast.classPrefix}`,
1360 close: lpData.toast.close == 1,
1361 stopOnFocus: lpData.toast.stopOnFocus == 1,
1362 duration: lpData.toast.duration
1363 };
1364 const show = (message, status = 'success', argsCustom) => {
1365 let args = argsToastify;
1366 if (argsCustom) {
1367 args = {
1368 ...args,
1369 ...argsCustom
1370 };
1371 }
1372 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
1373 ...args,
1374 text: message,
1375 className: `${lpData.toast.classPrefix} ${status}`
1376 });
1377 toastify.showToast();
1378 };
1379
1380 /***/ },
1381
1382 /***/ "./assets/src/js/utils.js"
1383 /*!********************************!*\
1384 !*** ./assets/src/js/utils.js ***!
1385 \********************************/
1386 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1387
1388 "use strict";
1389 __webpack_require__.r(__webpack_exports__);
1390 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1391 /* harmony export */ debounce: () => (/* binding */ debounce),
1392 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
1393 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
1394 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1395 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1396 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1397 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1398 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1399 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1400 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1401 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1402 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1403 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1404 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1405 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1406 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1407 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
1408 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
1409 /* harmony export */ });
1410 /**
1411 * Utils functions
1412 *
1413 * @param url
1414 * @param data
1415 * @param functions
1416 * @since 4.2.5.1
1417 * @version 1.0.7
1418 */
1419 const lpClassName = {
1420 hidden: 'lp-hidden',
1421 loading: 'loading',
1422 elCollapse: 'lp-collapse',
1423 elSectionToggle: '.lp-section-toggle',
1424 elTriggerToggle: '.lp-trigger-toggle',
1425 elBtnFullScreen: '.lp-btn-full-screen-view',
1426 elFullScreen: 'lp-full-screen-view',
1427 elBtnFullScreenClose: 'lp-full-screen-view__close'
1428 };
1429 const lpFetchAPI = (url, data = {}, functions = {}) => {
1430 if ('function' === typeof functions.before) {
1431 functions.before();
1432 }
1433 fetch(url, {
1434 method: 'GET',
1435 ...data
1436 }).then(response => response.json()).then(response => {
1437 if ('function' === typeof functions.success) {
1438 functions.success(response);
1439 }
1440 }).catch(err => {
1441 if ('function' === typeof functions.error) {
1442 functions.error(err);
1443 }
1444 }).finally(() => {
1445 if ('function' === typeof functions.completed) {
1446 functions.completed();
1447 }
1448 });
1449 };
1450
1451 /**
1452 * Get current URL without params.
1453 *
1454 * @since 4.2.5.1
1455 */
1456 const lpGetCurrentURLNoParam = () => {
1457 let currentUrl = window.location.href;
1458 const hasParams = currentUrl.includes('?');
1459 if (hasParams) {
1460 currentUrl = currentUrl.split('?')[0];
1461 }
1462 return currentUrl;
1463 };
1464 const lpAddQueryArgs = (endpoint, args) => {
1465 const url = new URL(endpoint);
1466 Object.keys(args).forEach(arg => {
1467 url.searchParams.set(arg, args[arg]);
1468 });
1469 return url;
1470 };
1471
1472 /**
1473 * Listen element viewed.
1474 *
1475 * @param el
1476 * @param callback
1477 * @since 4.2.5.8
1478 */
1479 const listenElementViewed = (el, callback) => {
1480 const observerSeeItem = new IntersectionObserver(function (entries) {
1481 for (const entry of entries) {
1482 if (entry.isIntersecting) {
1483 callback(entry);
1484 }
1485 }
1486 });
1487 observerSeeItem.observe(el);
1488 };
1489
1490 /**
1491 * Listen element created.
1492 *
1493 * @param callback
1494 * @since 4.2.5.8
1495 */
1496 const listenElementCreated = callback => {
1497 const observerCreateItem = new MutationObserver(function (mutations) {
1498 mutations.forEach(function (mutation) {
1499 if (mutation.addedNodes) {
1500 mutation.addedNodes.forEach(function (node) {
1501 if (node.nodeType === 1) {
1502 callback(node);
1503 }
1504 });
1505 }
1506 });
1507 });
1508 observerCreateItem.observe(document, {
1509 childList: true,
1510 subtree: true
1511 });
1512 // End.
1513 };
1514
1515 /**
1516 * Listen element created.
1517 *
1518 * @param selector
1519 * @param callback
1520 * @since 4.2.7.1
1521 */
1522 const lpOnElementReady = (selector, callback) => {
1523 const element = document.querySelector(selector);
1524 if (element) {
1525 callback(element);
1526 return;
1527 }
1528 const observer = new MutationObserver((mutations, obs) => {
1529 const element = document.querySelector(selector);
1530 if (element) {
1531 obs.disconnect();
1532 callback(element);
1533 }
1534 });
1535 observer.observe(document.documentElement, {
1536 childList: true,
1537 subtree: true
1538 });
1539 };
1540
1541 // Parse JSON from string with content include LP_AJAX_START.
1542 const lpAjaxParseJsonOld = data => {
1543 if (typeof data !== 'string') {
1544 return data;
1545 }
1546 const m = String.raw({
1547 raw: data
1548 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1549 try {
1550 if (m) {
1551 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1552 } else {
1553 data = JSON.parse(data);
1554 }
1555 } catch (e) {
1556 data = {};
1557 }
1558 return data;
1559 };
1560
1561 // status 0: hide, 1: show
1562 const lpShowHideEl = (el, status = 0) => {
1563 if (!el) {
1564 return;
1565 }
1566 if (!status) {
1567 el.classList.add(lpClassName.hidden);
1568 } else {
1569 el.classList.remove(lpClassName.hidden);
1570 }
1571 };
1572
1573 // status 0: hide, 1: show
1574 const lpSetLoadingEl = (el, status) => {
1575 if (!el) {
1576 return;
1577 }
1578 if (!status) {
1579 el.classList.remove(lpClassName.loading);
1580 } else {
1581 el.classList.add(lpClassName.loading);
1582 }
1583 };
1584
1585 // Toggle collapse section
1586 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1587 if (!elTriggerClassName) {
1588 elTriggerClassName = lpClassName.elTriggerToggle;
1589 }
1590
1591 // Exclude elements, which should not trigger the collapse toggle
1592 if (elsExclude && elsExclude.length > 0) {
1593 for (const elExclude of elsExclude) {
1594 if (target.closest(elExclude)) {
1595 return;
1596 }
1597 }
1598 }
1599 const elTrigger = target.closest(elTriggerClassName);
1600 if (!elTrigger) {
1601 return;
1602 }
1603
1604 //console.log( 'elTrigger', elTrigger );
1605
1606 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1607 if (!elSectionToggle) {
1608 return;
1609 }
1610 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1611 if ('function' === typeof callback) {
1612 callback(elSectionToggle);
1613 }
1614 };
1615
1616 // Get data of form
1617 const getDataOfForm = form => {
1618 const dataSend = {};
1619 const formData = new FormData(form);
1620 for (const pair of formData.entries()) {
1621 const key = pair[0];
1622 const value = formData.getAll(key);
1623 if (!dataSend.hasOwnProperty(key)) {
1624 // Convert value array to string.
1625 dataSend[key] = value.join(',');
1626 }
1627 }
1628 return dataSend;
1629 };
1630
1631 // Get field keys of form
1632 const getFieldKeysOfForm = form => {
1633 const keys = [];
1634 const elements = form.elements;
1635 for (let i = 0; i < elements.length; i++) {
1636 const name = elements[i].name;
1637 if (name && !keys.includes(name)) {
1638 keys.push(name);
1639 }
1640 }
1641 return keys;
1642 };
1643
1644 // Merge data handle with data form.
1645 const mergeDataWithDatForm = (elForm, dataHandle) => {
1646 const dataForm = getDataOfForm(elForm);
1647 const keys = getFieldKeysOfForm(elForm);
1648 keys.forEach(key => {
1649 if (!dataForm.hasOwnProperty(key)) {
1650 delete dataHandle[key];
1651 } else if (dataForm[key][0] === '') {
1652 delete dataForm[key];
1653 delete dataHandle[key];
1654 }
1655 });
1656 dataHandle = {
1657 ...dataHandle,
1658 ...dataForm
1659 };
1660 return dataHandle;
1661 };
1662
1663 /**
1664 * Event trigger
1665 * For each list of event handlers, listen event on document.
1666 *
1667 * eventName: 'click', 'change', ...
1668 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
1669 *
1670 * @param eventName
1671 * @param eventHandlers
1672 */
1673 const eventHandlers = (eventName, eventHandlers) => {
1674 document.addEventListener(eventName, e => {
1675 const target = e.target;
1676 let args = {
1677 e,
1678 target
1679 };
1680 eventHandlers.forEach(eventHandler => {
1681 args = {
1682 ...args,
1683 ...eventHandler
1684 };
1685
1686 //console.log( args );
1687
1688 // Check condition before call back
1689 if (eventHandler.conditionBeforeCallBack) {
1690 if (eventHandler.conditionBeforeCallBack(args) !== true) {
1691 return;
1692 }
1693 }
1694
1695 // Special check for keydown event with checkIsEventEnter = true
1696 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
1697 if (e.key !== 'Enter') {
1698 return;
1699 }
1700 }
1701 if (target.closest(eventHandler.selector)) {
1702 if (eventHandler.class) {
1703 // Call method of class, function callBack will understand exactly {this} is class object.
1704 eventHandler.class[eventHandler.callBack](args);
1705 } else {
1706 // For send args is objected, {this} is eventHandler object, not class object.
1707 eventHandler.callBack(args);
1708 }
1709 }
1710 });
1711 });
1712 };
1713
1714 /**
1715 * Debounce - delays function execution until after `wait` ms of inactivity.
1716 *
1717 * Each call resets the timer. Only the last call in a burst executes.
1718 *
1719 * USE CASES:
1720 * - Search inputs, form validation, window resize
1721 * - Multiple elements need independent timers
1722 * - When you need to call with different arguments
1723 *
1724 * EXAMPLES:
1725 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
1726 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
1727 *
1728 * const debouncedResize = debounce( recalculateLayout, 250 );
1729 * window.addEventListener('resize', debouncedResize);
1730 *
1731 * ⚠️ Create ONCE outside event handlers, not inside.
1732 *
1733 * @param {Function} func - Function to debounce (can be anonymous)
1734 * @param {number} wait - Milliseconds to wait (default: 500)
1735 * @return {Function} Debounced wrapper function
1736 * @since 4.3.7
1737 * @version 1.0.0
1738 */
1739 const debounce = (func, wait = 500) => {
1740 let timer;
1741 return args => {
1742 clearTimeout(timer);
1743 timer = setTimeout(() => func(args), wait);
1744 };
1745 };
1746
1747 /**
1748 * Initialize lp-toggle-enable components.
1749 *
1750 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
1751 * Reads initial state from `data-enabled` attribute ("true"/"false").
1752 * Calls `data-on-toggle` callback (if provided via options) on state change.
1753 *
1754 * HTML structure:
1755 * <label class="lp-toggle-enable" data-enabled="true">
1756 * <input type="checkbox" class="lp-toggle-enable__input" />
1757 * <span class="lp-toggle-enable__track"></span>
1758 * </label>
1759 *
1760 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
1761 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
1762 * @since 4.4.5
1763 * @version 1.0.0
1764 */
1765 window.lpToggleEnableInit = 0;
1766 const toggleEnable = (onToggle = null) => {
1767 if (window.lpToggleEnableInit) {
1768 return;
1769 }
1770 window.lpToggleEnableInit = 1;
1771 const selector = '.lp-toggle-enable';
1772 const updateUI = (toggle, isEnabled) => {
1773 toggle.classList.toggle('is-enabled', isEnabled);
1774 const input = toggle.querySelector('.lp-toggle-enable__input');
1775 if (input) {
1776 input.checked = isEnabled;
1777 input.value = isEnabled ? '1' : '0';
1778 }
1779 };
1780
1781 // Delegate click handling via eventHandlers.
1782 eventHandlers('click', [{
1783 selector,
1784 callBack: args => {
1785 const {
1786 e,
1787 target
1788 } = args;
1789 const toggle = target.closest(selector);
1790 if (!toggle || toggle.classList.contains('is-disabled')) {
1791 return;
1792 }
1793 e.preventDefault();
1794 const isEnabled = !toggle.classList.contains('is-enabled');
1795 updateUI(toggle, isEnabled);
1796 if ('function' === typeof onToggle) {
1797 onToggle(toggle, isEnabled);
1798 }
1799 }
1800 }]);
1801 };
1802
1803 /**
1804 * Initialize custom fullscreen view buttons.
1805 *
1806 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
1807 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
1808 * target element. Falls back to the button's parent element when
1809 * `data-target` is not provided.
1810 *
1811 * @since 4.4.5
1812 * @version 1.0.0
1813 */
1814 window.lpFullScreenViewInit = 0;
1815 const fullScreenView = () => {
1816 if (window.lpFullScreenViewInit) {
1817 return;
1818 }
1819 window.lpFullScreenViewInit = 1;
1820 let lastScrollY = 0;
1821 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
1822 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
1823 if (isFullscreen) {
1824 elTarget.classList.remove(lpClassName.elFullScreen);
1825 document.documentElement.classList.remove('lp-full-screen-active');
1826 window.scrollTo(0, lastScrollY);
1827 } else {
1828 lastScrollY = window.scrollY;
1829 elTarget.classList.add(lpClassName.elFullScreen);
1830 document.documentElement.classList.add('lp-full-screen-active');
1831 }
1832 if (!isFullscreen) {
1833 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
1834 const closeButton = document.createElement('button');
1835 closeButton.type = 'button';
1836 closeButton.className = lpClassName.elBtnFullScreenClose;
1837 closeButton.setAttribute('aria-label', 'Close');
1838 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
1839 closeButton.addEventListener('click', e => {
1840 e.preventDefault();
1841 lpToggleFullscreenView(elTarget);
1842 });
1843 elTarget.appendChild(closeButton);
1844 }
1845 } else {
1846 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
1847 if (closeButton) {
1848 closeButton.remove();
1849 }
1850 }
1851 };
1852 eventHandlers('click', [{
1853 selector: lpClassName.elBtnFullScreen,
1854 callBack: args => {
1855 const {
1856 e,
1857 target
1858 } = args;
1859 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
1860 if (!elBtnFullScreen) {
1861 console.log('No full screen button found');
1862 return;
1863 }
1864 e.preventDefault();
1865 let elTarget = null;
1866 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
1867 console.log(targetSelector);
1868 if (targetSelector) {
1869 elTarget = document.querySelector(targetSelector);
1870 }
1871 if (!elTarget) {
1872 console.log('No target element found');
1873 return;
1874 }
1875 lpToggleFullscreenView(elTarget, elBtnFullScreen);
1876 }
1877 }]);
1878 };
1879
1880 /***/ },
1881
1882 /***/ "./node_modules/cropperjs/dist/cropper.js"
1883 /*!************************************************!*\
1884 !*** ./node_modules/cropperjs/dist/cropper.js ***!
1885 \************************************************/
1886 (module) {
1887
1888 /*!
1889 * Cropper.js v1.6.2
1890 * https://fengyuanchen.github.io/cropperjs
1891 *
1892 * Copyright 2015-present Chen Fengyuan
1893 * Released under the MIT license
1894 *
1895 * Date: 2024-04-21T07:43:05.335Z
1896 */
1897
1898 (function (global, factory) {
1899 true ? module.exports = factory() :
1900 0;
1901 })(this, (function () { 'use strict';
1902
1903 function ownKeys(e, r) {
1904 var t = Object.keys(e);
1905 if (Object.getOwnPropertySymbols) {
1906 var o = Object.getOwnPropertySymbols(e);
1907 r && (o = o.filter(function (r) {
1908 return Object.getOwnPropertyDescriptor(e, r).enumerable;
1909 })), t.push.apply(t, o);
1910 }
1911 return t;
1912 }
1913 function _objectSpread2(e) {
1914 for (var r = 1; r < arguments.length; r++) {
1915 var t = null != arguments[r] ? arguments[r] : {};
1916 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
1917 _defineProperty(e, r, t[r]);
1918 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
1919 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
1920 });
1921 }
1922 return e;
1923 }
1924 function _toPrimitive(t, r) {
1925 if ("object" != typeof t || !t) return t;
1926 var e = t[Symbol.toPrimitive];
1927 if (void 0 !== e) {
1928 var i = e.call(t, r || "default");
1929 if ("object" != typeof i) return i;
1930 throw new TypeError("@@toPrimitive must return a primitive value.");
1931 }
1932 return ("string" === r ? String : Number)(t);
1933 }
1934 function _toPropertyKey(t) {
1935 var i = _toPrimitive(t, "string");
1936 return "symbol" == typeof i ? i : i + "";
1937 }
1938 function _typeof(o) {
1939 "@babel/helpers - typeof";
1940
1941 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
1942 return typeof o;
1943 } : function (o) {
1944 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
1945 }, _typeof(o);
1946 }
1947 function _classCallCheck(instance, Constructor) {
1948 if (!(instance instanceof Constructor)) {
1949 throw new TypeError("Cannot call a class as a function");
1950 }
1951 }
1952 function _defineProperties(target, props) {
1953 for (var i = 0; i < props.length; i++) {
1954 var descriptor = props[i];
1955 descriptor.enumerable = descriptor.enumerable || false;
1956 descriptor.configurable = true;
1957 if ("value" in descriptor) descriptor.writable = true;
1958 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
1959 }
1960 }
1961 function _createClass(Constructor, protoProps, staticProps) {
1962 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1963 if (staticProps) _defineProperties(Constructor, staticProps);
1964 Object.defineProperty(Constructor, "prototype", {
1965 writable: false
1966 });
1967 return Constructor;
1968 }
1969 function _defineProperty(obj, key, value) {
1970 key = _toPropertyKey(key);
1971 if (key in obj) {
1972 Object.defineProperty(obj, key, {
1973 value: value,
1974 enumerable: true,
1975 configurable: true,
1976 writable: true
1977 });
1978 } else {
1979 obj[key] = value;
1980 }
1981 return obj;
1982 }
1983 function _toConsumableArray(arr) {
1984 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
1985 }
1986 function _arrayWithoutHoles(arr) {
1987 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
1988 }
1989 function _iterableToArray(iter) {
1990 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1991 }
1992 function _unsupportedIterableToArray(o, minLen) {
1993 if (!o) return;
1994 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
1995 var n = Object.prototype.toString.call(o).slice(8, -1);
1996 if (n === "Object" && o.constructor) n = o.constructor.name;
1997 if (n === "Map" || n === "Set") return Array.from(o);
1998 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
1999 }
2000 function _arrayLikeToArray(arr, len) {
2001 if (len == null || len > arr.length) len = arr.length;
2002 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
2003 return arr2;
2004 }
2005 function _nonIterableSpread() {
2006 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2007 }
2008
2009 var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
2010 var WINDOW = IS_BROWSER ? window : {};
2011 var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;
2012 var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
2013 var NAMESPACE = 'cropper';
2014
2015 // Actions
2016 var ACTION_ALL = 'all';
2017 var ACTION_CROP = 'crop';
2018 var ACTION_MOVE = 'move';
2019 var ACTION_ZOOM = 'zoom';
2020 var ACTION_EAST = 'e';
2021 var ACTION_WEST = 'w';
2022 var ACTION_SOUTH = 's';
2023 var ACTION_NORTH = 'n';
2024 var ACTION_NORTH_EAST = 'ne';
2025 var ACTION_NORTH_WEST = 'nw';
2026 var ACTION_SOUTH_EAST = 'se';
2027 var ACTION_SOUTH_WEST = 'sw';
2028
2029 // Classes
2030 var CLASS_CROP = "".concat(NAMESPACE, "-crop");
2031 var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
2032 var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
2033 var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
2034 var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
2035 var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
2036 var CLASS_MOVE = "".concat(NAMESPACE, "-move");
2037
2038 // Data keys
2039 var DATA_ACTION = "".concat(NAMESPACE, "Action");
2040 var DATA_PREVIEW = "".concat(NAMESPACE, "Preview");
2041
2042 // Drag modes
2043 var DRAG_MODE_CROP = 'crop';
2044 var DRAG_MODE_MOVE = 'move';
2045 var DRAG_MODE_NONE = 'none';
2046
2047 // Events
2048 var EVENT_CROP = 'crop';
2049 var EVENT_CROP_END = 'cropend';
2050 var EVENT_CROP_MOVE = 'cropmove';
2051 var EVENT_CROP_START = 'cropstart';
2052 var EVENT_DBLCLICK = 'dblclick';
2053 var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
2054 var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
2055 var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
2056 var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
2057 var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
2058 var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
2059 var EVENT_READY = 'ready';
2060 var EVENT_RESIZE = 'resize';
2061 var EVENT_WHEEL = 'wheel';
2062 var EVENT_ZOOM = 'zoom';
2063
2064 // Mime types
2065 var MIME_TYPE_JPEG = 'image/jpeg';
2066
2067 // RegExps
2068 var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
2069 var REGEXP_DATA_URL = /^data:/;
2070 var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
2071 var REGEXP_TAG_NAME = /^img|canvas$/i;
2072
2073 // Misc
2074 // Inspired by the default width and height of a canvas element.
2075 var MIN_CONTAINER_WIDTH = 200;
2076 var MIN_CONTAINER_HEIGHT = 100;
2077
2078 var DEFAULTS = {
2079 // Define the view mode of the cropper
2080 viewMode: 0,
2081 // 0, 1, 2, 3
2082
2083 // Define the dragging mode of the cropper
2084 dragMode: DRAG_MODE_CROP,
2085 // 'crop', 'move' or 'none'
2086
2087 // Define the initial aspect ratio of the crop box
2088 initialAspectRatio: NaN,
2089 // Define the aspect ratio of the crop box
2090 aspectRatio: NaN,
2091 // An object with the previous cropping result data
2092 data: null,
2093 // A selector for adding extra containers to preview
2094 preview: '',
2095 // Re-render the cropper when resize the window
2096 responsive: true,
2097 // Restore the cropped area after resize the window
2098 restore: true,
2099 // Check if the current image is a cross-origin image
2100 checkCrossOrigin: true,
2101 // Check the current image's Exif Orientation information
2102 checkOrientation: true,
2103 // Show the black modal
2104 modal: true,
2105 // Show the dashed lines for guiding
2106 guides: true,
2107 // Show the center indicator for guiding
2108 center: true,
2109 // Show the white modal to highlight the crop box
2110 highlight: true,
2111 // Show the grid background
2112 background: true,
2113 // Enable to crop the image automatically when initialize
2114 autoCrop: true,
2115 // Define the percentage of automatic cropping area when initializes
2116 autoCropArea: 0.8,
2117 // Enable to move the image
2118 movable: true,
2119 // Enable to rotate the image
2120 rotatable: true,
2121 // Enable to scale the image
2122 scalable: true,
2123 // Enable to zoom the image
2124 zoomable: true,
2125 // Enable to zoom the image by dragging touch
2126 zoomOnTouch: true,
2127 // Enable to zoom the image by wheeling mouse
2128 zoomOnWheel: true,
2129 // Define zoom ratio when zoom the image by wheeling mouse
2130 wheelZoomRatio: 0.1,
2131 // Enable to move the crop box
2132 cropBoxMovable: true,
2133 // Enable to resize the crop box
2134 cropBoxResizable: true,
2135 // Toggle drag mode between "crop" and "move" when click twice on the cropper
2136 toggleDragModeOnDblclick: true,
2137 // Size limitation
2138 minCanvasWidth: 0,
2139 minCanvasHeight: 0,
2140 minCropBoxWidth: 0,
2141 minCropBoxHeight: 0,
2142 minContainerWidth: MIN_CONTAINER_WIDTH,
2143 minContainerHeight: MIN_CONTAINER_HEIGHT,
2144 // Shortcuts of events
2145 ready: null,
2146 cropstart: null,
2147 cropmove: null,
2148 cropend: null,
2149 crop: null,
2150 zoom: null
2151 };
2152
2153 var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
2154
2155 /**
2156 * Check if the given value is not a number.
2157 */
2158 var isNaN = Number.isNaN || WINDOW.isNaN;
2159
2160 /**
2161 * Check if the given value is a number.
2162 * @param {*} value - The value to check.
2163 * @returns {boolean} Returns `true` if the given value is a number, else `false`.
2164 */
2165 function isNumber(value) {
2166 return typeof value === 'number' && !isNaN(value);
2167 }
2168
2169 /**
2170 * Check if the given value is a positive number.
2171 * @param {*} value - The value to check.
2172 * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
2173 */
2174 var isPositiveNumber = function isPositiveNumber(value) {
2175 return value > 0 && value < Infinity;
2176 };
2177
2178 /**
2179 * Check if the given value is undefined.
2180 * @param {*} value - The value to check.
2181 * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
2182 */
2183 function isUndefined(value) {
2184 return typeof value === 'undefined';
2185 }
2186
2187 /**
2188 * Check if the given value is an object.
2189 * @param {*} value - The value to check.
2190 * @returns {boolean} Returns `true` if the given value is an object, else `false`.
2191 */
2192 function isObject(value) {
2193 return _typeof(value) === 'object' && value !== null;
2194 }
2195 var hasOwnProperty = Object.prototype.hasOwnProperty;
2196
2197 /**
2198 * Check if the given value is a plain object.
2199 * @param {*} value - The value to check.
2200 * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
2201 */
2202 function isPlainObject(value) {
2203 if (!isObject(value)) {
2204 return false;
2205 }
2206 try {
2207 var _constructor = value.constructor;
2208 var prototype = _constructor.prototype;
2209 return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
2210 } catch (error) {
2211 return false;
2212 }
2213 }
2214
2215 /**
2216 * Check if the given value is a function.
2217 * @param {*} value - The value to check.
2218 * @returns {boolean} Returns `true` if the given value is a function, else `false`.
2219 */
2220 function isFunction(value) {
2221 return typeof value === 'function';
2222 }
2223 var slice = Array.prototype.slice;
2224
2225 /**
2226 * Convert array-like or iterable object to an array.
2227 * @param {*} value - The value to convert.
2228 * @returns {Array} Returns a new array.
2229 */
2230 function toArray(value) {
2231 return Array.from ? Array.from(value) : slice.call(value);
2232 }
2233
2234 /**
2235 * Iterate the given data.
2236 * @param {*} data - The data to iterate.
2237 * @param {Function} callback - The process function for each element.
2238 * @returns {*} The original data.
2239 */
2240 function forEach(data, callback) {
2241 if (data && isFunction(callback)) {
2242 if (Array.isArray(data) || isNumber(data.length) /* array-like */) {
2243 toArray(data).forEach(function (value, key) {
2244 callback.call(data, value, key, data);
2245 });
2246 } else if (isObject(data)) {
2247 Object.keys(data).forEach(function (key) {
2248 callback.call(data, data[key], key, data);
2249 });
2250 }
2251 }
2252 return data;
2253 }
2254
2255 /**
2256 * Extend the given object.
2257 * @param {*} target - The target object to extend.
2258 * @param {*} args - The rest objects for merging to the target object.
2259 * @returns {Object} The extended object.
2260 */
2261 var assign = Object.assign || function assign(target) {
2262 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2263 args[_key - 1] = arguments[_key];
2264 }
2265 if (isObject(target) && args.length > 0) {
2266 args.forEach(function (arg) {
2267 if (isObject(arg)) {
2268 Object.keys(arg).forEach(function (key) {
2269 target[key] = arg[key];
2270 });
2271 }
2272 });
2273 }
2274 return target;
2275 };
2276 var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
2277
2278 /**
2279 * Normalize decimal number.
2280 * Check out {@link https://0.30000000000000004.com/}
2281 * @param {number} value - The value to normalize.
2282 * @param {number} [times=100000000000] - The times for normalizing.
2283 * @returns {number} Returns the normalized number.
2284 */
2285 function normalizeDecimalNumber(value) {
2286 var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
2287 return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
2288 }
2289 var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
2290
2291 /**
2292 * Apply styles to the given element.
2293 * @param {Element} element - The target element.
2294 * @param {Object} styles - The styles for applying.
2295 */
2296 function setStyle(element, styles) {
2297 var style = element.style;
2298 forEach(styles, function (value, property) {
2299 if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
2300 value = "".concat(value, "px");
2301 }
2302 style[property] = value;
2303 });
2304 }
2305
2306 /**
2307 * Check if the given element has a special class.
2308 * @param {Element} element - The element to check.
2309 * @param {string} value - The class to search.
2310 * @returns {boolean} Returns `true` if the special class was found.
2311 */
2312 function hasClass(element, value) {
2313 return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
2314 }
2315
2316 /**
2317 * Add classes to the given element.
2318 * @param {Element} element - The target element.
2319 * @param {string} value - The classes to be added.
2320 */
2321 function addClass(element, value) {
2322 if (!value) {
2323 return;
2324 }
2325 if (isNumber(element.length)) {
2326 forEach(element, function (elem) {
2327 addClass(elem, value);
2328 });
2329 return;
2330 }
2331 if (element.classList) {
2332 element.classList.add(value);
2333 return;
2334 }
2335 var className = element.className.trim();
2336 if (!className) {
2337 element.className = value;
2338 } else if (className.indexOf(value) < 0) {
2339 element.className = "".concat(className, " ").concat(value);
2340 }
2341 }
2342
2343 /**
2344 * Remove classes from the given element.
2345 * @param {Element} element - The target element.
2346 * @param {string} value - The classes to be removed.
2347 */
2348 function removeClass(element, value) {
2349 if (!value) {
2350 return;
2351 }
2352 if (isNumber(element.length)) {
2353 forEach(element, function (elem) {
2354 removeClass(elem, value);
2355 });
2356 return;
2357 }
2358 if (element.classList) {
2359 element.classList.remove(value);
2360 return;
2361 }
2362 if (element.className.indexOf(value) >= 0) {
2363 element.className = element.className.replace(value, '');
2364 }
2365 }
2366
2367 /**
2368 * Add or remove classes from the given element.
2369 * @param {Element} element - The target element.
2370 * @param {string} value - The classes to be toggled.
2371 * @param {boolean} added - Add only.
2372 */
2373 function toggleClass(element, value, added) {
2374 if (!value) {
2375 return;
2376 }
2377 if (isNumber(element.length)) {
2378 forEach(element, function (elem) {
2379 toggleClass(elem, value, added);
2380 });
2381 return;
2382 }
2383
2384 // IE10-11 doesn't support the second parameter of `classList.toggle`
2385 if (added) {
2386 addClass(element, value);
2387 } else {
2388 removeClass(element, value);
2389 }
2390 }
2391 var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
2392
2393 /**
2394 * Transform the given string from camelCase to kebab-case
2395 * @param {string} value - The value to transform.
2396 * @returns {string} The transformed value.
2397 */
2398 function toParamCase(value) {
2399 return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
2400 }
2401
2402 /**
2403 * Get data from the given element.
2404 * @param {Element} element - The target element.
2405 * @param {string} name - The data key to get.
2406 * @returns {string} The data value.
2407 */
2408 function getData(element, name) {
2409 if (isObject(element[name])) {
2410 return element[name];
2411 }
2412 if (element.dataset) {
2413 return element.dataset[name];
2414 }
2415 return element.getAttribute("data-".concat(toParamCase(name)));
2416 }
2417
2418 /**
2419 * Set data to the given element.
2420 * @param {Element} element - The target element.
2421 * @param {string} name - The data key to set.
2422 * @param {string} data - The data value.
2423 */
2424 function setData(element, name, data) {
2425 if (isObject(data)) {
2426 element[name] = data;
2427 } else if (element.dataset) {
2428 element.dataset[name] = data;
2429 } else {
2430 element.setAttribute("data-".concat(toParamCase(name)), data);
2431 }
2432 }
2433
2434 /**
2435 * Remove data from the given element.
2436 * @param {Element} element - The target element.
2437 * @param {string} name - The data key to remove.
2438 */
2439 function removeData(element, name) {
2440 if (isObject(element[name])) {
2441 try {
2442 delete element[name];
2443 } catch (error) {
2444 element[name] = undefined;
2445 }
2446 } else if (element.dataset) {
2447 // #128 Safari not allows to delete dataset property
2448 try {
2449 delete element.dataset[name];
2450 } catch (error) {
2451 element.dataset[name] = undefined;
2452 }
2453 } else {
2454 element.removeAttribute("data-".concat(toParamCase(name)));
2455 }
2456 }
2457 var REGEXP_SPACES = /\s\s*/;
2458 var onceSupported = function () {
2459 var supported = false;
2460 if (IS_BROWSER) {
2461 var once = false;
2462 var listener = function listener() {};
2463 var options = Object.defineProperty({}, 'once', {
2464 get: function get() {
2465 supported = true;
2466 return once;
2467 },
2468 /**
2469 * This setter can fix a `TypeError` in strict mode
2470 * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
2471 * @param {boolean} value - The value to set
2472 */
2473 set: function set(value) {
2474 once = value;
2475 }
2476 });
2477 WINDOW.addEventListener('test', listener, options);
2478 WINDOW.removeEventListener('test', listener, options);
2479 }
2480 return supported;
2481 }();
2482
2483 /**
2484 * Remove event listener from the target element.
2485 * @param {Element} element - The event target.
2486 * @param {string} type - The event type(s).
2487 * @param {Function} listener - The event listener.
2488 * @param {Object} options - The event options.
2489 */
2490 function removeListener(element, type, listener) {
2491 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
2492 var handler = listener;
2493 type.trim().split(REGEXP_SPACES).forEach(function (event) {
2494 if (!onceSupported) {
2495 var listeners = element.listeners;
2496 if (listeners && listeners[event] && listeners[event][listener]) {
2497 handler = listeners[event][listener];
2498 delete listeners[event][listener];
2499 if (Object.keys(listeners[event]).length === 0) {
2500 delete listeners[event];
2501 }
2502 if (Object.keys(listeners).length === 0) {
2503 delete element.listeners;
2504 }
2505 }
2506 }
2507 element.removeEventListener(event, handler, options);
2508 });
2509 }
2510
2511 /**
2512 * Add event listener to the target element.
2513 * @param {Element} element - The event target.
2514 * @param {string} type - The event type(s).
2515 * @param {Function} listener - The event listener.
2516 * @param {Object} options - The event options.
2517 */
2518 function addListener(element, type, listener) {
2519 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
2520 var _handler = listener;
2521 type.trim().split(REGEXP_SPACES).forEach(function (event) {
2522 if (options.once && !onceSupported) {
2523 var _element$listeners = element.listeners,
2524 listeners = _element$listeners === void 0 ? {} : _element$listeners;
2525 _handler = function handler() {
2526 delete listeners[event][listener];
2527 element.removeEventListener(event, _handler, options);
2528 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2529 args[_key2] = arguments[_key2];
2530 }
2531 listener.apply(element, args);
2532 };
2533 if (!listeners[event]) {
2534 listeners[event] = {};
2535 }
2536 if (listeners[event][listener]) {
2537 element.removeEventListener(event, listeners[event][listener], options);
2538 }
2539 listeners[event][listener] = _handler;
2540 element.listeners = listeners;
2541 }
2542 element.addEventListener(event, _handler, options);
2543 });
2544 }
2545
2546 /**
2547 * Dispatch event on the target element.
2548 * @param {Element} element - The event target.
2549 * @param {string} type - The event type(s).
2550 * @param {Object} data - The additional event data.
2551 * @returns {boolean} Indicate if the event is default prevented or not.
2552 */
2553 function dispatchEvent(element, type, data) {
2554 var event;
2555
2556 // Event and CustomEvent on IE9-11 are global objects, not constructors
2557 if (isFunction(Event) && isFunction(CustomEvent)) {
2558 event = new CustomEvent(type, {
2559 detail: data,
2560 bubbles: true,
2561 cancelable: true
2562 });
2563 } else {
2564 event = document.createEvent('CustomEvent');
2565 event.initCustomEvent(type, true, true, data);
2566 }
2567 return element.dispatchEvent(event);
2568 }
2569
2570 /**
2571 * Get the offset base on the document.
2572 * @param {Element} element - The target element.
2573 * @returns {Object} The offset data.
2574 */
2575 function getOffset(element) {
2576 var box = element.getBoundingClientRect();
2577 return {
2578 left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
2579 top: box.top + (window.pageYOffset - document.documentElement.clientTop)
2580 };
2581 }
2582 var location = WINDOW.location;
2583 var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
2584
2585 /**
2586 * Check if the given URL is a cross origin URL.
2587 * @param {string} url - The target URL.
2588 * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
2589 */
2590 function isCrossOriginURL(url) {
2591 var parts = url.match(REGEXP_ORIGINS);
2592 return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
2593 }
2594
2595 /**
2596 * Add timestamp to the given URL.
2597 * @param {string} url - The target URL.
2598 * @returns {string} The result URL.
2599 */
2600 function addTimestamp(url) {
2601 var timestamp = "timestamp=".concat(new Date().getTime());
2602 return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
2603 }
2604
2605 /**
2606 * Get transforms base on the given object.
2607 * @param {Object} obj - The target object.
2608 * @returns {string} A string contains transform values.
2609 */
2610 function getTransforms(_ref) {
2611 var rotate = _ref.rotate,
2612 scaleX = _ref.scaleX,
2613 scaleY = _ref.scaleY,
2614 translateX = _ref.translateX,
2615 translateY = _ref.translateY;
2616 var values = [];
2617 if (isNumber(translateX) && translateX !== 0) {
2618 values.push("translateX(".concat(translateX, "px)"));
2619 }
2620 if (isNumber(translateY) && translateY !== 0) {
2621 values.push("translateY(".concat(translateY, "px)"));
2622 }
2623
2624 // Rotate should come first before scale to match orientation transform
2625 if (isNumber(rotate) && rotate !== 0) {
2626 values.push("rotate(".concat(rotate, "deg)"));
2627 }
2628 if (isNumber(scaleX) && scaleX !== 1) {
2629 values.push("scaleX(".concat(scaleX, ")"));
2630 }
2631 if (isNumber(scaleY) && scaleY !== 1) {
2632 values.push("scaleY(".concat(scaleY, ")"));
2633 }
2634 var transform = values.length ? values.join(' ') : 'none';
2635 return {
2636 WebkitTransform: transform,
2637 msTransform: transform,
2638 transform: transform
2639 };
2640 }
2641
2642 /**
2643 * Get the max ratio of a group of pointers.
2644 * @param {string} pointers - The target pointers.
2645 * @returns {number} The result ratio.
2646 */
2647 function getMaxZoomRatio(pointers) {
2648 var pointers2 = _objectSpread2({}, pointers);
2649 var maxRatio = 0;
2650 forEach(pointers, function (pointer, pointerId) {
2651 delete pointers2[pointerId];
2652 forEach(pointers2, function (pointer2) {
2653 var x1 = Math.abs(pointer.startX - pointer2.startX);
2654 var y1 = Math.abs(pointer.startY - pointer2.startY);
2655 var x2 = Math.abs(pointer.endX - pointer2.endX);
2656 var y2 = Math.abs(pointer.endY - pointer2.endY);
2657 var z1 = Math.sqrt(x1 * x1 + y1 * y1);
2658 var z2 = Math.sqrt(x2 * x2 + y2 * y2);
2659 var ratio = (z2 - z1) / z1;
2660 if (Math.abs(ratio) > Math.abs(maxRatio)) {
2661 maxRatio = ratio;
2662 }
2663 });
2664 });
2665 return maxRatio;
2666 }
2667
2668 /**
2669 * Get a pointer from an event object.
2670 * @param {Object} event - The target event object.
2671 * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
2672 * @returns {Object} The result pointer contains start and/or end point coordinates.
2673 */
2674 function getPointer(_ref2, endOnly) {
2675 var pageX = _ref2.pageX,
2676 pageY = _ref2.pageY;
2677 var end = {
2678 endX: pageX,
2679 endY: pageY
2680 };
2681 return endOnly ? end : _objectSpread2({
2682 startX: pageX,
2683 startY: pageY
2684 }, end);
2685 }
2686
2687 /**
2688 * Get the center point coordinate of a group of pointers.
2689 * @param {Object} pointers - The target pointers.
2690 * @returns {Object} The center point coordinate.
2691 */
2692 function getPointersCenter(pointers) {
2693 var pageX = 0;
2694 var pageY = 0;
2695 var count = 0;
2696 forEach(pointers, function (_ref3) {
2697 var startX = _ref3.startX,
2698 startY = _ref3.startY;
2699 pageX += startX;
2700 pageY += startY;
2701 count += 1;
2702 });
2703 pageX /= count;
2704 pageY /= count;
2705 return {
2706 pageX: pageX,
2707 pageY: pageY
2708 };
2709 }
2710
2711 /**
2712 * Get the max sizes in a rectangle under the given aspect ratio.
2713 * @param {Object} data - The original sizes.
2714 * @param {string} [type='contain'] - The adjust type.
2715 * @returns {Object} The result sizes.
2716 */
2717 function getAdjustedSizes(_ref4) {
2718 var aspectRatio = _ref4.aspectRatio,
2719 height = _ref4.height,
2720 width = _ref4.width;
2721 var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
2722 var isValidWidth = isPositiveNumber(width);
2723 var isValidHeight = isPositiveNumber(height);
2724 if (isValidWidth && isValidHeight) {
2725 var adjustedWidth = height * aspectRatio;
2726 if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
2727 height = width / aspectRatio;
2728 } else {
2729 width = height * aspectRatio;
2730 }
2731 } else if (isValidWidth) {
2732 height = width / aspectRatio;
2733 } else if (isValidHeight) {
2734 width = height * aspectRatio;
2735 }
2736 return {
2737 width: width,
2738 height: height
2739 };
2740 }
2741
2742 /**
2743 * Get the new sizes of a rectangle after rotated.
2744 * @param {Object} data - The original sizes.
2745 * @returns {Object} The result sizes.
2746 */
2747 function getRotatedSizes(_ref5) {
2748 var width = _ref5.width,
2749 height = _ref5.height,
2750 degree = _ref5.degree;
2751 degree = Math.abs(degree) % 180;
2752 if (degree === 90) {
2753 return {
2754 width: height,
2755 height: width
2756 };
2757 }
2758 var arc = degree % 90 * Math.PI / 180;
2759 var sinArc = Math.sin(arc);
2760 var cosArc = Math.cos(arc);
2761 var newWidth = width * cosArc + height * sinArc;
2762 var newHeight = width * sinArc + height * cosArc;
2763 return degree > 90 ? {
2764 width: newHeight,
2765 height: newWidth
2766 } : {
2767 width: newWidth,
2768 height: newHeight
2769 };
2770 }
2771
2772 /**
2773 * Get a canvas which drew the given image.
2774 * @param {HTMLImageElement} image - The image for drawing.
2775 * @param {Object} imageData - The image data.
2776 * @param {Object} canvasData - The canvas data.
2777 * @param {Object} options - The options.
2778 * @returns {HTMLCanvasElement} The result canvas.
2779 */
2780 function getSourceCanvas(image, _ref6, _ref7, _ref8) {
2781 var imageAspectRatio = _ref6.aspectRatio,
2782 imageNaturalWidth = _ref6.naturalWidth,
2783 imageNaturalHeight = _ref6.naturalHeight,
2784 _ref6$rotate = _ref6.rotate,
2785 rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
2786 _ref6$scaleX = _ref6.scaleX,
2787 scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
2788 _ref6$scaleY = _ref6.scaleY,
2789 scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
2790 var aspectRatio = _ref7.aspectRatio,
2791 naturalWidth = _ref7.naturalWidth,
2792 naturalHeight = _ref7.naturalHeight;
2793 var _ref8$fillColor = _ref8.fillColor,
2794 fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
2795 _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
2796 imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
2797 _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
2798 imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
2799 _ref8$maxWidth = _ref8.maxWidth,
2800 maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
2801 _ref8$maxHeight = _ref8.maxHeight,
2802 maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
2803 _ref8$minWidth = _ref8.minWidth,
2804 minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
2805 _ref8$minHeight = _ref8.minHeight,
2806 minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
2807 var canvas = document.createElement('canvas');
2808 var context = canvas.getContext('2d');
2809 var maxSizes = getAdjustedSizes({
2810 aspectRatio: aspectRatio,
2811 width: maxWidth,
2812 height: maxHeight
2813 });
2814 var minSizes = getAdjustedSizes({
2815 aspectRatio: aspectRatio,
2816 width: minWidth,
2817 height: minHeight
2818 }, 'cover');
2819 var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
2820 var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
2821
2822 // Note: should always use image's natural sizes for drawing as
2823 // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
2824 var destMaxSizes = getAdjustedSizes({
2825 aspectRatio: imageAspectRatio,
2826 width: maxWidth,
2827 height: maxHeight
2828 });
2829 var destMinSizes = getAdjustedSizes({
2830 aspectRatio: imageAspectRatio,
2831 width: minWidth,
2832 height: minHeight
2833 }, 'cover');
2834 var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
2835 var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
2836 var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
2837 canvas.width = normalizeDecimalNumber(width);
2838 canvas.height = normalizeDecimalNumber(height);
2839 context.fillStyle = fillColor;
2840 context.fillRect(0, 0, width, height);
2841 context.save();
2842 context.translate(width / 2, height / 2);
2843 context.rotate(rotate * Math.PI / 180);
2844 context.scale(scaleX, scaleY);
2845 context.imageSmoothingEnabled = imageSmoothingEnabled;
2846 context.imageSmoothingQuality = imageSmoothingQuality;
2847 context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
2848 return Math.floor(normalizeDecimalNumber(param));
2849 }))));
2850 context.restore();
2851 return canvas;
2852 }
2853 var fromCharCode = String.fromCharCode;
2854
2855 /**
2856 * Get string from char code in data view.
2857 * @param {DataView} dataView - The data view for read.
2858 * @param {number} start - The start index.
2859 * @param {number} length - The read length.
2860 * @returns {string} The read result.
2861 */
2862 function getStringFromCharCode(dataView, start, length) {
2863 var str = '';
2864 length += start;
2865 for (var i = start; i < length; i += 1) {
2866 str += fromCharCode(dataView.getUint8(i));
2867 }
2868 return str;
2869 }
2870 var REGEXP_DATA_URL_HEAD = /^data:.*,/;
2871
2872 /**
2873 * Transform Data URL to array buffer.
2874 * @param {string} dataURL - The Data URL to transform.
2875 * @returns {ArrayBuffer} The result array buffer.
2876 */
2877 function dataURLToArrayBuffer(dataURL) {
2878 var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
2879 var binary = atob(base64);
2880 var arrayBuffer = new ArrayBuffer(binary.length);
2881 var uint8 = new Uint8Array(arrayBuffer);
2882 forEach(uint8, function (value, i) {
2883 uint8[i] = binary.charCodeAt(i);
2884 });
2885 return arrayBuffer;
2886 }
2887
2888 /**
2889 * Transform array buffer to Data URL.
2890 * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
2891 * @param {string} mimeType - The mime type of the Data URL.
2892 * @returns {string} The result Data URL.
2893 */
2894 function arrayBufferToDataURL(arrayBuffer, mimeType) {
2895 var chunks = [];
2896
2897 // Chunk Typed Array for better performance (#435)
2898 var chunkSize = 8192;
2899 var uint8 = new Uint8Array(arrayBuffer);
2900 while (uint8.length > 0) {
2901 // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
2902 // eslint-disable-next-line prefer-spread
2903 chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
2904 uint8 = uint8.subarray(chunkSize);
2905 }
2906 return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
2907 }
2908
2909 /**
2910 * Get orientation value from given array buffer.
2911 * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
2912 * @returns {number} The read orientation value.
2913 */
2914 function resetAndGetOrientation(arrayBuffer) {
2915 var dataView = new DataView(arrayBuffer);
2916 var orientation;
2917
2918 // Ignores range error when the image does not have correct Exif information
2919 try {
2920 var littleEndian;
2921 var app1Start;
2922 var ifdStart;
2923
2924 // Only handle JPEG image (start by 0xFFD8)
2925 if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
2926 var length = dataView.byteLength;
2927 var offset = 2;
2928 while (offset + 1 < length) {
2929 if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
2930 app1Start = offset;
2931 break;
2932 }
2933 offset += 1;
2934 }
2935 }
2936 if (app1Start) {
2937 var exifIDCode = app1Start + 4;
2938 var tiffOffset = app1Start + 10;
2939 if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
2940 var endianness = dataView.getUint16(tiffOffset);
2941 littleEndian = endianness === 0x4949;
2942 if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
2943 if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
2944 var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
2945 if (firstIFDOffset >= 0x00000008) {
2946 ifdStart = tiffOffset + firstIFDOffset;
2947 }
2948 }
2949 }
2950 }
2951 }
2952 if (ifdStart) {
2953 var _length = dataView.getUint16(ifdStart, littleEndian);
2954 var _offset;
2955 var i;
2956 for (i = 0; i < _length; i += 1) {
2957 _offset = ifdStart + i * 12 + 2;
2958 if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
2959 // 8 is the offset of the current tag's value
2960 _offset += 8;
2961
2962 // Get the original orientation value
2963 orientation = dataView.getUint16(_offset, littleEndian);
2964
2965 // Override the orientation with its default value
2966 dataView.setUint16(_offset, 1, littleEndian);
2967 break;
2968 }
2969 }
2970 }
2971 } catch (error) {
2972 orientation = 1;
2973 }
2974 return orientation;
2975 }
2976
2977 /**
2978 * Parse Exif Orientation value.
2979 * @param {number} orientation - The orientation to parse.
2980 * @returns {Object} The parsed result.
2981 */
2982 function parseOrientation(orientation) {
2983 var rotate = 0;
2984 var scaleX = 1;
2985 var scaleY = 1;
2986 switch (orientation) {
2987 // Flip horizontal
2988 case 2:
2989 scaleX = -1;
2990 break;
2991
2992 // Rotate left 180°
2993 case 3:
2994 rotate = -180;
2995 break;
2996
2997 // Flip vertical
2998 case 4:
2999 scaleY = -1;
3000 break;
3001
3002 // Flip vertical and rotate right 90°
3003 case 5:
3004 rotate = 90;
3005 scaleY = -1;
3006 break;
3007
3008 // Rotate right 90°
3009 case 6:
3010 rotate = 90;
3011 break;
3012
3013 // Flip horizontal and rotate right 90°
3014 case 7:
3015 rotate = 90;
3016 scaleX = -1;
3017 break;
3018
3019 // Rotate left 90°
3020 case 8:
3021 rotate = -90;
3022 break;
3023 }
3024 return {
3025 rotate: rotate,
3026 scaleX: scaleX,
3027 scaleY: scaleY
3028 };
3029 }
3030
3031 var render = {
3032 render: function render() {
3033 this.initContainer();
3034 this.initCanvas();
3035 this.initCropBox();
3036 this.renderCanvas();
3037 if (this.cropped) {
3038 this.renderCropBox();
3039 }
3040 },
3041 initContainer: function initContainer() {
3042 var element = this.element,
3043 options = this.options,
3044 container = this.container,
3045 cropper = this.cropper;
3046 var minWidth = Number(options.minContainerWidth);
3047 var minHeight = Number(options.minContainerHeight);
3048 addClass(cropper, CLASS_HIDDEN);
3049 removeClass(element, CLASS_HIDDEN);
3050 var containerData = {
3051 width: Math.max(container.offsetWidth, minWidth >= 0 ? minWidth : MIN_CONTAINER_WIDTH),
3052 height: Math.max(container.offsetHeight, minHeight >= 0 ? minHeight : MIN_CONTAINER_HEIGHT)
3053 };
3054 this.containerData = containerData;
3055 setStyle(cropper, {
3056 width: containerData.width,
3057 height: containerData.height
3058 });
3059 addClass(element, CLASS_HIDDEN);
3060 removeClass(cropper, CLASS_HIDDEN);
3061 },
3062 // Canvas (image wrapper)
3063 initCanvas: function initCanvas() {
3064 var containerData = this.containerData,
3065 imageData = this.imageData;
3066 var viewMode = this.options.viewMode;
3067 var rotated = Math.abs(imageData.rotate) % 180 === 90;
3068 var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
3069 var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
3070 var aspectRatio = naturalWidth / naturalHeight;
3071 var canvasWidth = containerData.width;
3072 var canvasHeight = containerData.height;
3073 if (containerData.height * aspectRatio > containerData.width) {
3074 if (viewMode === 3) {
3075 canvasWidth = containerData.height * aspectRatio;
3076 } else {
3077 canvasHeight = containerData.width / aspectRatio;
3078 }
3079 } else if (viewMode === 3) {
3080 canvasHeight = containerData.width / aspectRatio;
3081 } else {
3082 canvasWidth = containerData.height * aspectRatio;
3083 }
3084 var canvasData = {
3085 aspectRatio: aspectRatio,
3086 naturalWidth: naturalWidth,
3087 naturalHeight: naturalHeight,
3088 width: canvasWidth,
3089 height: canvasHeight
3090 };
3091 this.canvasData = canvasData;
3092 this.limited = viewMode === 1 || viewMode === 2;
3093 this.limitCanvas(true, true);
3094 canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
3095 canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
3096 canvasData.left = (containerData.width - canvasData.width) / 2;
3097 canvasData.top = (containerData.height - canvasData.height) / 2;
3098 canvasData.oldLeft = canvasData.left;
3099 canvasData.oldTop = canvasData.top;
3100 this.initialCanvasData = assign({}, canvasData);
3101 },
3102 limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
3103 var options = this.options,
3104 containerData = this.containerData,
3105 canvasData = this.canvasData,
3106 cropBoxData = this.cropBoxData;
3107 var viewMode = options.viewMode;
3108 var aspectRatio = canvasData.aspectRatio;
3109 var cropped = this.cropped && cropBoxData;
3110 if (sizeLimited) {
3111 var minCanvasWidth = Number(options.minCanvasWidth) || 0;
3112 var minCanvasHeight = Number(options.minCanvasHeight) || 0;
3113 if (viewMode > 1) {
3114 minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
3115 minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
3116 if (viewMode === 3) {
3117 if (minCanvasHeight * aspectRatio > minCanvasWidth) {
3118 minCanvasWidth = minCanvasHeight * aspectRatio;
3119 } else {
3120 minCanvasHeight = minCanvasWidth / aspectRatio;
3121 }
3122 }
3123 } else if (viewMode > 0) {
3124 if (minCanvasWidth) {
3125 minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
3126 } else if (minCanvasHeight) {
3127 minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
3128 } else if (cropped) {
3129 minCanvasWidth = cropBoxData.width;
3130 minCanvasHeight = cropBoxData.height;
3131 if (minCanvasHeight * aspectRatio > minCanvasWidth) {
3132 minCanvasWidth = minCanvasHeight * aspectRatio;
3133 } else {
3134 minCanvasHeight = minCanvasWidth / aspectRatio;
3135 }
3136 }
3137 }
3138 var _getAdjustedSizes = getAdjustedSizes({
3139 aspectRatio: aspectRatio,
3140 width: minCanvasWidth,
3141 height: minCanvasHeight
3142 });
3143 minCanvasWidth = _getAdjustedSizes.width;
3144 minCanvasHeight = _getAdjustedSizes.height;
3145 canvasData.minWidth = minCanvasWidth;
3146 canvasData.minHeight = minCanvasHeight;
3147 canvasData.maxWidth = Infinity;
3148 canvasData.maxHeight = Infinity;
3149 }
3150 if (positionLimited) {
3151 if (viewMode > (cropped ? 0 : 1)) {
3152 var newCanvasLeft = containerData.width - canvasData.width;
3153 var newCanvasTop = containerData.height - canvasData.height;
3154 canvasData.minLeft = Math.min(0, newCanvasLeft);
3155 canvasData.minTop = Math.min(0, newCanvasTop);
3156 canvasData.maxLeft = Math.max(0, newCanvasLeft);
3157 canvasData.maxTop = Math.max(0, newCanvasTop);
3158 if (cropped && this.limited) {
3159 canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
3160 canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
3161 canvasData.maxLeft = cropBoxData.left;
3162 canvasData.maxTop = cropBoxData.top;
3163 if (viewMode === 2) {
3164 if (canvasData.width >= containerData.width) {
3165 canvasData.minLeft = Math.min(0, newCanvasLeft);
3166 canvasData.maxLeft = Math.max(0, newCanvasLeft);
3167 }
3168 if (canvasData.height >= containerData.height) {
3169 canvasData.minTop = Math.min(0, newCanvasTop);
3170 canvasData.maxTop = Math.max(0, newCanvasTop);
3171 }
3172 }
3173 }
3174 } else {
3175 canvasData.minLeft = -canvasData.width;
3176 canvasData.minTop = -canvasData.height;
3177 canvasData.maxLeft = containerData.width;
3178 canvasData.maxTop = containerData.height;
3179 }
3180 }
3181 },
3182 renderCanvas: function renderCanvas(changed, transformed) {
3183 var canvasData = this.canvasData,
3184 imageData = this.imageData;
3185 if (transformed) {
3186 var _getRotatedSizes = getRotatedSizes({
3187 width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
3188 height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
3189 degree: imageData.rotate || 0
3190 }),
3191 naturalWidth = _getRotatedSizes.width,
3192 naturalHeight = _getRotatedSizes.height;
3193 var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
3194 var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
3195 canvasData.left -= (width - canvasData.width) / 2;
3196 canvasData.top -= (height - canvasData.height) / 2;
3197 canvasData.width = width;
3198 canvasData.height = height;
3199 canvasData.aspectRatio = naturalWidth / naturalHeight;
3200 canvasData.naturalWidth = naturalWidth;
3201 canvasData.naturalHeight = naturalHeight;
3202 this.limitCanvas(true, false);
3203 }
3204 if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
3205 canvasData.left = canvasData.oldLeft;
3206 }
3207 if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
3208 canvasData.top = canvasData.oldTop;
3209 }
3210 canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
3211 canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
3212 this.limitCanvas(false, true);
3213 canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
3214 canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
3215 canvasData.oldLeft = canvasData.left;
3216 canvasData.oldTop = canvasData.top;
3217 setStyle(this.canvas, assign({
3218 width: canvasData.width,
3219 height: canvasData.height
3220 }, getTransforms({
3221 translateX: canvasData.left,
3222 translateY: canvasData.top
3223 })));
3224 this.renderImage(changed);
3225 if (this.cropped && this.limited) {
3226 this.limitCropBox(true, true);
3227 }
3228 },
3229 renderImage: function renderImage(changed) {
3230 var canvasData = this.canvasData,
3231 imageData = this.imageData;
3232 var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
3233 var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
3234 assign(imageData, {
3235 width: width,
3236 height: height,
3237 left: (canvasData.width - width) / 2,
3238 top: (canvasData.height - height) / 2
3239 });
3240 setStyle(this.image, assign({
3241 width: imageData.width,
3242 height: imageData.height
3243 }, getTransforms(assign({
3244 translateX: imageData.left,
3245 translateY: imageData.top
3246 }, imageData))));
3247 if (changed) {
3248 this.output();
3249 }
3250 },
3251 initCropBox: function initCropBox() {
3252 var options = this.options,
3253 canvasData = this.canvasData;
3254 var aspectRatio = options.aspectRatio || options.initialAspectRatio;
3255 var autoCropArea = Number(options.autoCropArea) || 0.8;
3256 var cropBoxData = {
3257 width: canvasData.width,
3258 height: canvasData.height
3259 };
3260 if (aspectRatio) {
3261 if (canvasData.height * aspectRatio > canvasData.width) {
3262 cropBoxData.height = cropBoxData.width / aspectRatio;
3263 } else {
3264 cropBoxData.width = cropBoxData.height * aspectRatio;
3265 }
3266 }
3267 this.cropBoxData = cropBoxData;
3268 this.limitCropBox(true, true);
3269
3270 // Initialize auto crop area
3271 cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
3272 cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
3273
3274 // The width/height of auto crop area must large than "minWidth/Height"
3275 cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
3276 cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
3277 cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
3278 cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
3279 cropBoxData.oldLeft = cropBoxData.left;
3280 cropBoxData.oldTop = cropBoxData.top;
3281 this.initialCropBoxData = assign({}, cropBoxData);
3282 },
3283 limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
3284 var options = this.options,
3285 containerData = this.containerData,
3286 canvasData = this.canvasData,
3287 cropBoxData = this.cropBoxData,
3288 limited = this.limited;
3289 var aspectRatio = options.aspectRatio;
3290 if (sizeLimited) {
3291 var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
3292 var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
3293 var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
3294 var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height;
3295
3296 // The min/maxCropBoxWidth/Height must be less than container's width/height
3297 minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
3298 minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
3299 if (aspectRatio) {
3300 if (minCropBoxWidth && minCropBoxHeight) {
3301 if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
3302 minCropBoxHeight = minCropBoxWidth / aspectRatio;
3303 } else {
3304 minCropBoxWidth = minCropBoxHeight * aspectRatio;
3305 }
3306 } else if (minCropBoxWidth) {
3307 minCropBoxHeight = minCropBoxWidth / aspectRatio;
3308 } else if (minCropBoxHeight) {
3309 minCropBoxWidth = minCropBoxHeight * aspectRatio;
3310 }
3311 if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
3312 maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
3313 } else {
3314 maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
3315 }
3316 }
3317
3318 // The minWidth/Height must be less than maxWidth/Height
3319 cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
3320 cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
3321 cropBoxData.maxWidth = maxCropBoxWidth;
3322 cropBoxData.maxHeight = maxCropBoxHeight;
3323 }
3324 if (positionLimited) {
3325 if (limited) {
3326 cropBoxData.minLeft = Math.max(0, canvasData.left);
3327 cropBoxData.minTop = Math.max(0, canvasData.top);
3328 cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
3329 cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
3330 } else {
3331 cropBoxData.minLeft = 0;
3332 cropBoxData.minTop = 0;
3333 cropBoxData.maxLeft = containerData.width - cropBoxData.width;
3334 cropBoxData.maxTop = containerData.height - cropBoxData.height;
3335 }
3336 }
3337 },
3338 renderCropBox: function renderCropBox() {
3339 var options = this.options,
3340 containerData = this.containerData,
3341 cropBoxData = this.cropBoxData;
3342 if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
3343 cropBoxData.left = cropBoxData.oldLeft;
3344 }
3345 if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
3346 cropBoxData.top = cropBoxData.oldTop;
3347 }
3348 cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
3349 cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
3350 this.limitCropBox(false, true);
3351 cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
3352 cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
3353 cropBoxData.oldLeft = cropBoxData.left;
3354 cropBoxData.oldTop = cropBoxData.top;
3355 if (options.movable && options.cropBoxMovable) {
3356 // Turn to move the canvas when the crop box is equal to the container
3357 setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
3358 }
3359 setStyle(this.cropBox, assign({
3360 width: cropBoxData.width,
3361 height: cropBoxData.height
3362 }, getTransforms({
3363 translateX: cropBoxData.left,
3364 translateY: cropBoxData.top
3365 })));
3366 if (this.cropped && this.limited) {
3367 this.limitCanvas(true, true);
3368 }
3369 if (!this.disabled) {
3370 this.output();
3371 }
3372 },
3373 output: function output() {
3374 this.preview();
3375 dispatchEvent(this.element, EVENT_CROP, this.getData());
3376 }
3377 };
3378
3379 var preview = {
3380 initPreview: function initPreview() {
3381 var element = this.element,
3382 crossOrigin = this.crossOrigin;
3383 var preview = this.options.preview;
3384 var url = crossOrigin ? this.crossOriginUrl : this.url;
3385 var alt = element.alt || 'The image to preview';
3386 var image = document.createElement('img');
3387 if (crossOrigin) {
3388 image.crossOrigin = crossOrigin;
3389 }
3390 image.src = url;
3391 image.alt = alt;
3392 this.viewBox.appendChild(image);
3393 this.viewBoxImage = image;
3394 if (!preview) {
3395 return;
3396 }
3397 var previews = preview;
3398 if (typeof preview === 'string') {
3399 previews = element.ownerDocument.querySelectorAll(preview);
3400 } else if (preview.querySelector) {
3401 previews = [preview];
3402 }
3403 this.previews = previews;
3404 forEach(previews, function (el) {
3405 var img = document.createElement('img');
3406
3407 // Save the original size for recover
3408 setData(el, DATA_PREVIEW, {
3409 width: el.offsetWidth,
3410 height: el.offsetHeight,
3411 html: el.innerHTML
3412 });
3413 if (crossOrigin) {
3414 img.crossOrigin = crossOrigin;
3415 }
3416 img.src = url;
3417 img.alt = alt;
3418
3419 /**
3420 * Override img element styles
3421 * Add `display:block` to avoid margin top issue
3422 * Add `height:auto` to override `height` attribute on IE8
3423 * (Occur only when margin-top <= -height)
3424 */
3425 img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
3426 el.innerHTML = '';
3427 el.appendChild(img);
3428 });
3429 },
3430 resetPreview: function resetPreview() {
3431 forEach(this.previews, function (element) {
3432 var data = getData(element, DATA_PREVIEW);
3433 setStyle(element, {
3434 width: data.width,
3435 height: data.height
3436 });
3437 element.innerHTML = data.html;
3438 removeData(element, DATA_PREVIEW);
3439 });
3440 },
3441 preview: function preview() {
3442 var imageData = this.imageData,
3443 canvasData = this.canvasData,
3444 cropBoxData = this.cropBoxData;
3445 var cropBoxWidth = cropBoxData.width,
3446 cropBoxHeight = cropBoxData.height;
3447 var width = imageData.width,
3448 height = imageData.height;
3449 var left = cropBoxData.left - canvasData.left - imageData.left;
3450 var top = cropBoxData.top - canvasData.top - imageData.top;
3451 if (!this.cropped || this.disabled) {
3452 return;
3453 }
3454 setStyle(this.viewBoxImage, assign({
3455 width: width,
3456 height: height
3457 }, getTransforms(assign({
3458 translateX: -left,
3459 translateY: -top
3460 }, imageData))));
3461 forEach(this.previews, function (element) {
3462 var data = getData(element, DATA_PREVIEW);
3463 var originalWidth = data.width;
3464 var originalHeight = data.height;
3465 var newWidth = originalWidth;
3466 var newHeight = originalHeight;
3467 var ratio = 1;
3468 if (cropBoxWidth) {
3469 ratio = originalWidth / cropBoxWidth;
3470 newHeight = cropBoxHeight * ratio;
3471 }
3472 if (cropBoxHeight && newHeight > originalHeight) {
3473 ratio = originalHeight / cropBoxHeight;
3474 newWidth = cropBoxWidth * ratio;
3475 newHeight = originalHeight;
3476 }
3477 setStyle(element, {
3478 width: newWidth,
3479 height: newHeight
3480 });
3481 setStyle(element.getElementsByTagName('img')[0], assign({
3482 width: width * ratio,
3483 height: height * ratio
3484 }, getTransforms(assign({
3485 translateX: -left * ratio,
3486 translateY: -top * ratio
3487 }, imageData))));
3488 });
3489 }
3490 };
3491
3492 var events = {
3493 bind: function bind() {
3494 var element = this.element,
3495 options = this.options,
3496 cropper = this.cropper;
3497 if (isFunction(options.cropstart)) {
3498 addListener(element, EVENT_CROP_START, options.cropstart);
3499 }
3500 if (isFunction(options.cropmove)) {
3501 addListener(element, EVENT_CROP_MOVE, options.cropmove);
3502 }
3503 if (isFunction(options.cropend)) {
3504 addListener(element, EVENT_CROP_END, options.cropend);
3505 }
3506 if (isFunction(options.crop)) {
3507 addListener(element, EVENT_CROP, options.crop);
3508 }
3509 if (isFunction(options.zoom)) {
3510 addListener(element, EVENT_ZOOM, options.zoom);
3511 }
3512 addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
3513 if (options.zoomable && options.zoomOnWheel) {
3514 addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
3515 passive: false,
3516 capture: true
3517 });
3518 }
3519 if (options.toggleDragModeOnDblclick) {
3520 addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
3521 }
3522 addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
3523 addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
3524 if (options.responsive) {
3525 addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
3526 }
3527 },
3528 unbind: function unbind() {
3529 var element = this.element,
3530 options = this.options,
3531 cropper = this.cropper;
3532 if (isFunction(options.cropstart)) {
3533 removeListener(element, EVENT_CROP_START, options.cropstart);
3534 }
3535 if (isFunction(options.cropmove)) {
3536 removeListener(element, EVENT_CROP_MOVE, options.cropmove);
3537 }
3538 if (isFunction(options.cropend)) {
3539 removeListener(element, EVENT_CROP_END, options.cropend);
3540 }
3541 if (isFunction(options.crop)) {
3542 removeListener(element, EVENT_CROP, options.crop);
3543 }
3544 if (isFunction(options.zoom)) {
3545 removeListener(element, EVENT_ZOOM, options.zoom);
3546 }
3547 removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
3548 if (options.zoomable && options.zoomOnWheel) {
3549 removeListener(cropper, EVENT_WHEEL, this.onWheel, {
3550 passive: false,
3551 capture: true
3552 });
3553 }
3554 if (options.toggleDragModeOnDblclick) {
3555 removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
3556 }
3557 removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
3558 removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
3559 if (options.responsive) {
3560 removeListener(window, EVENT_RESIZE, this.onResize);
3561 }
3562 }
3563 };
3564
3565 var handlers = {
3566 resize: function resize() {
3567 if (this.disabled) {
3568 return;
3569 }
3570 var options = this.options,
3571 container = this.container,
3572 containerData = this.containerData;
3573 var ratioX = container.offsetWidth / containerData.width;
3574 var ratioY = container.offsetHeight / containerData.height;
3575 var ratio = Math.abs(ratioX - 1) > Math.abs(ratioY - 1) ? ratioX : ratioY;
3576
3577 // Resize when width changed or height changed
3578 if (ratio !== 1) {
3579 var canvasData;
3580 var cropBoxData;
3581 if (options.restore) {
3582 canvasData = this.getCanvasData();
3583 cropBoxData = this.getCropBoxData();
3584 }
3585 this.render();
3586 if (options.restore) {
3587 this.setCanvasData(forEach(canvasData, function (n, i) {
3588 canvasData[i] = n * ratio;
3589 }));
3590 this.setCropBoxData(forEach(cropBoxData, function (n, i) {
3591 cropBoxData[i] = n * ratio;
3592 }));
3593 }
3594 }
3595 },
3596 dblclick: function dblclick() {
3597 if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
3598 return;
3599 }
3600 this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
3601 },
3602 wheel: function wheel(event) {
3603 var _this = this;
3604 var ratio = Number(this.options.wheelZoomRatio) || 0.1;
3605 var delta = 1;
3606 if (this.disabled) {
3607 return;
3608 }
3609 event.preventDefault();
3610
3611 // Limit wheel speed to prevent zoom too fast (#21)
3612 if (this.wheeling) {
3613 return;
3614 }
3615 this.wheeling = true;
3616 setTimeout(function () {
3617 _this.wheeling = false;
3618 }, 50);
3619 if (event.deltaY) {
3620 delta = event.deltaY > 0 ? 1 : -1;
3621 } else if (event.wheelDelta) {
3622 delta = -event.wheelDelta / 120;
3623 } else if (event.detail) {
3624 delta = event.detail > 0 ? 1 : -1;
3625 }
3626 this.zoom(-delta * ratio, event);
3627 },
3628 cropStart: function cropStart(event) {
3629 var buttons = event.buttons,
3630 button = event.button;
3631 if (this.disabled
3632
3633 // Handle mouse event and pointer event and ignore touch event
3634 || (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && (
3635 // No primary button (Usually the left button)
3636 isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0
3637
3638 // Open context menu
3639 || event.ctrlKey)) {
3640 return;
3641 }
3642 var options = this.options,
3643 pointers = this.pointers;
3644 var action;
3645 if (event.changedTouches) {
3646 // Handle touch event
3647 forEach(event.changedTouches, function (touch) {
3648 pointers[touch.identifier] = getPointer(touch);
3649 });
3650 } else {
3651 // Handle mouse event and pointer event
3652 pointers[event.pointerId || 0] = getPointer(event);
3653 }
3654 if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
3655 action = ACTION_ZOOM;
3656 } else {
3657 action = getData(event.target, DATA_ACTION);
3658 }
3659 if (!REGEXP_ACTIONS.test(action)) {
3660 return;
3661 }
3662 if (dispatchEvent(this.element, EVENT_CROP_START, {
3663 originalEvent: event,
3664 action: action
3665 }) === false) {
3666 return;
3667 }
3668
3669 // This line is required for preventing page zooming in iOS browsers
3670 event.preventDefault();
3671 this.action = action;
3672 this.cropping = false;
3673 if (action === ACTION_CROP) {
3674 this.cropping = true;
3675 addClass(this.dragBox, CLASS_MODAL);
3676 }
3677 },
3678 cropMove: function cropMove(event) {
3679 var action = this.action;
3680 if (this.disabled || !action) {
3681 return;
3682 }
3683 var pointers = this.pointers;
3684 event.preventDefault();
3685 if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
3686 originalEvent: event,
3687 action: action
3688 }) === false) {
3689 return;
3690 }
3691 if (event.changedTouches) {
3692 forEach(event.changedTouches, function (touch) {
3693 // The first parameter should not be undefined (#432)
3694 assign(pointers[touch.identifier] || {}, getPointer(touch, true));
3695 });
3696 } else {
3697 assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
3698 }
3699 this.change(event);
3700 },
3701 cropEnd: function cropEnd(event) {
3702 if (this.disabled) {
3703 return;
3704 }
3705 var action = this.action,
3706 pointers = this.pointers;
3707 if (event.changedTouches) {
3708 forEach(event.changedTouches, function (touch) {
3709 delete pointers[touch.identifier];
3710 });
3711 } else {
3712 delete pointers[event.pointerId || 0];
3713 }
3714 if (!action) {
3715 return;
3716 }
3717 event.preventDefault();
3718 if (!Object.keys(pointers).length) {
3719 this.action = '';
3720 }
3721 if (this.cropping) {
3722 this.cropping = false;
3723 toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
3724 }
3725 dispatchEvent(this.element, EVENT_CROP_END, {
3726 originalEvent: event,
3727 action: action
3728 });
3729 }
3730 };
3731
3732 var change = {
3733 change: function change(event) {
3734 var options = this.options,
3735 canvasData = this.canvasData,
3736 containerData = this.containerData,
3737 cropBoxData = this.cropBoxData,
3738 pointers = this.pointers;
3739 var action = this.action;
3740 var aspectRatio = options.aspectRatio;
3741 var left = cropBoxData.left,
3742 top = cropBoxData.top,
3743 width = cropBoxData.width,
3744 height = cropBoxData.height;
3745 var right = left + width;
3746 var bottom = top + height;
3747 var minLeft = 0;
3748 var minTop = 0;
3749 var maxWidth = containerData.width;
3750 var maxHeight = containerData.height;
3751 var renderable = true;
3752 var offset;
3753
3754 // Locking aspect ratio in "free mode" by holding shift key
3755 if (!aspectRatio && event.shiftKey) {
3756 aspectRatio = width && height ? width / height : 1;
3757 }
3758 if (this.limited) {
3759 minLeft = cropBoxData.minLeft;
3760 minTop = cropBoxData.minTop;
3761 maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
3762 maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
3763 }
3764 var pointer = pointers[Object.keys(pointers)[0]];
3765 var range = {
3766 x: pointer.endX - pointer.startX,
3767 y: pointer.endY - pointer.startY
3768 };
3769 var check = function check(side) {
3770 switch (side) {
3771 case ACTION_EAST:
3772 if (right + range.x > maxWidth) {
3773 range.x = maxWidth - right;
3774 }
3775 break;
3776 case ACTION_WEST:
3777 if (left + range.x < minLeft) {
3778 range.x = minLeft - left;
3779 }
3780 break;
3781 case ACTION_NORTH:
3782 if (top + range.y < minTop) {
3783 range.y = minTop - top;
3784 }
3785 break;
3786 case ACTION_SOUTH:
3787 if (bottom + range.y > maxHeight) {
3788 range.y = maxHeight - bottom;
3789 }
3790 break;
3791 }
3792 };
3793 switch (action) {
3794 // Move crop box
3795 case ACTION_ALL:
3796 left += range.x;
3797 top += range.y;
3798 break;
3799
3800 // Resize crop box
3801 case ACTION_EAST:
3802 if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
3803 renderable = false;
3804 break;
3805 }
3806 check(ACTION_EAST);
3807 width += range.x;
3808 if (width < 0) {
3809 action = ACTION_WEST;
3810 width = -width;
3811 left -= width;
3812 }
3813 if (aspectRatio) {
3814 height = width / aspectRatio;
3815 top += (cropBoxData.height - height) / 2;
3816 }
3817 break;
3818 case ACTION_NORTH:
3819 if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
3820 renderable = false;
3821 break;
3822 }
3823 check(ACTION_NORTH);
3824 height -= range.y;
3825 top += range.y;
3826 if (height < 0) {
3827 action = ACTION_SOUTH;
3828 height = -height;
3829 top -= height;
3830 }
3831 if (aspectRatio) {
3832 width = height * aspectRatio;
3833 left += (cropBoxData.width - width) / 2;
3834 }
3835 break;
3836 case ACTION_WEST:
3837 if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
3838 renderable = false;
3839 break;
3840 }
3841 check(ACTION_WEST);
3842 width -= range.x;
3843 left += range.x;
3844 if (width < 0) {
3845 action = ACTION_EAST;
3846 width = -width;
3847 left -= width;
3848 }
3849 if (aspectRatio) {
3850 height = width / aspectRatio;
3851 top += (cropBoxData.height - height) / 2;
3852 }
3853 break;
3854 case ACTION_SOUTH:
3855 if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
3856 renderable = false;
3857 break;
3858 }
3859 check(ACTION_SOUTH);
3860 height += range.y;
3861 if (height < 0) {
3862 action = ACTION_NORTH;
3863 height = -height;
3864 top -= height;
3865 }
3866 if (aspectRatio) {
3867 width = height * aspectRatio;
3868 left += (cropBoxData.width - width) / 2;
3869 }
3870 break;
3871 case ACTION_NORTH_EAST:
3872 if (aspectRatio) {
3873 if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
3874 renderable = false;
3875 break;
3876 }
3877 check(ACTION_NORTH);
3878 height -= range.y;
3879 top += range.y;
3880 width = height * aspectRatio;
3881 } else {
3882 check(ACTION_NORTH);
3883 check(ACTION_EAST);
3884 if (range.x >= 0) {
3885 if (right < maxWidth) {
3886 width += range.x;
3887 } else if (range.y <= 0 && top <= minTop) {
3888 renderable = false;
3889 }
3890 } else {
3891 width += range.x;
3892 }
3893 if (range.y <= 0) {
3894 if (top > minTop) {
3895 height -= range.y;
3896 top += range.y;
3897 }
3898 } else {
3899 height -= range.y;
3900 top += range.y;
3901 }
3902 }
3903 if (width < 0 && height < 0) {
3904 action = ACTION_SOUTH_WEST;
3905 height = -height;
3906 width = -width;
3907 top -= height;
3908 left -= width;
3909 } else if (width < 0) {
3910 action = ACTION_NORTH_WEST;
3911 width = -width;
3912 left -= width;
3913 } else if (height < 0) {
3914 action = ACTION_SOUTH_EAST;
3915 height = -height;
3916 top -= height;
3917 }
3918 break;
3919 case ACTION_NORTH_WEST:
3920 if (aspectRatio) {
3921 if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
3922 renderable = false;
3923 break;
3924 }
3925 check(ACTION_NORTH);
3926 height -= range.y;
3927 top += range.y;
3928 width = height * aspectRatio;
3929 left += cropBoxData.width - width;
3930 } else {
3931 check(ACTION_NORTH);
3932 check(ACTION_WEST);
3933 if (range.x <= 0) {
3934 if (left > minLeft) {
3935 width -= range.x;
3936 left += range.x;
3937 } else if (range.y <= 0 && top <= minTop) {
3938 renderable = false;
3939 }
3940 } else {
3941 width -= range.x;
3942 left += range.x;
3943 }
3944 if (range.y <= 0) {
3945 if (top > minTop) {
3946 height -= range.y;
3947 top += range.y;
3948 }
3949 } else {
3950 height -= range.y;
3951 top += range.y;
3952 }
3953 }
3954 if (width < 0 && height < 0) {
3955 action = ACTION_SOUTH_EAST;
3956 height = -height;
3957 width = -width;
3958 top -= height;
3959 left -= width;
3960 } else if (width < 0) {
3961 action = ACTION_NORTH_EAST;
3962 width = -width;
3963 left -= width;
3964 } else if (height < 0) {
3965 action = ACTION_SOUTH_WEST;
3966 height = -height;
3967 top -= height;
3968 }
3969 break;
3970 case ACTION_SOUTH_WEST:
3971 if (aspectRatio) {
3972 if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
3973 renderable = false;
3974 break;
3975 }
3976 check(ACTION_WEST);
3977 width -= range.x;
3978 left += range.x;
3979 height = width / aspectRatio;
3980 } else {
3981 check(ACTION_SOUTH);
3982 check(ACTION_WEST);
3983 if (range.x <= 0) {
3984 if (left > minLeft) {
3985 width -= range.x;
3986 left += range.x;
3987 } else if (range.y >= 0 && bottom >= maxHeight) {
3988 renderable = false;
3989 }
3990 } else {
3991 width -= range.x;
3992 left += range.x;
3993 }
3994 if (range.y >= 0) {
3995 if (bottom < maxHeight) {
3996 height += range.y;
3997 }
3998 } else {
3999 height += range.y;
4000 }
4001 }
4002 if (width < 0 && height < 0) {
4003 action = ACTION_NORTH_EAST;
4004 height = -height;
4005 width = -width;
4006 top -= height;
4007 left -= width;
4008 } else if (width < 0) {
4009 action = ACTION_SOUTH_EAST;
4010 width = -width;
4011 left -= width;
4012 } else if (height < 0) {
4013 action = ACTION_NORTH_WEST;
4014 height = -height;
4015 top -= height;
4016 }
4017 break;
4018 case ACTION_SOUTH_EAST:
4019 if (aspectRatio) {
4020 if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
4021 renderable = false;
4022 break;
4023 }
4024 check(ACTION_EAST);
4025 width += range.x;
4026 height = width / aspectRatio;
4027 } else {
4028 check(ACTION_SOUTH);
4029 check(ACTION_EAST);
4030 if (range.x >= 0) {
4031 if (right < maxWidth) {
4032 width += range.x;
4033 } else if (range.y >= 0 && bottom >= maxHeight) {
4034 renderable = false;
4035 }
4036 } else {
4037 width += range.x;
4038 }
4039 if (range.y >= 0) {
4040 if (bottom < maxHeight) {
4041 height += range.y;
4042 }
4043 } else {
4044 height += range.y;
4045 }
4046 }
4047 if (width < 0 && height < 0) {
4048 action = ACTION_NORTH_WEST;
4049 height = -height;
4050 width = -width;
4051 top -= height;
4052 left -= width;
4053 } else if (width < 0) {
4054 action = ACTION_SOUTH_WEST;
4055 width = -width;
4056 left -= width;
4057 } else if (height < 0) {
4058 action = ACTION_NORTH_EAST;
4059 height = -height;
4060 top -= height;
4061 }
4062 break;
4063
4064 // Move canvas
4065 case ACTION_MOVE:
4066 this.move(range.x, range.y);
4067 renderable = false;
4068 break;
4069
4070 // Zoom canvas
4071 case ACTION_ZOOM:
4072 this.zoom(getMaxZoomRatio(pointers), event);
4073 renderable = false;
4074 break;
4075
4076 // Create crop box
4077 case ACTION_CROP:
4078 if (!range.x || !range.y) {
4079 renderable = false;
4080 break;
4081 }
4082 offset = getOffset(this.cropper);
4083 left = pointer.startX - offset.left;
4084 top = pointer.startY - offset.top;
4085 width = cropBoxData.minWidth;
4086 height = cropBoxData.minHeight;
4087 if (range.x > 0) {
4088 action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
4089 } else if (range.x < 0) {
4090 left -= width;
4091 action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
4092 }
4093 if (range.y < 0) {
4094 top -= height;
4095 }
4096
4097 // Show the crop box if is hidden
4098 if (!this.cropped) {
4099 removeClass(this.cropBox, CLASS_HIDDEN);
4100 this.cropped = true;
4101 if (this.limited) {
4102 this.limitCropBox(true, true);
4103 }
4104 }
4105 break;
4106 }
4107 if (renderable) {
4108 cropBoxData.width = width;
4109 cropBoxData.height = height;
4110 cropBoxData.left = left;
4111 cropBoxData.top = top;
4112 this.action = action;
4113 this.renderCropBox();
4114 }
4115
4116 // Override
4117 forEach(pointers, function (p) {
4118 p.startX = p.endX;
4119 p.startY = p.endY;
4120 });
4121 }
4122 };
4123
4124 var methods = {
4125 // Show the crop box manually
4126 crop: function crop() {
4127 if (this.ready && !this.cropped && !this.disabled) {
4128 this.cropped = true;
4129 this.limitCropBox(true, true);
4130 if (this.options.modal) {
4131 addClass(this.dragBox, CLASS_MODAL);
4132 }
4133 removeClass(this.cropBox, CLASS_HIDDEN);
4134 this.setCropBoxData(this.initialCropBoxData);
4135 }
4136 return this;
4137 },
4138 // Reset the image and crop box to their initial states
4139 reset: function reset() {
4140 if (this.ready && !this.disabled) {
4141 this.imageData = assign({}, this.initialImageData);
4142 this.canvasData = assign({}, this.initialCanvasData);
4143 this.cropBoxData = assign({}, this.initialCropBoxData);
4144 this.renderCanvas();
4145 if (this.cropped) {
4146 this.renderCropBox();
4147 }
4148 }
4149 return this;
4150 },
4151 // Clear the crop box
4152 clear: function clear() {
4153 if (this.cropped && !this.disabled) {
4154 assign(this.cropBoxData, {
4155 left: 0,
4156 top: 0,
4157 width: 0,
4158 height: 0
4159 });
4160 this.cropped = false;
4161 this.renderCropBox();
4162 this.limitCanvas(true, true);
4163
4164 // Render canvas after crop box rendered
4165 this.renderCanvas();
4166 removeClass(this.dragBox, CLASS_MODAL);
4167 addClass(this.cropBox, CLASS_HIDDEN);
4168 }
4169 return this;
4170 },
4171 /**
4172 * Replace the image's src and rebuild the cropper
4173 * @param {string} url - The new URL.
4174 * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
4175 * @returns {Cropper} this
4176 */
4177 replace: function replace(url) {
4178 var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
4179 if (!this.disabled && url) {
4180 if (this.isImg) {
4181 this.element.src = url;
4182 }
4183 if (hasSameSize) {
4184 this.url = url;
4185 this.image.src = url;
4186 if (this.ready) {
4187 this.viewBoxImage.src = url;
4188 forEach(this.previews, function (element) {
4189 element.getElementsByTagName('img')[0].src = url;
4190 });
4191 }
4192 } else {
4193 if (this.isImg) {
4194 this.replaced = true;
4195 }
4196 this.options.data = null;
4197 this.uncreate();
4198 this.load(url);
4199 }
4200 }
4201 return this;
4202 },
4203 // Enable (unfreeze) the cropper
4204 enable: function enable() {
4205 if (this.ready && this.disabled) {
4206 this.disabled = false;
4207 removeClass(this.cropper, CLASS_DISABLED);
4208 }
4209 return this;
4210 },
4211 // Disable (freeze) the cropper
4212 disable: function disable() {
4213 if (this.ready && !this.disabled) {
4214 this.disabled = true;
4215 addClass(this.cropper, CLASS_DISABLED);
4216 }
4217 return this;
4218 },
4219 /**
4220 * Destroy the cropper and remove the instance from the image
4221 * @returns {Cropper} this
4222 */
4223 destroy: function destroy() {
4224 var element = this.element;
4225 if (!element[NAMESPACE]) {
4226 return this;
4227 }
4228 element[NAMESPACE] = undefined;
4229 if (this.isImg && this.replaced) {
4230 element.src = this.originalUrl;
4231 }
4232 this.uncreate();
4233 return this;
4234 },
4235 /**
4236 * Move the canvas with relative offsets
4237 * @param {number} offsetX - The relative offset distance on the x-axis.
4238 * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
4239 * @returns {Cropper} this
4240 */
4241 move: function move(offsetX) {
4242 var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
4243 var _this$canvasData = this.canvasData,
4244 left = _this$canvasData.left,
4245 top = _this$canvasData.top;
4246 return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
4247 },
4248 /**
4249 * Move the canvas to an absolute point
4250 * @param {number} x - The x-axis coordinate.
4251 * @param {number} [y=x] - The y-axis coordinate.
4252 * @returns {Cropper} this
4253 */
4254 moveTo: function moveTo(x) {
4255 var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
4256 var canvasData = this.canvasData;
4257 var changed = false;
4258 x = Number(x);
4259 y = Number(y);
4260 if (this.ready && !this.disabled && this.options.movable) {
4261 if (isNumber(x)) {
4262 canvasData.left = x;
4263 changed = true;
4264 }
4265 if (isNumber(y)) {
4266 canvasData.top = y;
4267 changed = true;
4268 }
4269 if (changed) {
4270 this.renderCanvas(true);
4271 }
4272 }
4273 return this;
4274 },
4275 /**
4276 * Zoom the canvas with a relative ratio
4277 * @param {number} ratio - The target ratio.
4278 * @param {Event} _originalEvent - The original event if any.
4279 * @returns {Cropper} this
4280 */
4281 zoom: function zoom(ratio, _originalEvent) {
4282 var canvasData = this.canvasData;
4283 ratio = Number(ratio);
4284 if (ratio < 0) {
4285 ratio = 1 / (1 - ratio);
4286 } else {
4287 ratio = 1 + ratio;
4288 }
4289 return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
4290 },
4291 /**
4292 * Zoom the canvas to an absolute ratio
4293 * @param {number} ratio - The target ratio.
4294 * @param {Object} pivot - The zoom pivot point coordinate.
4295 * @param {Event} _originalEvent - The original event if any.
4296 * @returns {Cropper} this
4297 */
4298 zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
4299 var options = this.options,
4300 canvasData = this.canvasData;
4301 var width = canvasData.width,
4302 height = canvasData.height,
4303 naturalWidth = canvasData.naturalWidth,
4304 naturalHeight = canvasData.naturalHeight;
4305 ratio = Number(ratio);
4306 if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
4307 var newWidth = naturalWidth * ratio;
4308 var newHeight = naturalHeight * ratio;
4309 if (dispatchEvent(this.element, EVENT_ZOOM, {
4310 ratio: ratio,
4311 oldRatio: width / naturalWidth,
4312 originalEvent: _originalEvent
4313 }) === false) {
4314 return this;
4315 }
4316 if (_originalEvent) {
4317 var pointers = this.pointers;
4318 var offset = getOffset(this.cropper);
4319 var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
4320 pageX: _originalEvent.pageX,
4321 pageY: _originalEvent.pageY
4322 };
4323
4324 // Zoom from the triggering point of the event
4325 canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
4326 canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
4327 } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
4328 canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
4329 canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
4330 } else {
4331 // Zoom from the center of the canvas
4332 canvasData.left -= (newWidth - width) / 2;
4333 canvasData.top -= (newHeight - height) / 2;
4334 }
4335 canvasData.width = newWidth;
4336 canvasData.height = newHeight;
4337 this.renderCanvas(true);
4338 }
4339 return this;
4340 },
4341 /**
4342 * Rotate the canvas with a relative degree
4343 * @param {number} degree - The rotate degree.
4344 * @returns {Cropper} this
4345 */
4346 rotate: function rotate(degree) {
4347 return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
4348 },
4349 /**
4350 * Rotate the canvas to an absolute degree
4351 * @param {number} degree - The rotate degree.
4352 * @returns {Cropper} this
4353 */
4354 rotateTo: function rotateTo(degree) {
4355 degree = Number(degree);
4356 if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
4357 this.imageData.rotate = degree % 360;
4358 this.renderCanvas(true, true);
4359 }
4360 return this;
4361 },
4362 /**
4363 * Scale the image on the x-axis.
4364 * @param {number} scaleX - The scale ratio on the x-axis.
4365 * @returns {Cropper} this
4366 */
4367 scaleX: function scaleX(_scaleX) {
4368 var scaleY = this.imageData.scaleY;
4369 return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
4370 },
4371 /**
4372 * Scale the image on the y-axis.
4373 * @param {number} scaleY - The scale ratio on the y-axis.
4374 * @returns {Cropper} this
4375 */
4376 scaleY: function scaleY(_scaleY) {
4377 var scaleX = this.imageData.scaleX;
4378 return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
4379 },
4380 /**
4381 * Scale the image
4382 * @param {number} scaleX - The scale ratio on the x-axis.
4383 * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
4384 * @returns {Cropper} this
4385 */
4386 scale: function scale(scaleX) {
4387 var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
4388 var imageData = this.imageData;
4389 var transformed = false;
4390 scaleX = Number(scaleX);
4391 scaleY = Number(scaleY);
4392 if (this.ready && !this.disabled && this.options.scalable) {
4393 if (isNumber(scaleX)) {
4394 imageData.scaleX = scaleX;
4395 transformed = true;
4396 }
4397 if (isNumber(scaleY)) {
4398 imageData.scaleY = scaleY;
4399 transformed = true;
4400 }
4401 if (transformed) {
4402 this.renderCanvas(true, true);
4403 }
4404 }
4405 return this;
4406 },
4407 /**
4408 * Get the cropped area position and size data (base on the original image)
4409 * @param {boolean} [rounded=false] - Indicate if round the data values or not.
4410 * @returns {Object} The result cropped data.
4411 */
4412 getData: function getData() {
4413 var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
4414 var options = this.options,
4415 imageData = this.imageData,
4416 canvasData = this.canvasData,
4417 cropBoxData = this.cropBoxData;
4418 var data;
4419 if (this.ready && this.cropped) {
4420 data = {
4421 x: cropBoxData.left - canvasData.left,
4422 y: cropBoxData.top - canvasData.top,
4423 width: cropBoxData.width,
4424 height: cropBoxData.height
4425 };
4426 var ratio = imageData.width / imageData.naturalWidth;
4427 forEach(data, function (n, i) {
4428 data[i] = n / ratio;
4429 });
4430 if (rounded) {
4431 // In case rounding off leads to extra 1px in right or bottom border
4432 // we should round the top-left corner and the dimension (#343).
4433 var bottom = Math.round(data.y + data.height);
4434 var right = Math.round(data.x + data.width);
4435 data.x = Math.round(data.x);
4436 data.y = Math.round(data.y);
4437 data.width = right - data.x;
4438 data.height = bottom - data.y;
4439 }
4440 } else {
4441 data = {
4442 x: 0,
4443 y: 0,
4444 width: 0,
4445 height: 0
4446 };
4447 }
4448 if (options.rotatable) {
4449 data.rotate = imageData.rotate || 0;
4450 }
4451 if (options.scalable) {
4452 data.scaleX = imageData.scaleX || 1;
4453 data.scaleY = imageData.scaleY || 1;
4454 }
4455 return data;
4456 },
4457 /**
4458 * Set the cropped area position and size with new data
4459 * @param {Object} data - The new data.
4460 * @returns {Cropper} this
4461 */
4462 setData: function setData(data) {
4463 var options = this.options,
4464 imageData = this.imageData,
4465 canvasData = this.canvasData;
4466 var cropBoxData = {};
4467 if (this.ready && !this.disabled && isPlainObject(data)) {
4468 var transformed = false;
4469 if (options.rotatable) {
4470 if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
4471 imageData.rotate = data.rotate;
4472 transformed = true;
4473 }
4474 }
4475 if (options.scalable) {
4476 if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
4477 imageData.scaleX = data.scaleX;
4478 transformed = true;
4479 }
4480 if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
4481 imageData.scaleY = data.scaleY;
4482 transformed = true;
4483 }
4484 }
4485 if (transformed) {
4486 this.renderCanvas(true, true);
4487 }
4488 var ratio = imageData.width / imageData.naturalWidth;
4489 if (isNumber(data.x)) {
4490 cropBoxData.left = data.x * ratio + canvasData.left;
4491 }
4492 if (isNumber(data.y)) {
4493 cropBoxData.top = data.y * ratio + canvasData.top;
4494 }
4495 if (isNumber(data.width)) {
4496 cropBoxData.width = data.width * ratio;
4497 }
4498 if (isNumber(data.height)) {
4499 cropBoxData.height = data.height * ratio;
4500 }
4501 this.setCropBoxData(cropBoxData);
4502 }
4503 return this;
4504 },
4505 /**
4506 * Get the container size data.
4507 * @returns {Object} The result container data.
4508 */
4509 getContainerData: function getContainerData() {
4510 return this.ready ? assign({}, this.containerData) : {};
4511 },
4512 /**
4513 * Get the image position and size data.
4514 * @returns {Object} The result image data.
4515 */
4516 getImageData: function getImageData() {
4517 return this.sized ? assign({}, this.imageData) : {};
4518 },
4519 /**
4520 * Get the canvas position and size data.
4521 * @returns {Object} The result canvas data.
4522 */
4523 getCanvasData: function getCanvasData() {
4524 var canvasData = this.canvasData;
4525 var data = {};
4526 if (this.ready) {
4527 forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
4528 data[n] = canvasData[n];
4529 });
4530 }
4531 return data;
4532 },
4533 /**
4534 * Set the canvas position and size with new data.
4535 * @param {Object} data - The new canvas data.
4536 * @returns {Cropper} this
4537 */
4538 setCanvasData: function setCanvasData(data) {
4539 var canvasData = this.canvasData;
4540 var aspectRatio = canvasData.aspectRatio;
4541 if (this.ready && !this.disabled && isPlainObject(data)) {
4542 if (isNumber(data.left)) {
4543 canvasData.left = data.left;
4544 }
4545 if (isNumber(data.top)) {
4546 canvasData.top = data.top;
4547 }
4548 if (isNumber(data.width)) {
4549 canvasData.width = data.width;
4550 canvasData.height = data.width / aspectRatio;
4551 } else if (isNumber(data.height)) {
4552 canvasData.height = data.height;
4553 canvasData.width = data.height * aspectRatio;
4554 }
4555 this.renderCanvas(true);
4556 }
4557 return this;
4558 },
4559 /**
4560 * Get the crop box position and size data.
4561 * @returns {Object} The result crop box data.
4562 */
4563 getCropBoxData: function getCropBoxData() {
4564 var cropBoxData = this.cropBoxData;
4565 var data;
4566 if (this.ready && this.cropped) {
4567 data = {
4568 left: cropBoxData.left,
4569 top: cropBoxData.top,
4570 width: cropBoxData.width,
4571 height: cropBoxData.height
4572 };
4573 }
4574 return data || {};
4575 },
4576 /**
4577 * Set the crop box position and size with new data.
4578 * @param {Object} data - The new crop box data.
4579 * @returns {Cropper} this
4580 */
4581 setCropBoxData: function setCropBoxData(data) {
4582 var cropBoxData = this.cropBoxData;
4583 var aspectRatio = this.options.aspectRatio;
4584 var widthChanged;
4585 var heightChanged;
4586 if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
4587 if (isNumber(data.left)) {
4588 cropBoxData.left = data.left;
4589 }
4590 if (isNumber(data.top)) {
4591 cropBoxData.top = data.top;
4592 }
4593 if (isNumber(data.width) && data.width !== cropBoxData.width) {
4594 widthChanged = true;
4595 cropBoxData.width = data.width;
4596 }
4597 if (isNumber(data.height) && data.height !== cropBoxData.height) {
4598 heightChanged = true;
4599 cropBoxData.height = data.height;
4600 }
4601 if (aspectRatio) {
4602 if (widthChanged) {
4603 cropBoxData.height = cropBoxData.width / aspectRatio;
4604 } else if (heightChanged) {
4605 cropBoxData.width = cropBoxData.height * aspectRatio;
4606 }
4607 }
4608 this.renderCropBox();
4609 }
4610 return this;
4611 },
4612 /**
4613 * Get a canvas drawn the cropped image.
4614 * @param {Object} [options={}] - The config options.
4615 * @returns {HTMLCanvasElement} - The result canvas.
4616 */
4617 getCroppedCanvas: function getCroppedCanvas() {
4618 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4619 if (!this.ready || !window.HTMLCanvasElement) {
4620 return null;
4621 }
4622 var canvasData = this.canvasData;
4623 var source = getSourceCanvas(this.image, this.imageData, canvasData, options);
4624
4625 // Returns the source canvas if it is not cropped.
4626 if (!this.cropped) {
4627 return source;
4628 }
4629 var _this$getData = this.getData(options.rounded),
4630 initialX = _this$getData.x,
4631 initialY = _this$getData.y,
4632 initialWidth = _this$getData.width,
4633 initialHeight = _this$getData.height;
4634 var ratio = source.width / Math.floor(canvasData.naturalWidth);
4635 if (ratio !== 1) {
4636 initialX *= ratio;
4637 initialY *= ratio;
4638 initialWidth *= ratio;
4639 initialHeight *= ratio;
4640 }
4641 var aspectRatio = initialWidth / initialHeight;
4642 var maxSizes = getAdjustedSizes({
4643 aspectRatio: aspectRatio,
4644 width: options.maxWidth || Infinity,
4645 height: options.maxHeight || Infinity
4646 });
4647 var minSizes = getAdjustedSizes({
4648 aspectRatio: aspectRatio,
4649 width: options.minWidth || 0,
4650 height: options.minHeight || 0
4651 }, 'cover');
4652 var _getAdjustedSizes = getAdjustedSizes({
4653 aspectRatio: aspectRatio,
4654 width: options.width || (ratio !== 1 ? source.width : initialWidth),
4655 height: options.height || (ratio !== 1 ? source.height : initialHeight)
4656 }),
4657 width = _getAdjustedSizes.width,
4658 height = _getAdjustedSizes.height;
4659 width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
4660 height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
4661 var canvas = document.createElement('canvas');
4662 var context = canvas.getContext('2d');
4663 canvas.width = normalizeDecimalNumber(width);
4664 canvas.height = normalizeDecimalNumber(height);
4665 context.fillStyle = options.fillColor || 'transparent';
4666 context.fillRect(0, 0, width, height);
4667 var _options$imageSmoothi = options.imageSmoothingEnabled,
4668 imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
4669 imageSmoothingQuality = options.imageSmoothingQuality;
4670 context.imageSmoothingEnabled = imageSmoothingEnabled;
4671 if (imageSmoothingQuality) {
4672 context.imageSmoothingQuality = imageSmoothingQuality;
4673 }
4674
4675 // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
4676 var sourceWidth = source.width;
4677 var sourceHeight = source.height;
4678
4679 // Source canvas parameters
4680 var srcX = initialX;
4681 var srcY = initialY;
4682 var srcWidth;
4683 var srcHeight;
4684
4685 // Destination canvas parameters
4686 var dstX;
4687 var dstY;
4688 var dstWidth;
4689 var dstHeight;
4690 if (srcX <= -initialWidth || srcX > sourceWidth) {
4691 srcX = 0;
4692 srcWidth = 0;
4693 dstX = 0;
4694 dstWidth = 0;
4695 } else if (srcX <= 0) {
4696 dstX = -srcX;
4697 srcX = 0;
4698 srcWidth = Math.min(sourceWidth, initialWidth + srcX);
4699 dstWidth = srcWidth;
4700 } else if (srcX <= sourceWidth) {
4701 dstX = 0;
4702 srcWidth = Math.min(initialWidth, sourceWidth - srcX);
4703 dstWidth = srcWidth;
4704 }
4705 if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
4706 srcY = 0;
4707 srcHeight = 0;
4708 dstY = 0;
4709 dstHeight = 0;
4710 } else if (srcY <= 0) {
4711 dstY = -srcY;
4712 srcY = 0;
4713 srcHeight = Math.min(sourceHeight, initialHeight + srcY);
4714 dstHeight = srcHeight;
4715 } else if (srcY <= sourceHeight) {
4716 dstY = 0;
4717 srcHeight = Math.min(initialHeight, sourceHeight - srcY);
4718 dstHeight = srcHeight;
4719 }
4720 var params = [srcX, srcY, srcWidth, srcHeight];
4721
4722 // Avoid "IndexSizeError"
4723 if (dstWidth > 0 && dstHeight > 0) {
4724 var scale = width / initialWidth;
4725 params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
4726 }
4727
4728 // All the numerical parameters should be integer for `drawImage`
4729 // https://github.com/fengyuanchen/cropper/issues/476
4730 context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
4731 return Math.floor(normalizeDecimalNumber(param));
4732 }))));
4733 return canvas;
4734 },
4735 /**
4736 * Change the aspect ratio of the crop box.
4737 * @param {number} aspectRatio - The new aspect ratio.
4738 * @returns {Cropper} this
4739 */
4740 setAspectRatio: function setAspectRatio(aspectRatio) {
4741 var options = this.options;
4742 if (!this.disabled && !isUndefined(aspectRatio)) {
4743 // 0 -> NaN
4744 options.aspectRatio = Math.max(0, aspectRatio) || NaN;
4745 if (this.ready) {
4746 this.initCropBox();
4747 if (this.cropped) {
4748 this.renderCropBox();
4749 }
4750 }
4751 }
4752 return this;
4753 },
4754 /**
4755 * Change the drag mode.
4756 * @param {string} mode - The new drag mode.
4757 * @returns {Cropper} this
4758 */
4759 setDragMode: function setDragMode(mode) {
4760 var options = this.options,
4761 dragBox = this.dragBox,
4762 face = this.face;
4763 if (this.ready && !this.disabled) {
4764 var croppable = mode === DRAG_MODE_CROP;
4765 var movable = options.movable && mode === DRAG_MODE_MOVE;
4766 mode = croppable || movable ? mode : DRAG_MODE_NONE;
4767 options.dragMode = mode;
4768 setData(dragBox, DATA_ACTION, mode);
4769 toggleClass(dragBox, CLASS_CROP, croppable);
4770 toggleClass(dragBox, CLASS_MOVE, movable);
4771 if (!options.cropBoxMovable) {
4772 // Sync drag mode to crop box when it is not movable
4773 setData(face, DATA_ACTION, mode);
4774 toggleClass(face, CLASS_CROP, croppable);
4775 toggleClass(face, CLASS_MOVE, movable);
4776 }
4777 }
4778 return this;
4779 }
4780 };
4781
4782 var AnotherCropper = WINDOW.Cropper;
4783 var Cropper = /*#__PURE__*/function () {
4784 /**
4785 * Create a new Cropper.
4786 * @param {Element} element - The target element for cropping.
4787 * @param {Object} [options={}] - The configuration options.
4788 */
4789 function Cropper(element) {
4790 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4791 _classCallCheck(this, Cropper);
4792 if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
4793 throw new Error('The first argument is required and must be an <img> or <canvas> element.');
4794 }
4795 this.element = element;
4796 this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
4797 this.cropped = false;
4798 this.disabled = false;
4799 this.pointers = {};
4800 this.ready = false;
4801 this.reloading = false;
4802 this.replaced = false;
4803 this.sized = false;
4804 this.sizing = false;
4805 this.init();
4806 }
4807 return _createClass(Cropper, [{
4808 key: "init",
4809 value: function init() {
4810 var element = this.element;
4811 var tagName = element.tagName.toLowerCase();
4812 var url;
4813 if (element[NAMESPACE]) {
4814 return;
4815 }
4816 element[NAMESPACE] = this;
4817 if (tagName === 'img') {
4818 this.isImg = true;
4819
4820 // e.g.: "img/picture.jpg"
4821 url = element.getAttribute('src') || '';
4822 this.originalUrl = url;
4823
4824 // Stop when it's a blank image
4825 if (!url) {
4826 return;
4827 }
4828
4829 // e.g.: "https://example.com/img/picture.jpg"
4830 url = element.src;
4831 } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
4832 url = element.toDataURL();
4833 }
4834 this.load(url);
4835 }
4836 }, {
4837 key: "load",
4838 value: function load(url) {
4839 var _this = this;
4840 if (!url) {
4841 return;
4842 }
4843 this.url = url;
4844 this.imageData = {};
4845 var element = this.element,
4846 options = this.options;
4847 if (!options.rotatable && !options.scalable) {
4848 options.checkOrientation = false;
4849 }
4850
4851 // Only IE10+ supports Typed Arrays
4852 if (!options.checkOrientation || !window.ArrayBuffer) {
4853 this.clone();
4854 return;
4855 }
4856
4857 // Detect the mime type of the image directly if it is a Data URL
4858 if (REGEXP_DATA_URL.test(url)) {
4859 // Read ArrayBuffer from Data URL of JPEG images directly for better performance
4860 if (REGEXP_DATA_URL_JPEG.test(url)) {
4861 this.read(dataURLToArrayBuffer(url));
4862 } else {
4863 // Only a JPEG image may contains Exif Orientation information,
4864 // the rest types of Data URLs are not necessary to check orientation at all.
4865 this.clone();
4866 }
4867 return;
4868 }
4869
4870 // 1. Detect the mime type of the image by a XMLHttpRequest.
4871 // 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.
4872 var xhr = new XMLHttpRequest();
4873 var clone = this.clone.bind(this);
4874 this.reloading = true;
4875 this.xhr = xhr;
4876
4877 // 1. Cross origin requests are only supported for protocol schemes:
4878 // http, https, data, chrome, chrome-extension.
4879 // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
4880 // in some browsers as IE11 and Safari.
4881 xhr.onabort = clone;
4882 xhr.onerror = clone;
4883 xhr.ontimeout = clone;
4884 xhr.onprogress = function () {
4885 // Abort the request directly if it not a JPEG image for better performance
4886 if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
4887 xhr.abort();
4888 }
4889 };
4890 xhr.onload = function () {
4891 _this.read(xhr.response);
4892 };
4893 xhr.onloadend = function () {
4894 _this.reloading = false;
4895 _this.xhr = null;
4896 };
4897
4898 // Bust cache when there is a "crossOrigin" property to avoid browser cache error
4899 if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
4900 url = addTimestamp(url);
4901 }
4902
4903 // The third parameter is required for avoiding side-effect (#682)
4904 xhr.open('GET', url, true);
4905 xhr.responseType = 'arraybuffer';
4906 xhr.withCredentials = element.crossOrigin === 'use-credentials';
4907 xhr.send();
4908 }
4909 }, {
4910 key: "read",
4911 value: function read(arrayBuffer) {
4912 var options = this.options,
4913 imageData = this.imageData;
4914
4915 // Reset the orientation value to its default value 1
4916 // as some iOS browsers will render image with its orientation
4917 var orientation = resetAndGetOrientation(arrayBuffer);
4918 var rotate = 0;
4919 var scaleX = 1;
4920 var scaleY = 1;
4921 if (orientation > 1) {
4922 // Generate a new URL which has the default orientation value
4923 this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
4924 var _parseOrientation = parseOrientation(orientation);
4925 rotate = _parseOrientation.rotate;
4926 scaleX = _parseOrientation.scaleX;
4927 scaleY = _parseOrientation.scaleY;
4928 }
4929 if (options.rotatable) {
4930 imageData.rotate = rotate;
4931 }
4932 if (options.scalable) {
4933 imageData.scaleX = scaleX;
4934 imageData.scaleY = scaleY;
4935 }
4936 this.clone();
4937 }
4938 }, {
4939 key: "clone",
4940 value: function clone() {
4941 var element = this.element,
4942 url = this.url;
4943 var crossOrigin = element.crossOrigin;
4944 var crossOriginUrl = url;
4945 if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
4946 if (!crossOrigin) {
4947 crossOrigin = 'anonymous';
4948 }
4949
4950 // Bust cache when there is not a "crossOrigin" property (#519)
4951 crossOriginUrl = addTimestamp(url);
4952 }
4953 this.crossOrigin = crossOrigin;
4954 this.crossOriginUrl = crossOriginUrl;
4955 var image = document.createElement('img');
4956 if (crossOrigin) {
4957 image.crossOrigin = crossOrigin;
4958 }
4959 image.src = crossOriginUrl || url;
4960 image.alt = element.alt || 'The image to crop';
4961 this.image = image;
4962 image.onload = this.start.bind(this);
4963 image.onerror = this.stop.bind(this);
4964 addClass(image, CLASS_HIDE);
4965 element.parentNode.insertBefore(image, element.nextSibling);
4966 }
4967 }, {
4968 key: "start",
4969 value: function start() {
4970 var _this2 = this;
4971 var image = this.image;
4972 image.onload = null;
4973 image.onerror = null;
4974 this.sizing = true;
4975
4976 // Match all browsers that use WebKit as the layout engine in iOS devices,
4977 // such as Safari for iOS, Chrome for iOS, and in-app browsers.
4978 var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
4979 var done = function done(naturalWidth, naturalHeight) {
4980 assign(_this2.imageData, {
4981 naturalWidth: naturalWidth,
4982 naturalHeight: naturalHeight,
4983 aspectRatio: naturalWidth / naturalHeight
4984 });
4985 _this2.initialImageData = assign({}, _this2.imageData);
4986 _this2.sizing = false;
4987 _this2.sized = true;
4988 _this2.build();
4989 };
4990
4991 // Most modern browsers (excepts iOS WebKit)
4992 if (image.naturalWidth && !isIOSWebKit) {
4993 done(image.naturalWidth, image.naturalHeight);
4994 return;
4995 }
4996 var sizingImage = document.createElement('img');
4997 var body = document.body || document.documentElement;
4998 this.sizingImage = sizingImage;
4999 sizingImage.onload = function () {
5000 done(sizingImage.width, sizingImage.height);
5001 if (!isIOSWebKit) {
5002 body.removeChild(sizingImage);
5003 }
5004 };
5005 sizingImage.src = image.src;
5006
5007 // iOS WebKit will convert the image automatically
5008 // with its orientation once append it into DOM (#279)
5009 if (!isIOSWebKit) {
5010 sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
5011 body.appendChild(sizingImage);
5012 }
5013 }
5014 }, {
5015 key: "stop",
5016 value: function stop() {
5017 var image = this.image;
5018 image.onload = null;
5019 image.onerror = null;
5020 image.parentNode.removeChild(image);
5021 this.image = null;
5022 }
5023 }, {
5024 key: "build",
5025 value: function build() {
5026 if (!this.sized || this.ready) {
5027 return;
5028 }
5029 var element = this.element,
5030 options = this.options,
5031 image = this.image;
5032
5033 // Create cropper elements
5034 var container = element.parentNode;
5035 var template = document.createElement('div');
5036 template.innerHTML = TEMPLATE;
5037 var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
5038 var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
5039 var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
5040 var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
5041 var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
5042 this.container = container;
5043 this.cropper = cropper;
5044 this.canvas = canvas;
5045 this.dragBox = dragBox;
5046 this.cropBox = cropBox;
5047 this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
5048 this.face = face;
5049 canvas.appendChild(image);
5050
5051 // Hide the original image
5052 addClass(element, CLASS_HIDDEN);
5053
5054 // Inserts the cropper after to the current image
5055 container.insertBefore(cropper, element.nextSibling);
5056
5057 // Show the hidden image
5058 removeClass(image, CLASS_HIDE);
5059 this.initPreview();
5060 this.bind();
5061 options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
5062 options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
5063 options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
5064 addClass(cropBox, CLASS_HIDDEN);
5065 if (!options.guides) {
5066 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
5067 }
5068 if (!options.center) {
5069 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
5070 }
5071 if (options.background) {
5072 addClass(cropper, "".concat(NAMESPACE, "-bg"));
5073 }
5074 if (!options.highlight) {
5075 addClass(face, CLASS_INVISIBLE);
5076 }
5077 if (options.cropBoxMovable) {
5078 addClass(face, CLASS_MOVE);
5079 setData(face, DATA_ACTION, ACTION_ALL);
5080 }
5081 if (!options.cropBoxResizable) {
5082 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
5083 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
5084 }
5085 this.render();
5086 this.ready = true;
5087 this.setDragMode(options.dragMode);
5088 if (options.autoCrop) {
5089 this.crop();
5090 }
5091 this.setData(options.data);
5092 if (isFunction(options.ready)) {
5093 addListener(element, EVENT_READY, options.ready, {
5094 once: true
5095 });
5096 }
5097 dispatchEvent(element, EVENT_READY);
5098 }
5099 }, {
5100 key: "unbuild",
5101 value: function unbuild() {
5102 if (!this.ready) {
5103 return;
5104 }
5105 this.ready = false;
5106 this.unbind();
5107 this.resetPreview();
5108 var parentNode = this.cropper.parentNode;
5109 if (parentNode) {
5110 parentNode.removeChild(this.cropper);
5111 }
5112 removeClass(this.element, CLASS_HIDDEN);
5113 }
5114 }, {
5115 key: "uncreate",
5116 value: function uncreate() {
5117 if (this.ready) {
5118 this.unbuild();
5119 this.ready = false;
5120 this.cropped = false;
5121 } else if (this.sizing) {
5122 this.sizingImage.onload = null;
5123 this.sizing = false;
5124 this.sized = false;
5125 } else if (this.reloading) {
5126 this.xhr.onabort = null;
5127 this.xhr.abort();
5128 } else if (this.image) {
5129 this.stop();
5130 }
5131 }
5132
5133 /**
5134 * Get the no conflict cropper class.
5135 * @returns {Cropper} The cropper class.
5136 */
5137 }], [{
5138 key: "noConflict",
5139 value: function noConflict() {
5140 window.Cropper = AnotherCropper;
5141 return Cropper;
5142 }
5143
5144 /**
5145 * Change the default options.
5146 * @param {Object} options - The new default options.
5147 */
5148 }, {
5149 key: "setDefaults",
5150 value: function setDefaults(options) {
5151 assign(DEFAULTS, isPlainObject(options) && options);
5152 }
5153 }]);
5154 }();
5155 assign(Cropper.prototype, render, preview, events, handlers, change, methods);
5156
5157 return Cropper;
5158
5159 }));
5160
5161
5162 /***/ },
5163
5164 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css"
5165 /*!***************************************************************************************!*\
5166 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css ***!
5167 \***************************************************************************************/
5168 (module, __webpack_exports__, __webpack_require__) {
5169
5170 "use strict";
5171 __webpack_require__.r(__webpack_exports__);
5172 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5173 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5174 /* harmony export */ });
5175 /* 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");
5176 /* 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__);
5177 /* 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");
5178 /* 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__);
5179 /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../css-loader/dist/runtime/getUrl.js */ "./node_modules/css-loader/dist/runtime/getUrl.js");
5180 /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__);
5181 // Imports
5182
5183
5184
5185 var ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(/*! data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC */ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"), __webpack_require__.b);
5186 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()));
5187 var ___CSS_LOADER_URL_REPLACEMENT_0___ = _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_0___);
5188 // Module
5189 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
5190 * Cropper.js v1.6.2
5191 * https://fengyuanchen.github.io/cropperjs
5192 *
5193 * Copyright 2015-present Chen Fengyuan
5194 * Released under the MIT license
5195 *
5196 * Date: 2024-04-21T07:43:02.731Z
5197 */
5198
5199 .cropper-container {
5200 direction: ltr;
5201 font-size: 0;
5202 line-height: 0;
5203 position: relative;
5204 -ms-touch-action: none;
5205 touch-action: none;
5206 -webkit-touch-callout: none;
5207 -webkit-user-select: none;
5208 -moz-user-select: none;
5209 -ms-user-select: none;
5210 user-select: none;
5211 }
5212
5213 .cropper-container img {
5214 backface-visibility: hidden;
5215 display: block;
5216 height: 100%;
5217 image-orientation: 0deg;
5218 max-height: none !important;
5219 max-width: none !important;
5220 min-height: 0 !important;
5221 min-width: 0 !important;
5222 width: 100%;
5223 }
5224
5225 .cropper-wrap-box,
5226 .cropper-canvas,
5227 .cropper-drag-box,
5228 .cropper-crop-box,
5229 .cropper-modal {
5230 bottom: 0;
5231 left: 0;
5232 position: absolute;
5233 right: 0;
5234 top: 0;
5235 }
5236
5237 .cropper-wrap-box,
5238 .cropper-canvas {
5239 overflow: hidden;
5240 }
5241
5242 .cropper-drag-box {
5243 background-color: #fff;
5244 opacity: 0;
5245 }
5246
5247 .cropper-modal {
5248 background-color: #000;
5249 opacity: 0.5;
5250 }
5251
5252 .cropper-view-box {
5253 display: block;
5254 height: 100%;
5255 outline: 1px solid #39f;
5256 outline-color: rgba(51, 153, 255, 0.75);
5257 overflow: hidden;
5258 width: 100%;
5259 }
5260
5261 .cropper-dashed {
5262 border: 0 dashed #eee;
5263 display: block;
5264 opacity: 0.5;
5265 position: absolute;
5266 }
5267
5268 .cropper-dashed.dashed-h {
5269 border-bottom-width: 1px;
5270 border-top-width: 1px;
5271 height: calc(100% / 3);
5272 left: 0;
5273 top: calc(100% / 3);
5274 width: 100%;
5275 }
5276
5277 .cropper-dashed.dashed-v {
5278 border-left-width: 1px;
5279 border-right-width: 1px;
5280 height: 100%;
5281 left: calc(100% / 3);
5282 top: 0;
5283 width: calc(100% / 3);
5284 }
5285
5286 .cropper-center {
5287 display: block;
5288 height: 0;
5289 left: 50%;
5290 opacity: 0.75;
5291 position: absolute;
5292 top: 50%;
5293 width: 0;
5294 }
5295
5296 .cropper-center::before,
5297 .cropper-center::after {
5298 background-color: #eee;
5299 content: ' ';
5300 display: block;
5301 position: absolute;
5302 }
5303
5304 .cropper-center::before {
5305 height: 1px;
5306 left: -3px;
5307 top: 0;
5308 width: 7px;
5309 }
5310
5311 .cropper-center::after {
5312 height: 7px;
5313 left: 0;
5314 top: -3px;
5315 width: 1px;
5316 }
5317
5318 .cropper-face,
5319 .cropper-line,
5320 .cropper-point {
5321 display: block;
5322 height: 100%;
5323 opacity: 0.1;
5324 position: absolute;
5325 width: 100%;
5326 }
5327
5328 .cropper-face {
5329 background-color: #fff;
5330 left: 0;
5331 top: 0;
5332 }
5333
5334 .cropper-line {
5335 background-color: #39f;
5336 }
5337
5338 .cropper-line.line-e {
5339 cursor: ew-resize;
5340 right: -3px;
5341 top: 0;
5342 width: 5px;
5343 }
5344
5345 .cropper-line.line-n {
5346 cursor: ns-resize;
5347 height: 5px;
5348 left: 0;
5349 top: -3px;
5350 }
5351
5352 .cropper-line.line-w {
5353 cursor: ew-resize;
5354 left: -3px;
5355 top: 0;
5356 width: 5px;
5357 }
5358
5359 .cropper-line.line-s {
5360 bottom: -3px;
5361 cursor: ns-resize;
5362 height: 5px;
5363 left: 0;
5364 }
5365
5366 .cropper-point {
5367 background-color: #39f;
5368 height: 5px;
5369 opacity: 0.75;
5370 width: 5px;
5371 }
5372
5373 .cropper-point.point-e {
5374 cursor: ew-resize;
5375 margin-top: -3px;
5376 right: -3px;
5377 top: 50%;
5378 }
5379
5380 .cropper-point.point-n {
5381 cursor: ns-resize;
5382 left: 50%;
5383 margin-left: -3px;
5384 top: -3px;
5385 }
5386
5387 .cropper-point.point-w {
5388 cursor: ew-resize;
5389 left: -3px;
5390 margin-top: -3px;
5391 top: 50%;
5392 }
5393
5394 .cropper-point.point-s {
5395 bottom: -3px;
5396 cursor: s-resize;
5397 left: 50%;
5398 margin-left: -3px;
5399 }
5400
5401 .cropper-point.point-ne {
5402 cursor: nesw-resize;
5403 right: -3px;
5404 top: -3px;
5405 }
5406
5407 .cropper-point.point-nw {
5408 cursor: nwse-resize;
5409 left: -3px;
5410 top: -3px;
5411 }
5412
5413 .cropper-point.point-sw {
5414 bottom: -3px;
5415 cursor: nesw-resize;
5416 left: -3px;
5417 }
5418
5419 .cropper-point.point-se {
5420 bottom: -3px;
5421 cursor: nwse-resize;
5422 height: 20px;
5423 opacity: 1;
5424 right: -3px;
5425 width: 20px;
5426 }
5427
5428 @media (min-width: 768px) {
5429
5430 .cropper-point.point-se {
5431 height: 15px;
5432 width: 15px;
5433 }
5434 }
5435
5436 @media (min-width: 992px) {
5437
5438 .cropper-point.point-se {
5439 height: 10px;
5440 width: 10px;
5441 }
5442 }
5443
5444 @media (min-width: 1200px) {
5445
5446 .cropper-point.point-se {
5447 height: 5px;
5448 opacity: 0.75;
5449 width: 5px;
5450 }
5451 }
5452
5453 .cropper-point.point-se::before {
5454 background-color: #39f;
5455 bottom: -50%;
5456 content: ' ';
5457 display: block;
5458 height: 200%;
5459 opacity: 0;
5460 position: absolute;
5461 right: -50%;
5462 width: 200%;
5463 }
5464
5465 .cropper-invisible {
5466 opacity: 0;
5467 }
5468
5469 .cropper-bg {
5470 background-image: url(${___CSS_LOADER_URL_REPLACEMENT_0___});
5471 }
5472
5473 .cropper-hide {
5474 display: block;
5475 height: 0;
5476 position: absolute;
5477 width: 0;
5478 }
5479
5480 .cropper-hidden {
5481 display: none !important;
5482 }
5483
5484 .cropper-move {
5485 cursor: move;
5486 }
5487
5488 .cropper-crop {
5489 cursor: crosshair;
5490 }
5491
5492 .cropper-disabled .cropper-drag-box,
5493 .cropper-disabled .cropper-face,
5494 .cropper-disabled .cropper-line,
5495 .cropper-disabled .cropper-point {
5496 cursor: not-allowed;
5497 }
5498 `, "",{"version":3,"sources":["webpack://./node_modules/cropperjs/dist/cropper.css"],"names":[],"mappings":"AAAA;;;;;;;;EAQE;;AAEF;EACE,cAAc;EACd,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,sBAAsB;MAClB,kBAAkB;EACtB,2BAA2B;EAC3B,yBAAyB;KACtB,sBAAsB;MACrB,qBAAqB;UACjB,iBAAiB;AAC3B;;AAEA;IACI,2BAA2B;IAC3B,cAAc;IACd,YAAY;IACZ,uBAAuB;IACvB,2BAA2B;IAC3B,0BAA0B;IAC1B,wBAAwB;IACxB,uBAAuB;IACvB,WAAW;EACb;;AAEF;;;;;EAKE,SAAS;EACT,OAAO;EACP,kBAAkB;EAClB,QAAQ;EACR,MAAM;AACR;;AAEA;;EAEE,gBAAgB;AAClB;;AAEA;EACE,sBAAsB;EACtB,UAAU;AACZ;;AAEA;EACE,sBAAsB;EACtB,YAAY;AACd;;AAEA;EACE,cAAc;EACd,YAAY;EACZ,uBAAuB;EACvB,uCAAuC;EACvC,gBAAgB;EAChB,WAAW;AACb;;AAEA;EACE,qBAAqB;EACrB,cAAc;EACd,YAAY;EACZ,kBAAkB;AACpB;;AAEA;IACI,wBAAwB;IACxB,qBAAqB;IACrB,sBAAsB;IACtB,OAAO;IACP,mBAAmB;IACnB,WAAW;EACb;;AAEF;IACI,sBAAsB;IACtB,uBAAuB;IACvB,YAAY;IACZ,oBAAoB;IACpB,MAAM;IACN,qBAAqB;EACvB;;AAEF;EACE,cAAc;EACd,SAAS;EACT,SAAS;EACT,aAAa;EACb,kBAAkB;EAClB,QAAQ;EACR,QAAQ;AACV;;AAEA;;IAEI,sBAAsB;IACtB,YAAY;IACZ,cAAc;IACd,kBAAkB;EACpB;;AAEF;IACI,WAAW;IACX,UAAU;IACV,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,WAAW;IACX,OAAO;IACP,SAAS;IACT,UAAU;EACZ;;AAEF;;;EAGE,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,kBAAkB;EAClB,WAAW;AACb;;AAEA;EACE,sBAAsB;EACtB,OAAO;EACP,MAAM;AACR;;AAEA;EACE,sBAAsB;AACxB;;AAEA;IACI,iBAAiB;IACjB,WAAW;IACX,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,iBAAiB;IACjB,WAAW;IACX,OAAO;IACP,SAAS;EACX;;AAEF;IACI,iBAAiB;IACjB,UAAU;IACV,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,YAAY;IACZ,iBAAiB;IACjB,WAAW;IACX,OAAO;EACT;;AAEF;EACE,sBAAsB;EACtB,WAAW;EACX,aAAa;EACb,UAAU;AACZ;;AAEA;IACI,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,QAAQ;EACV;;AAEF;IACI,iBAAiB;IACjB,SAAS;IACT,iBAAiB;IACjB,SAAS;EACX;;AAEF;IACI,iBAAiB;IACjB,UAAU;IACV,gBAAgB;IAChB,QAAQ;EACV;;AAEF;IACI,YAAY;IACZ,gBAAgB;IAChB,SAAS;IACT,iBAAiB;EACnB;;AAEF;IACI,mBAAmB;IACnB,WAAW;IACX,SAAS;EACX;;AAEF;IACI,mBAAmB;IACnB,UAAU;IACV,SAAS;EACX;;AAEF;IACI,YAAY;IACZ,mBAAmB;IACnB,UAAU;EACZ;;AAEF;IACI,YAAY;IACZ,mBAAmB;IACnB,YAAY;IACZ,UAAU;IACV,WAAW;IACX,WAAW;EACb;;AAEF;;AAEA;MACM,YAAY;MACZ,WAAW;EACf;IACE;;AAEJ;;AAEA;MACM,YAAY;MACZ,WAAW;EACf;IACE;;AAEJ;;AAEA;MACM,WAAW;MACX,aAAa;MACb,UAAU;EACd;IACE;;AAEJ;IACI,sBAAsB;IACtB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,YAAY;IACZ,UAAU;IACV,kBAAkB;IAClB,WAAW;IACX,WAAW;EACb;;AAEF;EACE,UAAU;AACZ;;AAEA;EACE,yDAA+Q;AACjR;;AAEA;EACE,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;AACV;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,iBAAiB;AACnB;;AAEA;;;;EAIE,mBAAmB;AACrB","sourcesContent":["/*!\n * Cropper.js v1.6.2\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2024-04-21T07:43:02.731Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n backface-visibility: hidden;\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n }\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: 0.5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline: 1px solid #39f;\n outline-color: rgba(51, 153, 255, 0.75);\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: 0.5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n }\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n }\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: 0.75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center::before,\n .cropper-center::after {\n background-color: #eee;\n content: ' ';\n display: block;\n position: absolute;\n }\n\n.cropper-center::before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n }\n\n.cropper-center::after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n }\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: 0.1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n }\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n }\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: 0.75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n }\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n }\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n }\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n }\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n }\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n }\n\n@media (min-width: 768px) {\n\n.cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n }\n\n@media (min-width: 992px) {\n\n.cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n }\n\n@media (min-width: 1200px) {\n\n.cropper-point.point-se {\n height: 5px;\n opacity: 0.75;\n width: 5px;\n }\n }\n\n.cropper-point.point-se::before {\n background-color: #39f;\n bottom: -50%;\n content: ' ';\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n }\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n"],"sourceRoot":""}]);
5499 // Exports
5500 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
5501
5502
5503 /***/ },
5504
5505 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
5506 /*!*****************************************************************************************!*\
5507 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
5508 \*****************************************************************************************/
5509 (module, __webpack_exports__, __webpack_require__) {
5510
5511 "use strict";
5512 __webpack_require__.r(__webpack_exports__);
5513 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5514 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5515 /* harmony export */ });
5516 /* 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");
5517 /* 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__);
5518 /* 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");
5519 /* 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__);
5520 // Imports
5521
5522
5523 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()));
5524 // Module
5525 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
5526 * Toastify js 1.12.0
5527 * https://github.com/apvarun/toastify-js
5528 * @license MIT licensed
5529 *
5530 * Copyright (C) 2018 Varun A P
5531 */
5532
5533 .toastify {
5534 padding: 12px 20px;
5535 color: #ffffff;
5536 display: inline-block;
5537 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
5538 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
5539 background: linear-gradient(135deg, #73a5ff, #5477f5);
5540 position: fixed;
5541 opacity: 0;
5542 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
5543 border-radius: 2px;
5544 cursor: pointer;
5545 text-decoration: none;
5546 max-width: calc(50% - 20px);
5547 z-index: 2147483647;
5548 }
5549
5550 .toastify.on {
5551 opacity: 1;
5552 }
5553
5554 .toast-close {
5555 background: transparent;
5556 border: 0;
5557 color: white;
5558 cursor: pointer;
5559 font-family: inherit;
5560 font-size: 1em;
5561 opacity: 0.4;
5562 padding: 0 5px;
5563 }
5564
5565 .toastify-right {
5566 right: 15px;
5567 }
5568
5569 .toastify-left {
5570 left: 15px;
5571 }
5572
5573 .toastify-top {
5574 top: -150px;
5575 }
5576
5577 .toastify-bottom {
5578 bottom: -150px;
5579 }
5580
5581 .toastify-rounded {
5582 border-radius: 25px;
5583 }
5584
5585 .toastify-avatar {
5586 width: 1.5em;
5587 height: 1.5em;
5588 margin: -7px 5px;
5589 border-radius: 2px;
5590 }
5591
5592 .toastify-center {
5593 margin-left: auto;
5594 margin-right: auto;
5595 left: 0;
5596 right: 0;
5597 max-width: fit-content;
5598 max-width: -moz-fit-content;
5599 }
5600
5601 @media only screen and (max-width: 360px) {
5602 .toastify-right, .toastify-left {
5603 margin-left: auto;
5604 margin-right: auto;
5605 left: 0;
5606 right: 0;
5607 max-width: fit-content;
5608 }
5609 }
5610 `, "",{"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":""}]);
5611 // Exports
5612 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
5613
5614
5615 /***/ },
5616
5617 /***/ "./node_modules/css-loader/dist/runtime/api.js"
5618 /*!*****************************************************!*\
5619 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
5620 \*****************************************************/
5621 (module) {
5622
5623 "use strict";
5624
5625
5626 /*
5627 MIT License http://www.opensource.org/licenses/mit-license.php
5628 Author Tobias Koppers @sokra
5629 */
5630 module.exports = function (cssWithMappingToString) {
5631 var list = [];
5632
5633 // return the list of modules as css string
5634 list.toString = function toString() {
5635 return this.map(function (item) {
5636 var content = "";
5637 var needLayer = typeof item[5] !== "undefined";
5638 if (item[4]) {
5639 content += "@supports (".concat(item[4], ") {");
5640 }
5641 if (item[2]) {
5642 content += "@media ".concat(item[2], " {");
5643 }
5644 if (needLayer) {
5645 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
5646 }
5647 content += cssWithMappingToString(item);
5648 if (needLayer) {
5649 content += "}";
5650 }
5651 if (item[2]) {
5652 content += "}";
5653 }
5654 if (item[4]) {
5655 content += "}";
5656 }
5657 return content;
5658 }).join("");
5659 };
5660
5661 // import a list of modules into the list
5662 list.i = function i(modules, media, dedupe, supports, layer) {
5663 if (typeof modules === "string") {
5664 modules = [[null, modules, undefined]];
5665 }
5666 var alreadyImportedModules = {};
5667 if (dedupe) {
5668 for (var k = 0; k < this.length; k++) {
5669 var id = this[k][0];
5670 if (id != null) {
5671 alreadyImportedModules[id] = true;
5672 }
5673 }
5674 }
5675 for (var _k = 0; _k < modules.length; _k++) {
5676 var item = [].concat(modules[_k]);
5677 if (dedupe && alreadyImportedModules[item[0]]) {
5678 continue;
5679 }
5680 if (typeof layer !== "undefined") {
5681 if (typeof item[5] === "undefined") {
5682 item[5] = layer;
5683 } else {
5684 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
5685 item[5] = layer;
5686 }
5687 }
5688 if (media) {
5689 if (!item[2]) {
5690 item[2] = media;
5691 } else {
5692 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
5693 item[2] = media;
5694 }
5695 }
5696 if (supports) {
5697 if (!item[4]) {
5698 item[4] = "".concat(supports);
5699 } else {
5700 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
5701 item[4] = supports;
5702 }
5703 }
5704 list.push(item);
5705 }
5706 };
5707 return list;
5708 };
5709
5710 /***/ },
5711
5712 /***/ "./node_modules/css-loader/dist/runtime/getUrl.js"
5713 /*!********************************************************!*\
5714 !*** ./node_modules/css-loader/dist/runtime/getUrl.js ***!
5715 \********************************************************/
5716 (module) {
5717
5718 "use strict";
5719
5720
5721 module.exports = function (url, options) {
5722 if (!options) {
5723 options = {};
5724 }
5725 if (!url) {
5726 return url;
5727 }
5728 url = String(url.__esModule ? url.default : url);
5729
5730 // If url is already wrapped in quotes, remove them
5731 if (/^['"].*['"]$/.test(url)) {
5732 url = url.slice(1, -1);
5733 }
5734 if (options.hash) {
5735 url += options.hash;
5736 }
5737
5738 // Should url be wrapped?
5739 // See https://drafts.csswg.org/css-values-3/#urls
5740 if (/["'() \t\n]|(%20)/.test(url) || options.needQuotes) {
5741 return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, "\\n"), "\"");
5742 }
5743 return url;
5744 };
5745
5746 /***/ },
5747
5748 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
5749 /*!************************************************************!*\
5750 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
5751 \************************************************************/
5752 (module) {
5753
5754 "use strict";
5755
5756
5757 module.exports = function (item) {
5758 var content = item[1];
5759 var cssMapping = item[3];
5760 if (!cssMapping) {
5761 return content;
5762 }
5763 if (typeof btoa === "function") {
5764 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
5765 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
5766 var sourceMapping = "/*# ".concat(data, " */");
5767 return [content].concat([sourceMapping]).join("\n");
5768 }
5769 return [content].join("\n");
5770 };
5771
5772 /***/ },
5773
5774 /***/ "./node_modules/cropperjs/dist/cropper.css"
5775 /*!*************************************************!*\
5776 !*** ./node_modules/cropperjs/dist/cropper.css ***!
5777 \*************************************************/
5778 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5779
5780 "use strict";
5781 __webpack_require__.r(__webpack_exports__);
5782 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5783 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5784 /* harmony export */ });
5785 /* 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");
5786 /* 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__);
5787 /* 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");
5788 /* 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__);
5789 /* 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");
5790 /* 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__);
5791 /* 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");
5792 /* 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__);
5793 /* 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");
5794 /* 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__);
5795 /* 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");
5796 /* 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__);
5797 /* harmony import */ var _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../../css-loader/dist/cjs.js!./cropper.css */ "./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css");
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809 var options = {};
5810
5811 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5812 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5813
5814 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5815
5816 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5817 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5818
5819 var update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
5820
5821
5822
5823
5824 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
5825
5826
5827 /***/ },
5828
5829 /***/ "./node_modules/toastify-js/src/toastify.css"
5830 /*!***************************************************!*\
5831 !*** ./node_modules/toastify-js/src/toastify.css ***!
5832 \***************************************************/
5833 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5834
5835 "use strict";
5836 __webpack_require__.r(__webpack_exports__);
5837 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5838 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5839 /* harmony export */ });
5840 /* 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");
5841 /* 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__);
5842 /* 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");
5843 /* 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__);
5844 /* 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");
5845 /* 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__);
5846 /* 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");
5847 /* 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__);
5848 /* 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");
5849 /* 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__);
5850 /* 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");
5851 /* 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__);
5852 /* 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");
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864 var options = {};
5865
5866 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5867 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5868
5869 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5870
5871 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5872 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5873
5874 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);
5875
5876
5877
5878
5879 /* 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);
5880
5881
5882 /***/ },
5883
5884 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
5885 /*!****************************************************************************!*\
5886 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5887 \****************************************************************************/
5888 (module) {
5889
5890 "use strict";
5891
5892
5893 var stylesInDOM = [];
5894 function getIndexByIdentifier(identifier) {
5895 var result = -1;
5896 for (var i = 0; i < stylesInDOM.length; i++) {
5897 if (stylesInDOM[i].identifier === identifier) {
5898 result = i;
5899 break;
5900 }
5901 }
5902 return result;
5903 }
5904 function modulesToDom(list, options) {
5905 var idCountMap = {};
5906 var identifiers = [];
5907 for (var i = 0; i < list.length; i++) {
5908 var item = list[i];
5909 var id = options.base ? item[0] + options.base : item[0];
5910 var count = idCountMap[id] || 0;
5911 var identifier = "".concat(id, " ").concat(count);
5912 idCountMap[id] = count + 1;
5913 var indexByIdentifier = getIndexByIdentifier(identifier);
5914 var obj = {
5915 css: item[1],
5916 media: item[2],
5917 sourceMap: item[3],
5918 supports: item[4],
5919 layer: item[5]
5920 };
5921 if (indexByIdentifier !== -1) {
5922 stylesInDOM[indexByIdentifier].references++;
5923 stylesInDOM[indexByIdentifier].updater(obj);
5924 } else {
5925 var updater = addElementStyle(obj, options);
5926 options.byIndex = i;
5927 stylesInDOM.splice(i, 0, {
5928 identifier: identifier,
5929 updater: updater,
5930 references: 1
5931 });
5932 }
5933 identifiers.push(identifier);
5934 }
5935 return identifiers;
5936 }
5937 function addElementStyle(obj, options) {
5938 var api = options.domAPI(options);
5939 api.update(obj);
5940 var updater = function updater(newObj) {
5941 if (newObj) {
5942 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5943 return;
5944 }
5945 api.update(obj = newObj);
5946 } else {
5947 api.remove();
5948 }
5949 };
5950 return updater;
5951 }
5952 module.exports = function (list, options) {
5953 options = options || {};
5954 list = list || [];
5955 var lastIdentifiers = modulesToDom(list, options);
5956 return function update(newList) {
5957 newList = newList || [];
5958 for (var i = 0; i < lastIdentifiers.length; i++) {
5959 var identifier = lastIdentifiers[i];
5960 var index = getIndexByIdentifier(identifier);
5961 stylesInDOM[index].references--;
5962 }
5963 var newLastIdentifiers = modulesToDom(newList, options);
5964 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5965 var _identifier = lastIdentifiers[_i];
5966 var _index = getIndexByIdentifier(_identifier);
5967 if (stylesInDOM[_index].references === 0) {
5968 stylesInDOM[_index].updater();
5969 stylesInDOM.splice(_index, 1);
5970 }
5971 }
5972 lastIdentifiers = newLastIdentifiers;
5973 };
5974 };
5975
5976 /***/ },
5977
5978 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
5979 /*!********************************************************************!*\
5980 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5981 \********************************************************************/
5982 (module) {
5983
5984 "use strict";
5985
5986
5987 var memo = {};
5988
5989 /* istanbul ignore next */
5990 function getTarget(target) {
5991 if (typeof memo[target] === "undefined") {
5992 var styleTarget = document.querySelector(target);
5993
5994 // Special case to return head of iframe instead of iframe itself
5995 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5996 try {
5997 // This will throw an exception if access to iframe is blocked
5998 // due to cross-origin restrictions
5999 styleTarget = styleTarget.contentDocument.head;
6000 } catch (e) {
6001 // istanbul ignore next
6002 styleTarget = null;
6003 }
6004 }
6005 memo[target] = styleTarget;
6006 }
6007 return memo[target];
6008 }
6009
6010 /* istanbul ignore next */
6011 function insertBySelector(insert, style) {
6012 var target = getTarget(insert);
6013 if (!target) {
6014 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
6015 }
6016 target.appendChild(style);
6017 }
6018 module.exports = insertBySelector;
6019
6020 /***/ },
6021
6022 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
6023 /*!**********************************************************************!*\
6024 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
6025 \**********************************************************************/
6026 (module) {
6027
6028 "use strict";
6029
6030
6031 /* istanbul ignore next */
6032 function insertStyleElement(options) {
6033 var element = document.createElement("style");
6034 options.setAttributes(element, options.attributes);
6035 options.insert(element, options.options);
6036 return element;
6037 }
6038 module.exports = insertStyleElement;
6039
6040 /***/ },
6041
6042 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
6043 /*!**********************************************************************************!*\
6044 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
6045 \**********************************************************************************/
6046 (module, __unused_webpack_exports, __webpack_require__) {
6047
6048 "use strict";
6049
6050
6051 /* istanbul ignore next */
6052 function setAttributesWithoutAttributes(styleElement) {
6053 var nonce = true ? __webpack_require__.nc : 0;
6054 if (nonce) {
6055 styleElement.setAttribute("nonce", nonce);
6056 }
6057 }
6058 module.exports = setAttributesWithoutAttributes;
6059
6060 /***/ },
6061
6062 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
6063 /*!***************************************************************!*\
6064 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
6065 \***************************************************************/
6066 (module) {
6067
6068 "use strict";
6069
6070
6071 /* istanbul ignore next */
6072 function apply(styleElement, options, obj) {
6073 var css = "";
6074 if (obj.supports) {
6075 css += "@supports (".concat(obj.supports, ") {");
6076 }
6077 if (obj.media) {
6078 css += "@media ".concat(obj.media, " {");
6079 }
6080 var needLayer = typeof obj.layer !== "undefined";
6081 if (needLayer) {
6082 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
6083 }
6084 css += obj.css;
6085 if (needLayer) {
6086 css += "}";
6087 }
6088 if (obj.media) {
6089 css += "}";
6090 }
6091 if (obj.supports) {
6092 css += "}";
6093 }
6094 var sourceMap = obj.sourceMap;
6095 if (sourceMap && typeof btoa !== "undefined") {
6096 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
6097 }
6098
6099 // For old IE
6100 /* istanbul ignore if */
6101 options.styleTagTransform(css, styleElement, options.options);
6102 }
6103 function removeStyleElement(styleElement) {
6104 // istanbul ignore if
6105 if (styleElement.parentNode === null) {
6106 return false;
6107 }
6108 styleElement.parentNode.removeChild(styleElement);
6109 }
6110
6111 /* istanbul ignore next */
6112 function domAPI(options) {
6113 if (typeof document === "undefined") {
6114 return {
6115 update: function update() {},
6116 remove: function remove() {}
6117 };
6118 }
6119 var styleElement = options.insertStyleElement(options);
6120 return {
6121 update: function update(obj) {
6122 apply(styleElement, options, obj);
6123 },
6124 remove: function remove() {
6125 removeStyleElement(styleElement);
6126 }
6127 };
6128 }
6129 module.exports = domAPI;
6130
6131 /***/ },
6132
6133 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
6134 /*!*********************************************************************!*\
6135 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
6136 \*********************************************************************/
6137 (module) {
6138
6139 "use strict";
6140
6141
6142 /* istanbul ignore next */
6143 function styleTagTransform(css, styleElement) {
6144 if (styleElement.styleSheet) {
6145 styleElement.styleSheet.cssText = css;
6146 } else {
6147 while (styleElement.firstChild) {
6148 styleElement.removeChild(styleElement.firstChild);
6149 }
6150 styleElement.appendChild(document.createTextNode(css));
6151 }
6152 }
6153 module.exports = styleTagTransform;
6154
6155 /***/ },
6156
6157 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
6158 /*!**********************************************************!*\
6159 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
6160 \**********************************************************/
6161 (module) {
6162
6163 /*!
6164 * sweetalert2 v11.26.25
6165 * Released under the MIT License.
6166 */
6167 (function (global, factory) {
6168 true ? module.exports = factory() :
6169 0;
6170 })(this, (function () { 'use strict';
6171
6172 function _assertClassBrand(e, t, n) {
6173 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6174 throw new TypeError("Private element is not present on this object");
6175 }
6176 function _checkPrivateRedeclaration(e, t) {
6177 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6178 }
6179 function _classPrivateFieldGet2(s, a) {
6180 return s.get(_assertClassBrand(s, a));
6181 }
6182 function _classPrivateFieldInitSpec(e, t, a) {
6183 _checkPrivateRedeclaration(e, t), t.set(e, a);
6184 }
6185 function _classPrivateFieldSet2(s, a, r) {
6186 return s.set(_assertClassBrand(s, a), r), r;
6187 }
6188
6189 const RESTORE_FOCUS_TIMEOUT = 100;
6190
6191 /** @type {GlobalState} */
6192 const globalState = {};
6193 const focusPreviousActiveElement = () => {
6194 if (globalState.previousActiveElement instanceof HTMLElement) {
6195 globalState.previousActiveElement.focus();
6196 globalState.previousActiveElement = null;
6197 } else if (document.body) {
6198 document.body.focus();
6199 }
6200 };
6201
6202 /**
6203 * Restore previous active (focused) element
6204 *
6205 * @param {boolean} returnFocus
6206 * @returns {Promise<void>}
6207 */
6208 const restoreActiveElement = returnFocus => {
6209 return new Promise(resolve => {
6210 if (!returnFocus) {
6211 return resolve();
6212 }
6213 const x = window.scrollX;
6214 const y = window.scrollY;
6215 globalState.restoreFocusTimeout = setTimeout(() => {
6216 focusPreviousActiveElement();
6217 resolve();
6218 }, RESTORE_FOCUS_TIMEOUT); // issues/900
6219
6220 window.scrollTo(x, y);
6221 });
6222 };
6223
6224 const swalPrefix = 'swal2-';
6225
6226 /**
6227 * @typedef {Record<SwalClass, string>} SwalClasses
6228 */
6229
6230 /**
6231 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
6232 * @typedef {Record<SwalIcon, string>} SwalIcons
6233 */
6234
6235 /** @type {SwalClass[]} */
6236 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'];
6237 const swalClasses = classNames.reduce((acc, className) => {
6238 acc[className] = swalPrefix + className;
6239 return acc;
6240 }, /** @type {SwalClasses} */{});
6241
6242 /** @type {SwalIcon[]} */
6243 const icons = ['success', 'warning', 'info', 'question', 'error'];
6244 const iconTypes = icons.reduce((acc, icon) => {
6245 acc[icon] = swalPrefix + icon;
6246 return acc;
6247 }, /** @type {SwalIcons} */{});
6248
6249 const consolePrefix = 'SweetAlert2:';
6250
6251 /**
6252 * Capitalize the first letter of a string
6253 *
6254 * @param {string} str
6255 * @returns {string}
6256 */
6257 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
6258
6259 /**
6260 * Standardize console warnings
6261 *
6262 * @param {string | string[]} message
6263 */
6264 const warn = message => {
6265 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
6266 };
6267
6268 /**
6269 * Standardize console errors
6270 *
6271 * @param {string} message
6272 */
6273 const error = message => {
6274 console.error(`${consolePrefix} ${message}`);
6275 };
6276
6277 /**
6278 * Private global state for `warnOnce`
6279 *
6280 * @type {string[]}
6281 * @private
6282 */
6283 const previousWarnOnceMessages = [];
6284
6285 /**
6286 * Show a console warning, but only if it hasn't already been shown
6287 *
6288 * @param {string} message
6289 */
6290 const warnOnce = message => {
6291 if (!previousWarnOnceMessages.includes(message)) {
6292 previousWarnOnceMessages.push(message);
6293 warn(message);
6294 }
6295 };
6296
6297 /**
6298 * Show a one-time console warning about deprecated params/methods
6299 *
6300 * @param {string} deprecatedParam
6301 * @param {string?} useInstead
6302 */
6303 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
6304 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
6305 };
6306
6307 /**
6308 * If `arg` is a function, call it (with no arguments or context) and return the result.
6309 * Otherwise, just pass the value through
6310 *
6311 * @param {(() => *) | *} arg
6312 * @returns {*}
6313 */
6314 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
6315
6316 /**
6317 * @param {*} arg
6318 * @returns {boolean}
6319 */
6320 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
6321
6322 /**
6323 * @param {*} arg
6324 * @returns {Promise<*>}
6325 */
6326 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
6327
6328 /**
6329 * @param {*} arg
6330 * @returns {boolean}
6331 */
6332 const isPromise = arg => arg && Promise.resolve(arg) === arg;
6333
6334 /**
6335 * @returns {boolean}
6336 */
6337 const isFirefox = () => navigator.userAgent.includes('Firefox');
6338
6339 /**
6340 * Gets the popup container which contains the backdrop and the popup itself.
6341 *
6342 * @returns {HTMLElement | null}
6343 */
6344 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6345
6346 /**
6347 * @param {string} selectorString
6348 * @returns {HTMLElement | null}
6349 */
6350 const elementBySelector = selectorString => {
6351 const container = getContainer();
6352 return container ? container.querySelector(selectorString) : null;
6353 };
6354
6355 /**
6356 * @param {string} className
6357 * @returns {HTMLElement | null}
6358 */
6359 const elementByClass = className => {
6360 return elementBySelector(`.${className}`);
6361 };
6362
6363 /**
6364 * @returns {HTMLElement | null}
6365 */
6366 const getPopup = () => elementByClass(swalClasses.popup);
6367
6368 /**
6369 * @returns {HTMLElement | null}
6370 */
6371 const getIcon = () => elementByClass(swalClasses.icon);
6372
6373 /**
6374 * @returns {HTMLElement | null}
6375 */
6376 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6377
6378 /**
6379 * @returns {HTMLElement | null}
6380 */
6381 const getTitle = () => elementByClass(swalClasses.title);
6382
6383 /**
6384 * @returns {HTMLElement | null}
6385 */
6386 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6387
6388 /**
6389 * @returns {HTMLElement | null}
6390 */
6391 const getImage = () => elementByClass(swalClasses.image);
6392
6393 /**
6394 * @returns {HTMLElement | null}
6395 */
6396 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6397
6398 /**
6399 * @returns {HTMLElement | null}
6400 */
6401 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6402
6403 /**
6404 * @returns {HTMLButtonElement | null}
6405 */
6406 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6407
6408 /**
6409 * @returns {HTMLButtonElement | null}
6410 */
6411 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6412
6413 /**
6414 * @returns {HTMLButtonElement | null}
6415 */
6416 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6417
6418 /**
6419 * @returns {HTMLElement | null}
6420 */
6421 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6422
6423 /**
6424 * @returns {HTMLElement | null}
6425 */
6426 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6427
6428 /**
6429 * @returns {HTMLElement | null}
6430 */
6431 const getActions = () => elementByClass(swalClasses.actions);
6432
6433 /**
6434 * @returns {HTMLElement | null}
6435 */
6436 const getFooter = () => elementByClass(swalClasses.footer);
6437
6438 /**
6439 * @returns {HTMLElement | null}
6440 */
6441 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6442
6443 /**
6444 * @returns {HTMLElement | null}
6445 */
6446 const getCloseButton = () => elementByClass(swalClasses.close);
6447
6448 // https://github.com/jkup/focusable/blob/master/index.js
6449 const focusable = `
6450 a[href],
6451 area[href],
6452 input:not([disabled]),
6453 select:not([disabled]),
6454 textarea:not([disabled]),
6455 button:not([disabled]),
6456 iframe,
6457 object,
6458 embed,
6459 [tabindex="0"],
6460 [contenteditable],
6461 audio[controls],
6462 video[controls],
6463 summary
6464 `;
6465 /**
6466 * @returns {HTMLElement[]}
6467 */
6468 const getFocusableElements = () => {
6469 const popup = getPopup();
6470 if (!popup) {
6471 return [];
6472 }
6473 /** @type {NodeListOf<HTMLElement>} */
6474 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6475 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6476 // sort according to tabindex
6477 .sort((a, b) => {
6478 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6479 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6480 if (tabindexA > tabindexB) {
6481 return 1;
6482 } else if (tabindexA < tabindexB) {
6483 return -1;
6484 }
6485 return 0;
6486 });
6487
6488 /** @type {NodeListOf<HTMLElement>} */
6489 const otherFocusableElements = popup.querySelectorAll(focusable);
6490 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6491 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6492 };
6493
6494 /**
6495 * @returns {boolean}
6496 */
6497 const isModal = () => {
6498 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6499 };
6500
6501 /**
6502 * @returns {boolean}
6503 */
6504 const isToast = () => {
6505 const popup = getPopup();
6506 if (!popup) {
6507 return false;
6508 }
6509 return hasClass(popup, swalClasses.toast);
6510 };
6511
6512 /**
6513 * @returns {boolean}
6514 */
6515 const isLoading = () => {
6516 const popup = getPopup();
6517 if (!popup) {
6518 return false;
6519 }
6520 return popup.hasAttribute('data-loading');
6521 };
6522
6523 /**
6524 * Securely set innerHTML of an element
6525 * https://github.com/sweetalert2/sweetalert2/issues/1926
6526 *
6527 * @param {HTMLElement} elem
6528 * @param {string} html
6529 */
6530 const setInnerHtml = (elem, html) => {
6531 elem.textContent = '';
6532 if (html) {
6533 const parser = new DOMParser();
6534 const parsed = parser.parseFromString(html, `text/html`);
6535 const head = parsed.querySelector('head');
6536 if (head) {
6537 Array.from(head.childNodes).forEach(child => {
6538 elem.appendChild(child);
6539 });
6540 }
6541 const body = parsed.querySelector('body');
6542 if (body) {
6543 Array.from(body.childNodes).forEach(child => {
6544 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6545 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6546 } else {
6547 elem.appendChild(child);
6548 }
6549 });
6550 }
6551 }
6552 };
6553
6554 /**
6555 * @param {HTMLElement} elem
6556 * @param {string} className
6557 * @returns {boolean}
6558 */
6559 const hasClass = (elem, className) => {
6560 if (!className) {
6561 return false;
6562 }
6563 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
6564 };
6565
6566 /**
6567 * @param {HTMLElement} elem
6568 * @param {SweetAlertOptions} params
6569 */
6570 const removeCustomClasses = (elem, params) => {
6571 Array.from(elem.classList).forEach(className => {
6572 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6573 elem.classList.remove(className);
6574 }
6575 });
6576 };
6577
6578 /**
6579 * @param {HTMLElement} elem
6580 * @param {SweetAlertOptions} params
6581 * @param {string} className
6582 */
6583 const applyCustomClass = (elem, params, className) => {
6584 removeCustomClasses(elem, params);
6585 if (!params.customClass) {
6586 return;
6587 }
6588 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6589 if (!customClass) {
6590 return;
6591 }
6592 if (typeof customClass !== 'string' && !customClass.forEach) {
6593 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6594 return;
6595 }
6596 addClass(elem, customClass);
6597 };
6598
6599 /**
6600 * @param {HTMLElement} popup
6601 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6602 * @returns {HTMLInputElement | null}
6603 */
6604 const getInput$1 = (popup, inputClass) => {
6605 if (!inputClass) {
6606 return null;
6607 }
6608 switch (inputClass) {
6609 case 'select':
6610 case 'textarea':
6611 case 'file':
6612 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6613 case 'checkbox':
6614 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6615 case 'radio':
6616 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6617 case 'range':
6618 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6619 default:
6620 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6621 }
6622 };
6623
6624 /**
6625 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6626 */
6627 const focusInput = input => {
6628 input.focus();
6629
6630 // place cursor at end of text in text input
6631 if (input.type !== 'file') {
6632 // http://stackoverflow.com/a/2345915
6633 const val = input.value;
6634 input.value = '';
6635 input.value = val;
6636 }
6637 };
6638
6639 /**
6640 * @param {HTMLElement | HTMLElement[] | null} target
6641 * @param {string | string[] | readonly string[] | undefined} classList
6642 * @param {boolean} condition
6643 */
6644 const toggleClass = (target, classList, condition) => {
6645 if (!target || !classList) {
6646 return;
6647 }
6648 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
6649 const targets = Array.isArray(target) ? target : [target];
6650 targets.forEach(elem => {
6651 classes.forEach(className => {
6652 if (condition) {
6653 elem.classList.add(className);
6654 } else {
6655 elem.classList.remove(className);
6656 }
6657 });
6658 });
6659 };
6660
6661 /**
6662 * @param {HTMLElement | HTMLElement[] | null} target
6663 * @param {string | string[] | readonly string[] | undefined} classList
6664 */
6665 const addClass = (target, classList) => {
6666 toggleClass(target, classList, true);
6667 };
6668
6669 /**
6670 * @param {HTMLElement | HTMLElement[] | null} target
6671 * @param {string | string[] | readonly string[] | undefined} classList
6672 */
6673 const removeClass = (target, classList) => {
6674 toggleClass(target, classList, false);
6675 };
6676
6677 /**
6678 * Get direct child of an element by class name
6679 *
6680 * @param {HTMLElement} elem
6681 * @param {string} className
6682 * @returns {HTMLElement | undefined}
6683 */
6684 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
6685 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
6686
6687 /**
6688 * @param {HTMLElement} elem
6689 * @param {string} property
6690 * @param {string | number | null | undefined} value
6691 */
6692 const applyNumericalStyle = (elem, property, value) => {
6693 if (value === `${parseInt(`${value}`)}`) {
6694 value = parseInt(value);
6695 }
6696 if (value || value === 0) {
6697 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6698 } else {
6699 elem.style.removeProperty(property);
6700 }
6701 };
6702
6703 /**
6704 * @param {HTMLElement | null} elem
6705 * @param {string} display
6706 */
6707 const show = (elem, display = 'flex') => {
6708 if (!elem) {
6709 return;
6710 }
6711 elem.style.display = display;
6712 };
6713
6714 /**
6715 * @param {HTMLElement | null} elem
6716 */
6717 const hide = elem => {
6718 if (!elem) {
6719 return;
6720 }
6721 elem.style.display = 'none';
6722 };
6723
6724 /**
6725 * @param {HTMLElement | null} elem
6726 * @param {string} display
6727 */
6728 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6729 if (!elem) {
6730 return;
6731 }
6732 new MutationObserver(() => {
6733 toggle(elem, elem.innerHTML, display);
6734 }).observe(elem, {
6735 childList: true,
6736 subtree: true
6737 });
6738 };
6739
6740 /**
6741 * @param {HTMLElement} parent
6742 * @param {string} selector
6743 * @param {string} property
6744 * @param {string} value
6745 */
6746 const setStyle = (parent, selector, property, value) => {
6747 /** @type {HTMLElement | null} */
6748 const el = parent.querySelector(selector);
6749 if (el) {
6750 el.style.setProperty(property, value);
6751 }
6752 };
6753
6754 /**
6755 * @param {HTMLElement} elem
6756 * @param {boolean | string | null | undefined} condition
6757 * @param {string} display
6758 */
6759 const toggle = (elem, condition, display = 'flex') => {
6760 if (condition) {
6761 show(elem, display);
6762 } else {
6763 hide(elem);
6764 }
6765 };
6766
6767 /**
6768 * borrowed from jquery $(elem).is(':visible') implementation
6769 *
6770 * @param {HTMLElement | null} elem
6771 * @returns {boolean}
6772 */
6773 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6774
6775 /**
6776 * @returns {boolean}
6777 */
6778 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6779
6780 /**
6781 * @param {HTMLElement} elem
6782 * @returns {boolean}
6783 */
6784 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6785
6786 /**
6787 * @param {HTMLElement} element
6788 * @param {HTMLElement} stopElement
6789 * @returns {boolean}
6790 */
6791 const selfOrParentIsScrollable = (element, stopElement) => {
6792 let parent = /** @type {HTMLElement | null} */element;
6793 while (parent && parent !== stopElement) {
6794 if (isScrollable(parent)) {
6795 return true;
6796 }
6797 parent = parent.parentElement;
6798 }
6799 return false;
6800 };
6801
6802 /**
6803 * borrowed from https://stackoverflow.com/a/46352119
6804 *
6805 * @param {HTMLElement} elem
6806 * @returns {boolean}
6807 */
6808 const hasCssAnimation = elem => {
6809 const style = window.getComputedStyle(elem);
6810 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6811 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6812 return animDuration > 0 || transDuration > 0;
6813 };
6814
6815 /**
6816 * @param {number} timer
6817 * @param {boolean} reset
6818 */
6819 const animateTimerProgressBar = (timer, reset = false) => {
6820 const timerProgressBar = getTimerProgressBar();
6821 if (!timerProgressBar) {
6822 return;
6823 }
6824 if (isVisible$1(timerProgressBar)) {
6825 if (reset) {
6826 timerProgressBar.style.transition = 'none';
6827 timerProgressBar.style.width = '100%';
6828 }
6829 setTimeout(() => {
6830 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6831 timerProgressBar.style.width = '0%';
6832 }, 10);
6833 }
6834 };
6835 const stopTimerProgressBar = () => {
6836 const timerProgressBar = getTimerProgressBar();
6837 if (!timerProgressBar) {
6838 return;
6839 }
6840 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6841 timerProgressBar.style.removeProperty('transition');
6842 timerProgressBar.style.width = '100%';
6843 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6844 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6845 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6846 };
6847
6848 /**
6849 * Detect Node env
6850 *
6851 * @returns {boolean}
6852 */
6853 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6854
6855 const sweetHTML = `
6856 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6857 <button type="button" class="${swalClasses.close}"></button>
6858 <ul class="${swalClasses['progress-steps']}"></ul>
6859 <div class="${swalClasses.icon}"></div>
6860 <img class="${swalClasses.image}" />
6861 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6862 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6863 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6864 <input type="file" class="${swalClasses.file}" />
6865 <div class="${swalClasses.range}">
6866 <input type="range" />
6867 <output></output>
6868 </div>
6869 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6870 <div class="${swalClasses.radio}"></div>
6871 <label class="${swalClasses.checkbox}">
6872 <input type="checkbox" id="${swalClasses.checkbox}" />
6873 <span class="${swalClasses.label}"></span>
6874 </label>
6875 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6876 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6877 <div class="${swalClasses.actions}">
6878 <div class="${swalClasses.loader}"></div>
6879 <button type="button" class="${swalClasses.confirm}"></button>
6880 <button type="button" class="${swalClasses.deny}"></button>
6881 <button type="button" class="${swalClasses.cancel}"></button>
6882 </div>
6883 <div class="${swalClasses.footer}"></div>
6884 <div class="${swalClasses['timer-progress-bar-container']}">
6885 <div class="${swalClasses['timer-progress-bar']}"></div>
6886 </div>
6887 </div>
6888 `.replace(/(^|\n)\s*/g, '');
6889
6890 /**
6891 * @returns {boolean}
6892 */
6893 const resetOldContainer = () => {
6894 const oldContainer = getContainer();
6895 if (!oldContainer) {
6896 return false;
6897 }
6898 oldContainer.remove();
6899 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6900 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6901 swalClasses['has-column']]);
6902 return true;
6903 };
6904 const resetValidationMessage$1 = () => {
6905 if (globalState.currentInstance) {
6906 globalState.currentInstance.resetValidationMessage();
6907 }
6908 };
6909 const addInputChangeListeners = () => {
6910 const popup = getPopup();
6911 if (!popup) {
6912 return;
6913 }
6914 const input = getDirectChildByClass(popup, swalClasses.input);
6915 const file = getDirectChildByClass(popup, swalClasses.file);
6916 /** @type {HTMLInputElement | null} */
6917 const range = popup.querySelector(`.${swalClasses.range} input`);
6918 /** @type {HTMLOutputElement | null} */
6919 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6920 const select = getDirectChildByClass(popup, swalClasses.select);
6921 /** @type {HTMLInputElement | null} */
6922 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6923 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6924 if (input) {
6925 input.oninput = resetValidationMessage$1;
6926 }
6927 if (file) {
6928 file.onchange = resetValidationMessage$1;
6929 }
6930 if (select) {
6931 select.onchange = resetValidationMessage$1;
6932 }
6933 if (checkbox) {
6934 checkbox.onchange = resetValidationMessage$1;
6935 }
6936 if (textarea) {
6937 textarea.oninput = resetValidationMessage$1;
6938 }
6939 if (range && rangeOutput) {
6940 range.oninput = () => {
6941 resetValidationMessage$1();
6942 rangeOutput.value = range.value;
6943 };
6944 range.onchange = () => {
6945 resetValidationMessage$1();
6946 rangeOutput.value = range.value;
6947 };
6948 }
6949 };
6950
6951 /**
6952 * @param {string | HTMLElement} target
6953 * @returns {HTMLElement}
6954 */
6955 const getTarget = target => {
6956 if (typeof target === 'string') {
6957 const element = document.querySelector(target);
6958 if (!element) {
6959 throw new Error(`Target element "${target}" not found`);
6960 }
6961 return /** @type {HTMLElement} */element;
6962 }
6963 return target;
6964 };
6965
6966 /**
6967 * @param {SweetAlertOptions} params
6968 */
6969 const setupAccessibility = params => {
6970 const popup = getPopup();
6971 if (!popup) {
6972 return;
6973 }
6974 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6975 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6976 if (!params.toast) {
6977 popup.setAttribute('aria-modal', 'true');
6978 }
6979 };
6980
6981 /**
6982 * @param {HTMLElement} targetElement
6983 */
6984 const setupRTL = targetElement => {
6985 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6986 addClass(getContainer(), swalClasses.rtl);
6987 globalState.isRTL = true;
6988 }
6989 };
6990
6991 /**
6992 * Add modal + backdrop to DOM
6993 *
6994 * @param {SweetAlertOptions} params
6995 */
6996 const init = params => {
6997 // Clean up the old popup container if it exists
6998 const oldContainerExisted = resetOldContainer();
6999 if (isNodeEnv()) {
7000 error('SweetAlert2 requires document to initialize');
7001 return;
7002 }
7003 const container = document.createElement('div');
7004 container.className = swalClasses.container;
7005 if (oldContainerExisted) {
7006 addClass(container, swalClasses['no-transition']);
7007 }
7008 setInnerHtml(container, sweetHTML);
7009 container.dataset['swal2Theme'] = params.theme;
7010 const targetElement = getTarget(params.target || 'body');
7011 targetElement.appendChild(container);
7012 if (params.topLayer) {
7013 container.setAttribute('popover', '');
7014 container.showPopover();
7015 }
7016 setupAccessibility(params);
7017 setupRTL(targetElement);
7018 addInputChangeListeners();
7019 };
7020
7021 /**
7022 * @param {HTMLElement | object | string} param
7023 * @param {HTMLElement} target
7024 */
7025 const parseHtmlToContainer = (param, target) => {
7026 // DOM element
7027 if (param instanceof HTMLElement) {
7028 target.appendChild(param);
7029 }
7030
7031 // Object
7032 else if (typeof param === 'object') {
7033 handleObject(param, target);
7034 }
7035
7036 // Plain string
7037 else if (param) {
7038 setInnerHtml(target, param);
7039 }
7040 };
7041
7042 /**
7043 * @param {object} param
7044 * @param {HTMLElement} target
7045 */
7046 const handleObject = (param, target) => {
7047 // JQuery element(s)
7048 if ('jquery' in param) {
7049 handleJqueryElem(target, param);
7050 }
7051
7052 // For other objects use their string representation
7053 else {
7054 setInnerHtml(target, param.toString());
7055 }
7056 };
7057
7058 /**
7059 * @param {HTMLElement} target
7060 * @param {any} elem
7061 */
7062 const handleJqueryElem = (target, elem) => {
7063 target.textContent = '';
7064 if (0 in elem) {
7065 for (let i = 0; i in elem; i++) {
7066 target.appendChild(elem[i].cloneNode(true));
7067 }
7068 } else {
7069 target.appendChild(elem.cloneNode(true));
7070 }
7071 };
7072
7073 /**
7074 * @param {SweetAlert} instance
7075 * @param {SweetAlertOptions} params
7076 */
7077 const renderActions = (instance, params) => {
7078 const actions = getActions();
7079 const loader = getLoader();
7080 if (!actions || !loader) {
7081 return;
7082 }
7083
7084 // Actions (buttons) wrapper
7085 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
7086 hide(actions);
7087 } else {
7088 show(actions);
7089 }
7090
7091 // Custom class
7092 applyCustomClass(actions, params, 'actions');
7093
7094 // Render all the buttons
7095 renderButtons(actions, loader, params);
7096
7097 // Loader
7098 setInnerHtml(loader, params.loaderHtml || '');
7099 applyCustomClass(loader, params, 'loader');
7100 };
7101
7102 /**
7103 * @param {HTMLElement} actions
7104 * @param {HTMLElement} loader
7105 * @param {SweetAlertOptions} params
7106 */
7107 function renderButtons(actions, loader, params) {
7108 const confirmButton = getConfirmButton();
7109 const denyButton = getDenyButton();
7110 const cancelButton = getCancelButton();
7111 if (!confirmButton || !denyButton || !cancelButton) {
7112 return;
7113 }
7114
7115 // Render buttons
7116 renderButton(confirmButton, 'confirm', params);
7117 renderButton(denyButton, 'deny', params);
7118 renderButton(cancelButton, 'cancel', params);
7119 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
7120 if (params.reverseButtons) {
7121 if (params.toast) {
7122 actions.insertBefore(cancelButton, confirmButton);
7123 actions.insertBefore(denyButton, confirmButton);
7124 } else {
7125 actions.insertBefore(cancelButton, loader);
7126 actions.insertBefore(denyButton, loader);
7127 actions.insertBefore(confirmButton, loader);
7128 }
7129 }
7130 }
7131
7132 /**
7133 * @param {HTMLElement} confirmButton
7134 * @param {HTMLElement} denyButton
7135 * @param {HTMLElement} cancelButton
7136 * @param {SweetAlertOptions} params
7137 */
7138 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
7139 if (!params.buttonsStyling) {
7140 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7141 return;
7142 }
7143 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7144
7145 // Apply custom background colors and outline colors to action buttons
7146 /** @type {[HTMLElement, string, string | undefined][]} */
7147 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
7148 buttons.forEach(([button, type, color]) => {
7149 if (color) {
7150 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
7151 }
7152 applyOutlineColor(button);
7153 });
7154 }
7155
7156 /**
7157 * @param {HTMLElement} button
7158 */
7159 function applyOutlineColor(button) {
7160 const buttonStyle = window.getComputedStyle(button);
7161 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7162 // If the button already has a custom outline color, no need to change it
7163 return;
7164 }
7165 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7166 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7167 }
7168
7169 /**
7170 * @param {HTMLElement} button
7171 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7172 * @param {SweetAlertOptions} params
7173 */
7174 function renderButton(button, buttonType, params) {
7175 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7176 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7177 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7178 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7179
7180 // Add buttons custom classes
7181 button.className = swalClasses[buttonType];
7182 applyCustomClass(button, params, `${buttonType}Button`);
7183 }
7184
7185 /**
7186 * @param {SweetAlert} instance
7187 * @param {SweetAlertOptions} params
7188 */
7189 const renderCloseButton = (instance, params) => {
7190 const closeButton = getCloseButton();
7191 if (!closeButton) {
7192 return;
7193 }
7194 setInnerHtml(closeButton, params.closeButtonHtml || '');
7195
7196 // Custom class
7197 applyCustomClass(closeButton, params, 'closeButton');
7198 toggle(closeButton, params.showCloseButton);
7199 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7200 };
7201
7202 /**
7203 * @param {SweetAlert} instance
7204 * @param {SweetAlertOptions} params
7205 */
7206 const renderContainer = (instance, params) => {
7207 const container = getContainer();
7208 if (!container) {
7209 return;
7210 }
7211 handleBackdropParam(container, params.backdrop);
7212 handlePositionParam(container, params.position);
7213 handleGrowParam(container, params.grow);
7214
7215 // Custom class
7216 applyCustomClass(container, params, 'container');
7217 };
7218
7219 /**
7220 * @param {HTMLElement} container
7221 * @param {SweetAlertOptions['backdrop']} backdrop
7222 */
7223 function handleBackdropParam(container, backdrop) {
7224 if (typeof backdrop === 'string') {
7225 container.style.background = backdrop;
7226 } else if (!backdrop) {
7227 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7228 }
7229 }
7230
7231 /**
7232 * @param {HTMLElement} container
7233 * @param {SweetAlertOptions['position']} position
7234 */
7235 function handlePositionParam(container, position) {
7236 if (!position) {
7237 return;
7238 }
7239 if (position in swalClasses) {
7240 addClass(container, swalClasses[position]);
7241 } else {
7242 warn('The "position" parameter is not valid, defaulting to "center"');
7243 addClass(container, swalClasses.center);
7244 }
7245 }
7246
7247 /**
7248 * @param {HTMLElement} container
7249 * @param {SweetAlertOptions['grow']} grow
7250 */
7251 function handleGrowParam(container, grow) {
7252 if (!grow) {
7253 return;
7254 }
7255 addClass(container, swalClasses[`grow-${grow}`]);
7256 }
7257
7258 /**
7259 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7260 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7261 * This is the approach that Babel will probably take to implement private methods/fields
7262 * https://github.com/tc39/proposal-private-methods
7263 * https://github.com/babel/babel/pull/7555
7264 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7265 * then we can use that language feature.
7266 */
7267
7268 var privateProps = {
7269 innerParams: new WeakMap(),
7270 domCache: new WeakMap(),
7271 focusedElement: new WeakMap()
7272 };
7273
7274 /// <reference path="../../../../sweetalert2.d.ts"/>
7275
7276
7277 /** @type {InputClass[]} */
7278 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7279
7280 /**
7281 * @param {SweetAlert} instance
7282 * @param {SweetAlertOptions} params
7283 */
7284 const renderInput = (instance, params) => {
7285 const popup = getPopup();
7286 if (!popup) {
7287 return;
7288 }
7289 const innerParams = privateProps.innerParams.get(instance);
7290 const rerender = !innerParams || params.input !== innerParams.input;
7291 inputClasses.forEach(inputClass => {
7292 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7293 if (!inputContainer) {
7294 return;
7295 }
7296
7297 // set attributes
7298 setAttributes(inputClass, params.inputAttributes);
7299
7300 // set class
7301 inputContainer.className = swalClasses[inputClass];
7302 if (rerender) {
7303 hide(inputContainer);
7304 }
7305 });
7306 if (params.input) {
7307 if (rerender) {
7308 showInput(params);
7309 }
7310 // set custom class
7311 setCustomClass(params);
7312 }
7313 };
7314
7315 /**
7316 * @param {SweetAlertOptions} params
7317 */
7318 const showInput = params => {
7319 if (!params.input) {
7320 return;
7321 }
7322 if (!renderInputType[params.input]) {
7323 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7324 return;
7325 }
7326 const inputContainer = getInputContainer(params.input);
7327 if (!inputContainer) {
7328 return;
7329 }
7330 const input = renderInputType[params.input](inputContainer, params);
7331 show(inputContainer);
7332
7333 // input autofocus
7334 if (params.inputAutoFocus) {
7335 setTimeout(() => {
7336 focusInput(input);
7337 });
7338 }
7339 };
7340
7341 /**
7342 * @param {HTMLInputElement} input
7343 */
7344 const removeAttributes = input => {
7345 for (const {
7346 name
7347 } of Array.from(input.attributes)) {
7348 if (!['id', 'type', 'value', 'style'].includes(name)) {
7349 input.removeAttribute(name);
7350 }
7351 }
7352 };
7353
7354 /**
7355 * @param {InputClass} inputClass
7356 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7357 */
7358 const setAttributes = (inputClass, inputAttributes) => {
7359 const popup = getPopup();
7360 if (!popup) {
7361 return;
7362 }
7363 const input = getInput$1(popup, inputClass);
7364 if (!input) {
7365 return;
7366 }
7367 removeAttributes(input);
7368 for (const attr in inputAttributes) {
7369 input.setAttribute(attr, inputAttributes[attr]);
7370 }
7371 };
7372
7373 /**
7374 * @param {SweetAlertOptions} params
7375 */
7376 const setCustomClass = params => {
7377 if (!params.input) {
7378 return;
7379 }
7380 const inputContainer = getInputContainer(params.input);
7381 if (inputContainer) {
7382 applyCustomClass(inputContainer, params, 'input');
7383 }
7384 };
7385
7386 /**
7387 * @param {HTMLInputElement | HTMLTextAreaElement} input
7388 * @param {SweetAlertOptions} params
7389 */
7390 const setInputPlaceholder = (input, params) => {
7391 if (!input.placeholder && params.inputPlaceholder) {
7392 input.placeholder = params.inputPlaceholder;
7393 }
7394 };
7395
7396 /**
7397 * @param {Input} input
7398 * @param {Input} prependTo
7399 * @param {SweetAlertOptions} params
7400 */
7401 const setInputLabel = (input, prependTo, params) => {
7402 if (params.inputLabel) {
7403 const label = document.createElement('label');
7404 const labelClass = swalClasses['input-label'];
7405 label.setAttribute('for', input.id);
7406 label.className = labelClass;
7407 if (typeof params.customClass === 'object') {
7408 addClass(label, params.customClass.inputLabel);
7409 }
7410 label.innerText = params.inputLabel;
7411 prependTo.insertAdjacentElement('beforebegin', label);
7412 }
7413 };
7414
7415 /**
7416 * @param {SweetAlertInput} inputType
7417 * @returns {HTMLElement | undefined}
7418 */
7419 const getInputContainer = inputType => {
7420 const popup = getPopup();
7421 if (!popup) {
7422 return;
7423 }
7424 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7425 };
7426
7427 /**
7428 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7429 * @param {SweetAlertOptions['inputValue']} inputValue
7430 */
7431 const checkAndSetInputValue = (input, inputValue) => {
7432 if (['string', 'number'].includes(typeof inputValue)) {
7433 input.value = `${inputValue}`;
7434 } else if (!isPromise(inputValue)) {
7435 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7436 }
7437 };
7438
7439 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7440 const renderInputType = {};
7441
7442 /**
7443 * @param {Input | HTMLElement} input
7444 * @param {SweetAlertOptions} params
7445 * @returns {Input}
7446 */
7447 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} */
7448 (input, params) => {
7449 // oxfmt-ignore
7450 const inputElement = /** @type {HTMLInputElement} */input;
7451 checkAndSetInputValue(inputElement, params.inputValue);
7452 setInputLabel(inputElement, inputElement, params);
7453 setInputPlaceholder(inputElement, params);
7454 // oxfmt-ignore
7455 inputElement.type = /** @type {string} */params.input;
7456 return inputElement;
7457 };
7458
7459 /**
7460 * @param {Input | HTMLElement} input
7461 * @param {SweetAlertOptions} params
7462 * @returns {Input}
7463 */
7464 renderInputType.file = (input, params) => {
7465 const inputElement = /** @type {HTMLInputElement} */input;
7466 setInputLabel(inputElement, inputElement, params);
7467 setInputPlaceholder(inputElement, params);
7468 return inputElement;
7469 };
7470
7471 /**
7472 * @param {Input | HTMLElement} range
7473 * @param {SweetAlertOptions} params
7474 * @returns {Input}
7475 */
7476 renderInputType.range = (range, params) => {
7477 const rangeContainer = /** @type {HTMLElement} */range;
7478 const rangeInput = rangeContainer.querySelector('input');
7479 const rangeOutput = rangeContainer.querySelector('output');
7480 if (rangeInput) {
7481 checkAndSetInputValue(rangeInput, params.inputValue);
7482 rangeInput.type = /** @type {string} */params.input;
7483 setInputLabel(rangeInput, /** @type {Input} */range, params);
7484 }
7485 if (rangeOutput) {
7486 checkAndSetInputValue(rangeOutput, params.inputValue);
7487 }
7488 return /** @type {Input} */range;
7489 };
7490
7491 /**
7492 * @param {Input | HTMLElement} select
7493 * @param {SweetAlertOptions} params
7494 * @returns {Input}
7495 */
7496 renderInputType.select = (select, params) => {
7497 const selectElement = /** @type {HTMLSelectElement} */select;
7498 selectElement.textContent = '';
7499 if (params.inputPlaceholder) {
7500 const placeholder = document.createElement('option');
7501 setInnerHtml(placeholder, params.inputPlaceholder);
7502 placeholder.value = '';
7503 placeholder.disabled = true;
7504 placeholder.selected = true;
7505 selectElement.appendChild(placeholder);
7506 }
7507 setInputLabel(selectElement, selectElement, params);
7508 return selectElement;
7509 };
7510
7511 /**
7512 * @param {Input | HTMLElement} radio
7513 * @returns {Input}
7514 */
7515 renderInputType.radio = radio => {
7516 const radioElement = /** @type {HTMLElement} */radio;
7517 radioElement.textContent = '';
7518 return /** @type {Input} */radio;
7519 };
7520
7521 /**
7522 * @param {Input | HTMLElement} checkboxContainer
7523 * @param {SweetAlertOptions} params
7524 * @returns {Input}
7525 */
7526 renderInputType.checkbox = (checkboxContainer, params) => {
7527 const popup = getPopup();
7528 if (!popup) {
7529 throw new Error('Popup not found');
7530 }
7531 const checkbox = getInput$1(popup, 'checkbox');
7532 if (!checkbox) {
7533 throw new Error('Checkbox input not found');
7534 }
7535 checkbox.value = '1';
7536 checkbox.checked = Boolean(params.inputValue);
7537 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7538 const label = containerElement.querySelector('span');
7539 if (label) {
7540 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7541 if (placeholderOrLabel) {
7542 setInnerHtml(label, placeholderOrLabel);
7543 }
7544 }
7545 return checkbox;
7546 };
7547
7548 /**
7549 * @param {Input | HTMLElement} textarea
7550 * @param {SweetAlertOptions} params
7551 * @returns {Input}
7552 */
7553 renderInputType.textarea = (textarea, params) => {
7554 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7555 checkAndSetInputValue(textareaElement, params.inputValue);
7556 setInputPlaceholder(textareaElement, params);
7557 setInputLabel(textareaElement, textareaElement, params);
7558
7559 /**
7560 * @param {HTMLElement} el
7561 * @returns {number}
7562 */
7563 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7564
7565 // https://github.com/sweetalert2/sweetalert2/issues/2291
7566 setTimeout(() => {
7567 // https://github.com/sweetalert2/sweetalert2/issues/1699
7568 if ('MutationObserver' in window) {
7569 const popup = getPopup();
7570 if (!popup) {
7571 return;
7572 }
7573 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7574 const textareaResizeHandler = () => {
7575 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7576 if (!document.body.contains(textareaElement)) {
7577 return;
7578 }
7579 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7580 const popupElement = getPopup();
7581 if (popupElement) {
7582 if (textareaWidth > initialPopupWidth) {
7583 popupElement.style.width = `${textareaWidth}px`;
7584 } else {
7585 applyNumericalStyle(popupElement, 'width', params.width);
7586 }
7587 }
7588 };
7589 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7590 attributes: true,
7591 attributeFilter: ['style']
7592 });
7593 }
7594 });
7595 return textareaElement;
7596 };
7597
7598 /**
7599 * @param {SweetAlert} instance
7600 * @param {SweetAlertOptions} params
7601 */
7602 const renderContent = (instance, params) => {
7603 const htmlContainer = getHtmlContainer();
7604 if (!htmlContainer) {
7605 return;
7606 }
7607 showWhenInnerHtmlPresent(htmlContainer);
7608 applyCustomClass(htmlContainer, params, 'htmlContainer');
7609
7610 // Content as HTML
7611 if (params.html) {
7612 parseHtmlToContainer(params.html, htmlContainer);
7613 show(htmlContainer, 'block');
7614 }
7615
7616 // Content as plain text
7617 else if (params.text) {
7618 htmlContainer.textContent = params.text;
7619 show(htmlContainer, 'block');
7620 }
7621
7622 // No content
7623 else {
7624 hide(htmlContainer);
7625 }
7626 renderInput(instance, params);
7627 };
7628
7629 /**
7630 * @param {SweetAlert} instance
7631 * @param {SweetAlertOptions} params
7632 */
7633 const renderFooter = (instance, params) => {
7634 const footer = getFooter();
7635 if (!footer) {
7636 return;
7637 }
7638 showWhenInnerHtmlPresent(footer);
7639 toggle(footer, Boolean(params.footer), 'block');
7640 if (params.footer) {
7641 parseHtmlToContainer(params.footer, footer);
7642 }
7643
7644 // Custom class
7645 applyCustomClass(footer, params, 'footer');
7646 };
7647
7648 /**
7649 * @param {SweetAlert} instance
7650 * @param {SweetAlertOptions} params
7651 */
7652 const renderIcon = (instance, params) => {
7653 const innerParams = privateProps.innerParams.get(instance);
7654 const icon = getIcon();
7655 if (!icon) {
7656 return;
7657 }
7658
7659 // if the given icon already rendered, apply the styling without re-rendering the icon
7660 if (innerParams && params.icon === innerParams.icon) {
7661 // Custom or default content
7662 setContent(icon, params);
7663 applyStyles(icon, params);
7664 return;
7665 }
7666 if (!params.icon && !params.iconHtml) {
7667 hide(icon);
7668 return;
7669 }
7670 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7671 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7672 hide(icon);
7673 return;
7674 }
7675 show(icon);
7676
7677 // Custom or default content
7678 setContent(icon, params);
7679 applyStyles(icon, params);
7680
7681 // Animate icon
7682 addClass(icon, params.showClass && params.showClass.icon);
7683
7684 // Re-adjust the success icon on system theme change
7685 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7686 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7687 };
7688
7689 /**
7690 * @param {HTMLElement} icon
7691 * @param {SweetAlertOptions} params
7692 */
7693 const applyStyles = (icon, params) => {
7694 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7695 if (params.icon !== iconType) {
7696 removeClass(icon, iconClassName);
7697 }
7698 }
7699 addClass(icon, params.icon && iconTypes[params.icon]);
7700
7701 // Icon color
7702 setColor(icon, params);
7703
7704 // Success icon background color
7705 adjustSuccessIconBackgroundColor();
7706
7707 // Custom class
7708 applyCustomClass(icon, params, 'icon');
7709 };
7710
7711 // Adjust success icon background color to match the popup background color
7712 const adjustSuccessIconBackgroundColor = () => {
7713 const popup = getPopup();
7714 if (!popup) {
7715 return;
7716 }
7717 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7718 /** @type {NodeListOf<HTMLElement>} */
7719 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7720 successIconParts.forEach(part => {
7721 part.style.backgroundColor = popupBackgroundColor;
7722 });
7723 };
7724
7725 /**
7726 *
7727 * @param {SweetAlertOptions} params
7728 * @returns {string}
7729 */
7730 const successIconHtml = params => `
7731 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7732 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7733 <div class="swal2-success-ring"></div>
7734 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7735 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7736 `;
7737 const errorIconHtml = `
7738 <span class="swal2-x-mark">
7739 <span class="swal2-x-mark-line-left"></span>
7740 <span class="swal2-x-mark-line-right"></span>
7741 </span>
7742 `;
7743
7744 /**
7745 * @param {HTMLElement} icon
7746 * @param {SweetAlertOptions} params
7747 */
7748 const setContent = (icon, params) => {
7749 if (!params.icon && !params.iconHtml) {
7750 return;
7751 }
7752 let oldContent = icon.innerHTML;
7753 let newContent = '';
7754 if (params.iconHtml) {
7755 newContent = iconContent(params.iconHtml);
7756 } else if (params.icon === 'success') {
7757 newContent = successIconHtml(params);
7758 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7759 } else if (params.icon === 'error') {
7760 newContent = errorIconHtml;
7761 } else if (params.icon) {
7762 const defaultIconHtml = {
7763 question: '?',
7764 warning: '!',
7765 info: 'i'
7766 };
7767 newContent = iconContent(defaultIconHtml[params.icon]);
7768 }
7769 if (oldContent.trim() !== newContent.trim()) {
7770 setInnerHtml(icon, newContent);
7771 }
7772 };
7773
7774 /**
7775 * @param {HTMLElement} icon
7776 * @param {SweetAlertOptions} params
7777 */
7778 const setColor = (icon, params) => {
7779 if (!params.iconColor) {
7780 return;
7781 }
7782 icon.style.color = params.iconColor;
7783 icon.style.borderColor = params.iconColor;
7784 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7785 setStyle(icon, sel, 'background-color', params.iconColor);
7786 }
7787 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7788 };
7789
7790 /**
7791 * @param {string} content
7792 * @returns {string}
7793 */
7794 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7795
7796 /**
7797 * @param {SweetAlert} instance
7798 * @param {SweetAlertOptions} params
7799 */
7800 const renderImage = (instance, params) => {
7801 const image = getImage();
7802 if (!image) {
7803 return;
7804 }
7805 if (!params.imageUrl) {
7806 hide(image);
7807 return;
7808 }
7809 show(image, '');
7810
7811 // Src, alt
7812 image.setAttribute('src', params.imageUrl);
7813 image.setAttribute('alt', params.imageAlt || '');
7814
7815 // Width, height
7816 applyNumericalStyle(image, 'width', params.imageWidth);
7817 applyNumericalStyle(image, 'height', params.imageHeight);
7818
7819 // Class
7820 image.className = swalClasses.image;
7821 applyCustomClass(image, params, 'image');
7822 };
7823
7824 let dragging = false;
7825 let mousedownX = 0;
7826 let mousedownY = 0;
7827 let initialX = 0;
7828 let initialY = 0;
7829
7830 /**
7831 * @param {HTMLElement} popup
7832 */
7833 const addDraggableListeners = popup => {
7834 popup.addEventListener('mousedown', down);
7835 document.body.addEventListener('mousemove', move);
7836 popup.addEventListener('mouseup', up);
7837 popup.addEventListener('touchstart', down);
7838 document.body.addEventListener('touchmove', move);
7839 popup.addEventListener('touchend', up);
7840 };
7841
7842 /**
7843 * @param {HTMLElement} popup
7844 */
7845 const removeDraggableListeners = popup => {
7846 popup.removeEventListener('mousedown', down);
7847 document.body.removeEventListener('mousemove', move);
7848 popup.removeEventListener('mouseup', up);
7849 popup.removeEventListener('touchstart', down);
7850 document.body.removeEventListener('touchmove', move);
7851 popup.removeEventListener('touchend', up);
7852 };
7853
7854 /**
7855 * @param {MouseEvent | TouchEvent} event
7856 */
7857 const down = event => {
7858 const popup = getPopup();
7859 if (!popup) {
7860 return;
7861 }
7862 const icon = getIcon();
7863 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7864 dragging = true;
7865 const clientXY = getClientXY(event);
7866 mousedownX = clientXY.clientX;
7867 mousedownY = clientXY.clientY;
7868 initialX = parseInt(popup.style.insetInlineStart) || 0;
7869 initialY = parseInt(popup.style.insetBlockStart) || 0;
7870 addClass(popup, 'swal2-dragging');
7871 }
7872 };
7873
7874 /**
7875 * @param {MouseEvent | TouchEvent} event
7876 */
7877 const move = event => {
7878 const popup = getPopup();
7879 if (!popup) {
7880 return;
7881 }
7882 if (dragging) {
7883 let {
7884 clientX,
7885 clientY
7886 } = getClientXY(event);
7887 const deltaX = clientX - mousedownX;
7888 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7889 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7890 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7891 }
7892 };
7893 const up = () => {
7894 const popup = getPopup();
7895 dragging = false;
7896 removeClass(popup, 'swal2-dragging');
7897 };
7898
7899 /**
7900 * @param {MouseEvent | TouchEvent} event
7901 * @returns {{ clientX: number, clientY: number }}
7902 */
7903 const getClientXY = event => {
7904 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
7905 return {
7906 clientX: source.clientX,
7907 clientY: source.clientY
7908 };
7909 };
7910
7911 /**
7912 * @param {SweetAlert} instance
7913 * @param {SweetAlertOptions} params
7914 */
7915 const renderPopup = (instance, params) => {
7916 const container = getContainer();
7917 const popup = getPopup();
7918 if (!container || !popup) {
7919 return;
7920 }
7921
7922 // Width
7923 // https://github.com/sweetalert2/sweetalert2/issues/2170
7924 if (params.toast) {
7925 applyNumericalStyle(container, 'width', params.width);
7926 popup.style.width = '100%';
7927 const loader = getLoader();
7928 if (loader) {
7929 popup.insertBefore(loader, getIcon());
7930 }
7931 } else {
7932 applyNumericalStyle(popup, 'width', params.width);
7933 }
7934
7935 // Padding
7936 applyNumericalStyle(popup, 'padding', params.padding);
7937
7938 // Color
7939 if (params.color) {
7940 popup.style.color = params.color;
7941 }
7942
7943 // Background
7944 if (params.background) {
7945 popup.style.background = params.background;
7946 }
7947 hide(getValidationMessage());
7948
7949 // Classes
7950 addClasses$1(popup, params);
7951 if (params.draggable && !params.toast) {
7952 addClass(popup, swalClasses.draggable);
7953 addDraggableListeners(popup);
7954 } else {
7955 removeClass(popup, swalClasses.draggable);
7956 removeDraggableListeners(popup);
7957 }
7958 };
7959
7960 /**
7961 * @param {HTMLElement} popup
7962 * @param {SweetAlertOptions} params
7963 */
7964 const addClasses$1 = (popup, params) => {
7965 const showClass = params.showClass || {};
7966 // Default Class + showClass when updating Swal.update({})
7967 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7968 if (params.toast) {
7969 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7970 addClass(popup, swalClasses.toast);
7971 } else {
7972 addClass(popup, swalClasses.modal);
7973 }
7974
7975 // Custom class
7976 applyCustomClass(popup, params, 'popup');
7977 // TODO: remove in the next major
7978 if (typeof params.customClass === 'string') {
7979 addClass(popup, params.customClass);
7980 }
7981
7982 // Icon class (#1842)
7983 if (params.icon) {
7984 addClass(popup, swalClasses[`icon-${params.icon}`]);
7985 }
7986 };
7987
7988 /**
7989 * @param {SweetAlert} instance
7990 * @param {SweetAlertOptions} params
7991 */
7992 const renderProgressSteps = (instance, params) => {
7993 const progressStepsContainer = getProgressSteps();
7994 if (!progressStepsContainer) {
7995 return;
7996 }
7997 const {
7998 progressSteps,
7999 currentProgressStep
8000 } = params;
8001 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8002 hide(progressStepsContainer);
8003 return;
8004 }
8005 show(progressStepsContainer);
8006 progressStepsContainer.textContent = '';
8007 if (currentProgressStep >= progressSteps.length) {
8008 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
8009 }
8010 progressSteps.forEach((step, index) => {
8011 const stepEl = createStepElement(step);
8012 progressStepsContainer.appendChild(stepEl);
8013 if (index === currentProgressStep) {
8014 addClass(stepEl, swalClasses['active-progress-step']);
8015 }
8016 if (index !== progressSteps.length - 1) {
8017 const lineEl = createLineElement(params);
8018 progressStepsContainer.appendChild(lineEl);
8019 }
8020 });
8021 };
8022
8023 /**
8024 * @param {string} step
8025 * @returns {HTMLLIElement}
8026 */
8027 const createStepElement = step => {
8028 const stepEl = document.createElement('li');
8029 addClass(stepEl, swalClasses['progress-step']);
8030 setInnerHtml(stepEl, step);
8031 return stepEl;
8032 };
8033
8034 /**
8035 * @param {SweetAlertOptions} params
8036 * @returns {HTMLLIElement}
8037 */
8038 const createLineElement = params => {
8039 const lineEl = document.createElement('li');
8040 addClass(lineEl, swalClasses['progress-step-line']);
8041 if (params.progressStepsDistance) {
8042 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
8043 }
8044 return lineEl;
8045 };
8046
8047 /**
8048 * @param {SweetAlert} instance
8049 * @param {SweetAlertOptions} params
8050 */
8051 const renderTitle = (instance, params) => {
8052 const title = getTitle();
8053 if (!title) {
8054 return;
8055 }
8056 showWhenInnerHtmlPresent(title);
8057 toggle(title, Boolean(params.title || params.titleText), 'block');
8058 if (params.title) {
8059 parseHtmlToContainer(params.title, title);
8060 }
8061 if (params.titleText) {
8062 title.innerText = params.titleText;
8063 }
8064
8065 // Custom class
8066 applyCustomClass(title, params, 'title');
8067 };
8068
8069 /**
8070 * @param {SweetAlert} instance
8071 * @param {SweetAlertOptions} params
8072 */
8073 const render = (instance, params) => {
8074 var _globalState$eventEmi;
8075 renderPopup(instance, params);
8076 renderContainer(instance, params);
8077 renderProgressSteps(instance, params);
8078 renderIcon(instance, params);
8079 renderImage(instance, params);
8080 renderTitle(instance, params);
8081 renderCloseButton(instance, params);
8082 renderContent(instance, params);
8083 renderActions(instance, params);
8084 renderFooter(instance, params);
8085 const popup = getPopup();
8086 if (typeof params.didRender === 'function' && popup) {
8087 params.didRender(popup);
8088 }
8089 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
8090 };
8091
8092 /*
8093 * Global function to determine if SweetAlert2 popup is shown
8094 */
8095 const isVisible = () => {
8096 return isVisible$1(getPopup());
8097 };
8098
8099 /*
8100 * Global function to click 'Confirm' button
8101 */
8102 const clickConfirm = () => {
8103 var _dom$getConfirmButton;
8104 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
8105 };
8106
8107 /*
8108 * Global function to click 'Deny' button
8109 */
8110 const clickDeny = () => {
8111 var _dom$getDenyButton;
8112 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
8113 };
8114
8115 /*
8116 * Global function to click 'Cancel' button
8117 */
8118 const clickCancel = () => {
8119 var _dom$getCancelButton;
8120 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
8121 };
8122
8123 /** @type {Record<DismissReason, DismissReason>} */
8124 const DismissReason = Object.freeze({
8125 cancel: 'cancel',
8126 backdrop: 'backdrop',
8127 close: 'close',
8128 esc: 'esc',
8129 timer: 'timer'
8130 });
8131
8132 /**
8133 * @param {GlobalState} globalState
8134 */
8135 const removeKeydownHandler = globalState => {
8136 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8137 const handler = /** @type {EventListenerOrEventListenerObject} */
8138 /** @type {unknown} */globalState.keydownHandler;
8139 globalState.keydownTarget.removeEventListener('keydown', handler, {
8140 capture: globalState.keydownListenerCapture
8141 });
8142 globalState.keydownHandlerAdded = false;
8143 }
8144 };
8145
8146 /**
8147 * @param {GlobalState} globalState
8148 * @param {SweetAlertOptions} innerParams
8149 * @param {(dismiss: DismissReason) => void} dismissWith
8150 */
8151 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8152 removeKeydownHandler(globalState);
8153 if (!innerParams.toast) {
8154 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8155 const handler = e => keydownHandler(innerParams, e, dismissWith);
8156 globalState.keydownHandler = handler;
8157 const target = innerParams.keydownListenerCapture ? window : getPopup();
8158 if (target) {
8159 globalState.keydownTarget = target;
8160 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8161 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8162 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8163 capture: globalState.keydownListenerCapture
8164 });
8165 globalState.keydownHandlerAdded = true;
8166 }
8167 }
8168 };
8169
8170 /**
8171 * @param {number} index
8172 * @param {number} increment
8173 * @returns {boolean} shouldPreventDefault
8174 */
8175 const setFocus = (index, increment) => {
8176 var _dom$getPopup;
8177 const focusableElements = getFocusableElements();
8178 // search for visible elements and select the next possible match
8179 if (focusableElements.length) {
8180 index = index + increment;
8181
8182 // shift + tab when .swal2-popup is focused
8183 if (index === -2) {
8184 index = focusableElements.length - 1;
8185 }
8186
8187 // rollover to first item
8188 if (index === focusableElements.length) {
8189 index = 0;
8190
8191 // go to last item
8192 } else if (index === -1) {
8193 index = focusableElements.length - 1;
8194 }
8195 focusableElements[index].focus();
8196
8197 // don't prevent default for iframes (Firefox fix)
8198 // https://github.com/sweetalert2/sweetalert2/issues/2931
8199 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
8200 return false;
8201 }
8202 return true;
8203 }
8204 // no visible focusable elements, focus the popup
8205 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8206 return true;
8207 };
8208 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8209 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8210
8211 /**
8212 * @param {SweetAlertOptions} innerParams
8213 * @param {KeyboardEvent} event
8214 * @param {(dismiss: DismissReason) => void} dismissWith
8215 */
8216 const keydownHandler = (innerParams, event, dismissWith) => {
8217 if (!innerParams) {
8218 return; // This instance has already been destroyed
8219 }
8220
8221 // Ignore keydown during IME composition
8222 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8223 // https://github.com/sweetalert2/sweetalert2/issues/720
8224 // https://github.com/sweetalert2/sweetalert2/issues/2406
8225 if (event.isComposing || event.keyCode === 229) {
8226 return;
8227 }
8228 if (innerParams.stopKeydownPropagation) {
8229 event.stopPropagation();
8230 }
8231
8232 // ENTER
8233 if (event.key === 'Enter') {
8234 handleEnter(event, innerParams);
8235 }
8236
8237 // TAB
8238 else if (event.key === 'Tab') {
8239 handleTab(event);
8240 }
8241
8242 // ARROWS - switch focus between buttons
8243 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8244 handleArrows(event.key);
8245 }
8246
8247 // ESC
8248 else if (event.key === 'Escape') {
8249 handleEsc(event, innerParams, dismissWith);
8250 }
8251 };
8252
8253 /**
8254 * @param {KeyboardEvent} event
8255 * @param {SweetAlertOptions} innerParams
8256 */
8257 const handleEnter = (event, innerParams) => {
8258 // https://github.com/sweetalert2/sweetalert2/issues/2386
8259 if (!callIfFunction(innerParams.allowEnterKey)) {
8260 return;
8261 }
8262 const popup = getPopup();
8263 if (!popup || !innerParams.input) {
8264 return;
8265 }
8266 const input = getInput$1(popup, innerParams.input);
8267 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8268 if (['textarea', 'file'].includes(innerParams.input)) {
8269 return; // do not submit
8270 }
8271 clickConfirm();
8272 event.preventDefault();
8273 }
8274 };
8275
8276 /**
8277 * @param {KeyboardEvent} event
8278 */
8279 const handleTab = event => {
8280 const targetElement = event.target;
8281 const focusableElements = getFocusableElements();
8282 const btnIndex = focusableElements.findIndex(el => el === targetElement);
8283
8284 // don't prevent default for iframes (Firefox fix)
8285 // https://github.com/sweetalert2/sweetalert2/issues/2931
8286 let shouldPreventDefault = true;
8287
8288 // Cycle to the next button
8289 if (!event.shiftKey) {
8290 shouldPreventDefault = setFocus(btnIndex, 1);
8291 }
8292
8293 // Cycle to the prev button
8294 else {
8295 shouldPreventDefault = setFocus(btnIndex, -1);
8296 }
8297 event.stopPropagation();
8298 if (shouldPreventDefault) {
8299 event.preventDefault();
8300 }
8301 };
8302
8303 /**
8304 * @param {string} key
8305 */
8306 const handleArrows = key => {
8307 const actions = getActions();
8308 const confirmButton = getConfirmButton();
8309 const denyButton = getDenyButton();
8310 const cancelButton = getCancelButton();
8311 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8312 return;
8313 }
8314 /** @type HTMLElement[] */
8315 const buttons = [confirmButton, denyButton, cancelButton];
8316 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8317 return;
8318 }
8319 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8320 let buttonToFocus = document.activeElement;
8321 if (!buttonToFocus) {
8322 return;
8323 }
8324 for (let i = 0; i < actions.children.length; i++) {
8325 buttonToFocus = buttonToFocus[sibling];
8326 if (!buttonToFocus) {
8327 return;
8328 }
8329 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8330 break;
8331 }
8332 }
8333 if (buttonToFocus instanceof HTMLButtonElement) {
8334 buttonToFocus.focus();
8335 }
8336 };
8337
8338 /**
8339 * @param {KeyboardEvent} event
8340 * @param {SweetAlertOptions} innerParams
8341 * @param {(dismiss: DismissReason) => void} dismissWith
8342 */
8343 const handleEsc = (event, innerParams, dismissWith) => {
8344 event.preventDefault();
8345 if (callIfFunction(innerParams.allowEscapeKey)) {
8346 dismissWith(DismissReason.esc);
8347 }
8348 };
8349
8350 /**
8351 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8352 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8353 * This is the approach that Babel will probably take to implement private methods/fields
8354 * https://github.com/tc39/proposal-private-methods
8355 * https://github.com/babel/babel/pull/7555
8356 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8357 * then we can use that language feature.
8358 */
8359
8360 var privateMethods = {
8361 swalPromiseResolve: new WeakMap(),
8362 swalPromiseReject: new WeakMap()
8363 };
8364
8365 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8366 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8367 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8368 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8369
8370 const setAriaHidden = () => {
8371 const container = getContainer();
8372 const bodyChildren = Array.from(document.body.children);
8373 bodyChildren.forEach(el => {
8374 if (el.contains(container)) {
8375 return;
8376 }
8377 if (el.hasAttribute('aria-hidden')) {
8378 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8379 }
8380 el.setAttribute('aria-hidden', 'true');
8381 });
8382 };
8383 const unsetAriaHidden = () => {
8384 const bodyChildren = Array.from(document.body.children);
8385 bodyChildren.forEach(el => {
8386 if (el.hasAttribute('data-previous-aria-hidden')) {
8387 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8388 el.removeAttribute('data-previous-aria-hidden');
8389 } else {
8390 el.removeAttribute('aria-hidden');
8391 }
8392 });
8393 };
8394
8395 // @ts-ignore
8396 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8397
8398 // @ts-ignore
8399 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
8400
8401 /**
8402 * Fix iOS scrolling
8403 * http://stackoverflow.com/q/39626302
8404 */
8405 const iOSfix = () => {
8406 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8407 const offset = document.body.scrollTop;
8408 document.body.style.top = `${offset * -1}px`;
8409 addClass(document.body, swalClasses.iosfix);
8410 lockBodyScroll();
8411 }
8412 };
8413
8414 /**
8415 * https://github.com/sweetalert2/sweetalert2/issues/1246
8416 */
8417 const lockBodyScroll = () => {
8418 const container = getContainer();
8419 if (!container) {
8420 return;
8421 }
8422 /** @type {boolean} */
8423 let preventTouchMove;
8424 /**
8425 * @param {TouchEvent} event
8426 */
8427 container.ontouchstart = event => {
8428 preventTouchMove = shouldPreventTouchMove(event);
8429 };
8430 /**
8431 * @param {TouchEvent} event
8432 */
8433 container.ontouchmove = event => {
8434 if (preventTouchMove) {
8435 event.preventDefault();
8436 event.stopPropagation();
8437 }
8438 };
8439 };
8440
8441 /**
8442 * @param {TouchEvent} event
8443 * @returns {boolean}
8444 */
8445 const shouldPreventTouchMove = event => {
8446 const target = event.target;
8447 const container = getContainer();
8448 const htmlContainer = getHtmlContainer();
8449 if (!container || !htmlContainer) {
8450 return false;
8451 }
8452 if (isStylus(event) || isZoom(event)) {
8453 return false;
8454 }
8455 if (target === container) {
8456 return true;
8457 }
8458 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8459 // #2823
8460 target.tagName !== 'INPUT' &&
8461 // #1603
8462 target.tagName !== 'TEXTAREA' &&
8463 // #2266
8464 !(isScrollable(htmlContainer) &&
8465 // #1944
8466 htmlContainer.contains(target))) {
8467 return true;
8468 }
8469 return false;
8470 };
8471
8472 /**
8473 * https://github.com/sweetalert2/sweetalert2/issues/1786
8474 *
8475 * @param {TouchEvent} event
8476 * @returns {boolean}
8477 */
8478 const isStylus = event => {
8479 return Boolean(event.touches && event.touches.length &&
8480 // @ts-ignore - touchType is not a standard property
8481 event.touches[0].touchType === 'stylus');
8482 };
8483
8484 /**
8485 * https://github.com/sweetalert2/sweetalert2/issues/1891
8486 *
8487 * @param {TouchEvent} event
8488 * @returns {boolean}
8489 */
8490 const isZoom = event => {
8491 return event.touches && event.touches.length > 1;
8492 };
8493 const undoIOSfix = () => {
8494 if (hasClass(document.body, swalClasses.iosfix)) {
8495 const offset = parseInt(document.body.style.top, 10);
8496 removeClass(document.body, swalClasses.iosfix);
8497 document.body.style.top = '';
8498 document.body.scrollTop = offset * -1;
8499 }
8500 };
8501
8502 /**
8503 * Measure scrollbar width for padding body during modal show/hide
8504 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8505 *
8506 * @returns {number}
8507 */
8508 const measureScrollbar = () => {
8509 const scrollDiv = document.createElement('div');
8510 scrollDiv.className = swalClasses['scrollbar-measure'];
8511 document.body.appendChild(scrollDiv);
8512 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8513 document.body.removeChild(scrollDiv);
8514 return scrollbarWidth;
8515 };
8516
8517 /**
8518 * Remember state in cases where opening and handling a modal will fiddle with it.
8519 * @type {number | null}
8520 */
8521 let previousBodyPadding = null;
8522
8523 /**
8524 * @param {string} initialBodyOverflow
8525 */
8526 const replaceScrollbarWithPadding = initialBodyOverflow => {
8527 // for queues, do not do this more than once
8528 if (previousBodyPadding !== null) {
8529 return;
8530 }
8531 // if the body has overflow
8532 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8533 ) {
8534 // add padding so the content doesn't shift after removal of scrollbar
8535 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8536 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8537 }
8538 };
8539 const undoReplaceScrollbarWithPadding = () => {
8540 if (previousBodyPadding !== null) {
8541 document.body.style.paddingRight = `${previousBodyPadding}px`;
8542 previousBodyPadding = null;
8543 }
8544 };
8545
8546 /**
8547 * @param {SweetAlert} instance
8548 * @param {HTMLElement} container
8549 * @param {boolean} returnFocus
8550 * @param {(() => void) | undefined} didClose
8551 */
8552 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8553 if (isToast()) {
8554 triggerDidCloseAndDispose(instance, didClose);
8555 } else {
8556 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8557 removeKeydownHandler(globalState);
8558 }
8559
8560 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8561 // for some reason removing the container in Safari will scroll the document to bottom
8562 if (isSafariOrIOS) {
8563 container.setAttribute('style', 'display:none !important');
8564 container.removeAttribute('class');
8565 container.innerHTML = '';
8566 } else {
8567 container.remove();
8568 }
8569 if (isModal()) {
8570 undoReplaceScrollbarWithPadding();
8571 undoIOSfix();
8572 unsetAriaHidden();
8573 }
8574 removeBodyClasses();
8575 }
8576
8577 /**
8578 * Remove SweetAlert2 classes from body
8579 */
8580 function removeBodyClasses() {
8581 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8582 }
8583
8584 /**
8585 * Instance method to close sweetAlert
8586 *
8587 * @param {SweetAlertResult | undefined} resolveValue
8588 * @this {SweetAlert}
8589 */
8590 function close(resolveValue) {
8591 resolveValue = prepareResolveValue(resolveValue);
8592 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8593 const didClose = triggerClosePopup(this);
8594 if (this.isAwaitingPromise) {
8595 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8596 if (!resolveValue.isDismissed) {
8597 handleAwaitingPromise(this);
8598 swalPromiseResolve(resolveValue);
8599 }
8600 } else if (didClose) {
8601 // Resolve Swal promise
8602 swalPromiseResolve(resolveValue);
8603 }
8604 }
8605
8606 /**
8607 * @param {SweetAlert} instance
8608 * @returns {boolean}
8609 */
8610 const triggerClosePopup = instance => {
8611 const popup = getPopup();
8612 if (!popup) {
8613 return false;
8614 }
8615 const innerParams = privateProps.innerParams.get(instance);
8616 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8617 return false;
8618 }
8619 removeClass(popup, innerParams.showClass.popup);
8620 addClass(popup, innerParams.hideClass.popup);
8621 const backdrop = getContainer();
8622 removeClass(backdrop, innerParams.showClass.backdrop);
8623 addClass(backdrop, innerParams.hideClass.backdrop);
8624 handlePopupAnimation(instance, popup, innerParams);
8625 return true;
8626 };
8627
8628 /**
8629 * @param {Error | string} error
8630 * @this {SweetAlert}
8631 */
8632 function rejectPromise(error) {
8633 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8634 handleAwaitingPromise(this);
8635 if (rejectPromise) {
8636 // Reject Swal promise
8637 rejectPromise(error);
8638 }
8639 }
8640
8641 /**
8642 * @param {SweetAlert} instance
8643 */
8644 const handleAwaitingPromise = instance => {
8645 if (instance.isAwaitingPromise) {
8646 // @ts-ignore
8647 delete instance.isAwaitingPromise;
8648 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8649 if (!privateProps.innerParams.get(instance)) {
8650 instance._destroy();
8651 }
8652 }
8653 };
8654
8655 /**
8656 * @param {SweetAlertResult | undefined} resolveValue
8657 * @returns {SweetAlertResult}
8658 */
8659 const prepareResolveValue = resolveValue => {
8660 // When user calls Swal.close()
8661 if (typeof resolveValue === 'undefined') {
8662 return {
8663 isConfirmed: false,
8664 isDenied: false,
8665 isDismissed: true
8666 };
8667 }
8668 return Object.assign({
8669 isConfirmed: false,
8670 isDenied: false,
8671 isDismissed: false
8672 }, resolveValue);
8673 };
8674
8675 /**
8676 * @param {SweetAlert} instance
8677 * @param {HTMLElement} popup
8678 * @param {SweetAlertOptions} innerParams
8679 */
8680 const handlePopupAnimation = (instance, popup, innerParams) => {
8681 var _globalState$eventEmi;
8682 const container = getContainer();
8683 // If animation is supported, animate
8684 const animationIsSupported = hasCssAnimation(popup);
8685 if (typeof innerParams.willClose === 'function') {
8686 innerParams.willClose(popup);
8687 }
8688 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8689 if (animationIsSupported && container) {
8690 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8691 } else if (container) {
8692 // Otherwise, remove immediately
8693 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8694 }
8695 };
8696
8697 /**
8698 * @param {SweetAlert} instance
8699 * @param {HTMLElement} popup
8700 * @param {HTMLElement} container
8701 * @param {boolean} returnFocus
8702 * @param {(() => void) | undefined} didClose
8703 */
8704 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8705 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8706 /**
8707 * @param {AnimationEvent | TransitionEvent} e
8708 */
8709 const swalCloseAnimationFinished = function (e) {
8710 if (e.target === popup) {
8711 var _globalState$swalClos;
8712 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8713 delete globalState.swalCloseEventFinishedCallback;
8714 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8715 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8716 }
8717 };
8718 popup.addEventListener('animationend', swalCloseAnimationFinished);
8719 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8720 };
8721
8722 /**
8723 * @param {SweetAlert} instance
8724 * @param {(() => void) | undefined} didClose
8725 */
8726 const triggerDidCloseAndDispose = (instance, didClose) => {
8727 setTimeout(() => {
8728 var _globalState$eventEmi2;
8729 if (typeof didClose === 'function') {
8730 didClose.bind(instance.params)();
8731 }
8732 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8733 // instance might have been destroyed already
8734 if (instance._destroy) {
8735 instance._destroy();
8736 }
8737 });
8738 };
8739
8740 /**
8741 * Shows loader (spinner), this is useful with AJAX requests.
8742 * By default the loader be shown instead of the "Confirm" button.
8743 *
8744 * @param {HTMLButtonElement | null} [buttonToReplace]
8745 */
8746 const showLoading = buttonToReplace => {
8747 let popup = getPopup();
8748 if (!popup) {
8749 new Swal();
8750 }
8751 popup = getPopup();
8752 if (!popup) {
8753 return;
8754 }
8755 const loader = getLoader();
8756 if (isToast()) {
8757 hide(getIcon());
8758 } else {
8759 replaceButton(popup, buttonToReplace);
8760 }
8761 show(loader);
8762 popup.setAttribute('data-loading', 'true');
8763 popup.setAttribute('aria-busy', 'true');
8764 popup.focus();
8765 };
8766
8767 /**
8768 * @param {HTMLElement} popup
8769 * @param {HTMLButtonElement | null} [buttonToReplace]
8770 */
8771 const replaceButton = (popup, buttonToReplace) => {
8772 const actions = getActions();
8773 const loader = getLoader();
8774 if (!actions || !loader) {
8775 return;
8776 }
8777 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8778 buttonToReplace = getConfirmButton();
8779 }
8780 show(actions);
8781 if (buttonToReplace) {
8782 hide(buttonToReplace);
8783 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8784 actions.insertBefore(loader, buttonToReplace);
8785 }
8786 addClass([popup, actions], swalClasses.loading);
8787 };
8788
8789 /**
8790 * @param {SweetAlert} instance
8791 * @param {SweetAlertOptions} params
8792 */
8793 const handleInputOptionsAndValue = (instance, params) => {
8794 if (params.input === 'select' || params.input === 'radio') {
8795 handleInputOptions(instance, params);
8796 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8797 showLoading(getConfirmButton());
8798 handleInputValue(instance, params);
8799 }
8800 };
8801
8802 /**
8803 * @param {SweetAlert} instance
8804 * @param {SweetAlertOptions} innerParams
8805 * @returns {SweetAlertInputValue}
8806 */
8807 const getInputValue = (instance, innerParams) => {
8808 const input = instance.getInput();
8809 if (!input) {
8810 return null;
8811 }
8812 switch (innerParams.input) {
8813 case 'checkbox':
8814 return getCheckboxValue(input);
8815 case 'radio':
8816 return getRadioValue(input);
8817 case 'file':
8818 return getFileValue(input);
8819 default:
8820 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8821 }
8822 };
8823
8824 /**
8825 * @param {HTMLInputElement} input
8826 * @returns {number}
8827 */
8828 const getCheckboxValue = input => input.checked ? 1 : 0;
8829
8830 /**
8831 * @param {HTMLInputElement} input
8832 * @returns {string | null}
8833 */
8834 const getRadioValue = input => input.checked ? input.value : null;
8835
8836 /**
8837 * @param {HTMLInputElement} input
8838 * @returns {FileList | File | null}
8839 */
8840 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8841
8842 /**
8843 * @param {SweetAlert} instance
8844 * @param {SweetAlertOptions} params
8845 */
8846 const handleInputOptions = (instance, params) => {
8847 const popup = getPopup();
8848 if (!popup) {
8849 return;
8850 }
8851 /**
8852 * @param {*} inputOptions
8853 */
8854 const processInputOptions = inputOptions => {
8855 if (params.input === 'select') {
8856 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8857 } else if (params.input === 'radio') {
8858 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8859 }
8860 };
8861 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8862 showLoading(getConfirmButton());
8863 asPromise(params.inputOptions).then(inputOptions => {
8864 instance.hideLoading();
8865 processInputOptions(inputOptions);
8866 });
8867 } else if (typeof params.inputOptions === 'object') {
8868 processInputOptions(params.inputOptions);
8869 } else {
8870 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8871 }
8872 };
8873
8874 /**
8875 * @param {SweetAlert} instance
8876 * @param {SweetAlertOptions} params
8877 */
8878 const handleInputValue = (instance, params) => {
8879 const input = instance.getInput();
8880 if (!input) {
8881 return;
8882 }
8883 hide(input);
8884 asPromise(params.inputValue).then(inputValue => {
8885 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8886 show(input);
8887 input.focus();
8888 instance.hideLoading();
8889 }).catch(err => {
8890 error(`Error in inputValue promise: ${err}`);
8891 input.value = '';
8892 show(input);
8893 input.focus();
8894 instance.hideLoading();
8895 });
8896 };
8897
8898 /**
8899 * @param {HTMLElement} popup
8900 * @param {InputOptionFlattened[]} inputOptions
8901 * @param {SweetAlertOptions} params
8902 */
8903 function populateSelectOptions(popup, inputOptions, params) {
8904 const select = getDirectChildByClass(popup, swalClasses.select);
8905 if (!select) {
8906 return;
8907 }
8908 /**
8909 * @param {HTMLElement} parent
8910 * @param {string} optionLabel
8911 * @param {string} optionValue
8912 */
8913 const renderOption = (parent, optionLabel, optionValue) => {
8914 const option = document.createElement('option');
8915 option.value = optionValue;
8916 setInnerHtml(option, optionLabel);
8917 option.selected = isSelected(optionValue, params.inputValue);
8918 parent.appendChild(option);
8919 };
8920 inputOptions.forEach(inputOption => {
8921 const optionValue = inputOption[0];
8922 const optionLabel = inputOption[1];
8923 // <optgroup> spec:
8924 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8925 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8926 // check whether this is a <optgroup>
8927 if (Array.isArray(optionLabel)) {
8928 // if it is an array, then it is an <optgroup>
8929 const optgroup = document.createElement('optgroup');
8930 optgroup.label = optionValue;
8931 optgroup.disabled = false; // not configurable for now
8932 select.appendChild(optgroup);
8933 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8934 } else {
8935 // case of <option>
8936 renderOption(select, optionLabel, optionValue);
8937 }
8938 });
8939 select.focus();
8940 }
8941
8942 /**
8943 * @param {HTMLElement} popup
8944 * @param {InputOptionFlattened[]} inputOptions
8945 * @param {SweetAlertOptions} params
8946 */
8947 function populateRadioOptions(popup, inputOptions, params) {
8948 const radio = getDirectChildByClass(popup, swalClasses.radio);
8949 if (!radio) {
8950 return;
8951 }
8952 inputOptions.forEach(inputOption => {
8953 const radioValue = inputOption[0];
8954 const radioLabel = inputOption[1];
8955 const radioInput = document.createElement('input');
8956 const radioLabelElement = document.createElement('label');
8957 radioInput.type = 'radio';
8958 radioInput.name = swalClasses.radio;
8959 radioInput.value = radioValue;
8960 if (isSelected(radioValue, params.inputValue)) {
8961 radioInput.checked = true;
8962 }
8963 const label = document.createElement('span');
8964 setInnerHtml(label, radioLabel);
8965 label.className = swalClasses.label;
8966 radioLabelElement.appendChild(radioInput);
8967 radioLabelElement.appendChild(label);
8968 radio.appendChild(radioLabelElement);
8969 });
8970 const radios = radio.querySelectorAll('input');
8971 if (radios.length) {
8972 radios[0].focus();
8973 }
8974 }
8975
8976 /**
8977 * Converts `inputOptions` into an array of `[value, label]`s
8978 *
8979 * @param {*} inputOptions
8980 * @typedef {string[]} InputOptionFlattened
8981 * @returns {InputOptionFlattened[]}
8982 */
8983 const formatInputOptions = inputOptions => {
8984 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
8985 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
8986 };
8987
8988 /**
8989 * @param {string} optionValue
8990 * @param {SweetAlertInputValue} inputValue
8991 * @returns {boolean}
8992 */
8993 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
8994
8995 /**
8996 * @param {SweetAlert} instance
8997 */
8998 const handleConfirmButtonClick = instance => {
8999 const innerParams = privateProps.innerParams.get(instance);
9000 instance.disableButtons();
9001 if (innerParams.input) {
9002 handleConfirmOrDenyWithInput(instance, 'confirm');
9003 } else {
9004 confirm(instance, true);
9005 }
9006 };
9007
9008 /**
9009 * @param {SweetAlert} instance
9010 */
9011 const handleDenyButtonClick = instance => {
9012 const innerParams = privateProps.innerParams.get(instance);
9013 instance.disableButtons();
9014 if (innerParams.returnInputValueOnDeny) {
9015 handleConfirmOrDenyWithInput(instance, 'deny');
9016 } else {
9017 deny(instance, false);
9018 }
9019 };
9020
9021 /**
9022 * @param {SweetAlert} instance
9023 * @param {(dismiss: DismissReason) => void} dismissWith
9024 */
9025 const handleCancelButtonClick = (instance, dismissWith) => {
9026 instance.disableButtons();
9027 dismissWith(DismissReason.cancel);
9028 };
9029
9030 /**
9031 * @param {SweetAlert} instance
9032 * @param {'confirm' | 'deny'} type
9033 */
9034 const handleConfirmOrDenyWithInput = (instance, type) => {
9035 const innerParams = privateProps.innerParams.get(instance);
9036 if (!innerParams.input) {
9037 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
9038 return;
9039 }
9040 const input = instance.getInput();
9041 const inputValue = getInputValue(instance, innerParams);
9042 if (innerParams.inputValidator) {
9043 handleInputValidator(instance, inputValue, type);
9044 } else if (input && !input.checkValidity()) {
9045 instance.enableButtons();
9046 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
9047 } else if (type === 'deny') {
9048 deny(instance, inputValue);
9049 } else {
9050 confirm(instance, inputValue);
9051 }
9052 };
9053
9054 /**
9055 * @param {SweetAlert} instance
9056 * @param {SweetAlertInputValue} inputValue
9057 * @param {'confirm' | 'deny'} type
9058 */
9059 const handleInputValidator = (instance, inputValue, type) => {
9060 const innerParams = privateProps.innerParams.get(instance);
9061 instance.disableInput();
9062 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
9063 validationPromise.then(validationMessage => {
9064 instance.enableButtons();
9065 instance.enableInput();
9066 if (validationMessage) {
9067 instance.showValidationMessage(validationMessage);
9068 } else if (type === 'deny') {
9069 deny(instance, inputValue);
9070 } else {
9071 confirm(instance, inputValue);
9072 }
9073 });
9074 };
9075
9076 /**
9077 * @param {SweetAlert} instance
9078 * @param {*} value
9079 */
9080 const deny = (instance, value) => {
9081 const innerParams = privateProps.innerParams.get(instance);
9082 if (innerParams.showLoaderOnDeny) {
9083 showLoading(getDenyButton());
9084 }
9085 if (innerParams.preDeny) {
9086 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
9087 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
9088 preDenyPromise.then(preDenyValue => {
9089 if (preDenyValue === false) {
9090 instance.hideLoading();
9091 handleAwaitingPromise(instance);
9092 } else {
9093 instance.close(/** @type SweetAlertResult */{
9094 isDenied: true,
9095 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
9096 });
9097 }
9098 }).catch(error => rejectWith(instance, error));
9099 } else {
9100 instance.close(/** @type SweetAlertResult */{
9101 isDenied: true,
9102 value
9103 });
9104 }
9105 };
9106
9107 /**
9108 * @param {SweetAlert} instance
9109 * @param {*} value
9110 */
9111 const succeedWith = (instance, value) => {
9112 instance.close(/** @type SweetAlertResult */{
9113 isConfirmed: true,
9114 value
9115 });
9116 };
9117
9118 /**
9119 *
9120 * @param {SweetAlert} instance
9121 * @param {string} error
9122 */
9123 const rejectWith = (instance, error) => {
9124 instance.rejectPromise(error);
9125 };
9126
9127 /**
9128 *
9129 * @param {SweetAlert} instance
9130 * @param {*} value
9131 */
9132 const confirm = (instance, value) => {
9133 const innerParams = privateProps.innerParams.get(instance);
9134 if (innerParams.showLoaderOnConfirm) {
9135 showLoading();
9136 }
9137 if (innerParams.preConfirm) {
9138 instance.resetValidationMessage();
9139 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
9140 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9141 preConfirmPromise.then(preConfirmValue => {
9142 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9143 instance.hideLoading();
9144 handleAwaitingPromise(instance);
9145 } else {
9146 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9147 }
9148 }).catch(error => rejectWith(instance, error));
9149 } else {
9150 succeedWith(instance, value);
9151 }
9152 };
9153
9154 /**
9155 * Hides loader and shows back the button which was hidden by .showLoading()
9156 * @this {SweetAlert}
9157 */
9158 function hideLoading() {
9159 // do nothing if popup is closed
9160 const innerParams = privateProps.innerParams.get(this);
9161 if (!innerParams) {
9162 return;
9163 }
9164 const domCache = privateProps.domCache.get(this);
9165 hide(domCache.loader);
9166 if (isToast()) {
9167 if (innerParams.icon) {
9168 show(getIcon());
9169 }
9170 } else {
9171 showRelatedButton(domCache);
9172 }
9173 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9174 domCache.popup.removeAttribute('aria-busy');
9175 domCache.popup.removeAttribute('data-loading');
9176 this.enableButtons();
9177 }
9178
9179 /**
9180 * @param {DomCache} domCache
9181 */
9182 const showRelatedButton = domCache => {
9183 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9184 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9185 if (buttonToReplace.length) {
9186 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9187 } else if (allButtonsAreHidden()) {
9188 hide(domCache.actions);
9189 }
9190 };
9191
9192 /**
9193 * Gets the input DOM node, this method works with input parameter.
9194 *
9195 * @returns {HTMLInputElement | null}
9196 * @this {SweetAlert}
9197 */
9198 function getInput() {
9199 const innerParams = privateProps.innerParams.get(this);
9200 const domCache = privateProps.domCache.get(this);
9201 if (!domCache) {
9202 return null;
9203 }
9204 return getInput$1(domCache.popup, innerParams.input);
9205 }
9206
9207 /**
9208 * @param {SweetAlert} instance
9209 * @param {string[]} buttons
9210 * @param {boolean} disabled
9211 */
9212 function setButtonsDisabled(instance, buttons, disabled) {
9213 const domCache = privateProps.domCache.get(instance);
9214 buttons.forEach(button => {
9215 domCache[button].disabled = disabled;
9216 });
9217 }
9218
9219 /**
9220 * @param {HTMLInputElement | null} input
9221 * @param {boolean} disabled
9222 */
9223 function setInputDisabled(input, disabled) {
9224 const popup = getPopup();
9225 if (!popup || !input) {
9226 return;
9227 }
9228 if (input.type === 'radio') {
9229 /** @type {NodeListOf<HTMLInputElement>} */
9230 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9231 radios.forEach(radio => {
9232 radio.disabled = disabled;
9233 });
9234 } else {
9235 input.disabled = disabled;
9236 }
9237 }
9238
9239 /**
9240 * Enable all the buttons
9241 * @this {SweetAlert}
9242 */
9243 function enableButtons() {
9244 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9245 const focusedElement = privateProps.focusedElement.get(this);
9246 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
9247 focusedElement.focus();
9248 }
9249 privateProps.focusedElement.delete(this);
9250 }
9251
9252 /**
9253 * Disable all the buttons
9254 * @this {SweetAlert}
9255 */
9256 function disableButtons() {
9257 privateProps.focusedElement.set(this, document.activeElement);
9258 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9259 }
9260
9261 /**
9262 * Enable the input field
9263 * @this {SweetAlert}
9264 */
9265 function enableInput() {
9266 setInputDisabled(this.getInput(), false);
9267 }
9268
9269 /**
9270 * Disable the input field
9271 * @this {SweetAlert}
9272 */
9273 function disableInput() {
9274 setInputDisabled(this.getInput(), true);
9275 }
9276
9277 /**
9278 * Show block with validation message
9279 *
9280 * @param {string} error
9281 * @this {SweetAlert}
9282 */
9283 function showValidationMessage(error) {
9284 const domCache = privateProps.domCache.get(this);
9285 const params = privateProps.innerParams.get(this);
9286 setInnerHtml(domCache.validationMessage, error);
9287 domCache.validationMessage.className = swalClasses['validation-message'];
9288 if (params.customClass && params.customClass.validationMessage) {
9289 addClass(domCache.validationMessage, params.customClass.validationMessage);
9290 }
9291 show(domCache.validationMessage);
9292 const input = this.getInput();
9293 if (input) {
9294 input.setAttribute('aria-invalid', 'true');
9295 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9296 focusInput(input);
9297 addClass(input, swalClasses.inputerror);
9298 }
9299 }
9300
9301 /**
9302 * Hide block with validation message
9303 *
9304 * @this {SweetAlert}
9305 */
9306 function resetValidationMessage() {
9307 const domCache = privateProps.domCache.get(this);
9308 if (domCache.validationMessage) {
9309 hide(domCache.validationMessage);
9310 }
9311 const input = this.getInput();
9312 if (input) {
9313 input.removeAttribute('aria-invalid');
9314 input.removeAttribute('aria-describedby');
9315 removeClass(input, swalClasses.inputerror);
9316 }
9317 }
9318
9319 const defaultParams = {
9320 title: '',
9321 titleText: '',
9322 text: '',
9323 html: '',
9324 footer: '',
9325 icon: undefined,
9326 iconColor: undefined,
9327 iconHtml: undefined,
9328 template: undefined,
9329 toast: false,
9330 draggable: false,
9331 animation: true,
9332 theme: 'light',
9333 showClass: {
9334 popup: 'swal2-show',
9335 backdrop: 'swal2-backdrop-show',
9336 icon: 'swal2-icon-show'
9337 },
9338 hideClass: {
9339 popup: 'swal2-hide',
9340 backdrop: 'swal2-backdrop-hide',
9341 icon: 'swal2-icon-hide'
9342 },
9343 customClass: {},
9344 target: 'body',
9345 color: undefined,
9346 backdrop: true,
9347 heightAuto: true,
9348 allowOutsideClick: true,
9349 allowEscapeKey: true,
9350 allowEnterKey: true,
9351 stopKeydownPropagation: true,
9352 keydownListenerCapture: false,
9353 showConfirmButton: true,
9354 showDenyButton: false,
9355 showCancelButton: false,
9356 preConfirm: undefined,
9357 preDeny: undefined,
9358 confirmButtonText: 'OK',
9359 confirmButtonAriaLabel: '',
9360 confirmButtonColor: undefined,
9361 denyButtonText: 'No',
9362 denyButtonAriaLabel: '',
9363 denyButtonColor: undefined,
9364 cancelButtonText: 'Cancel',
9365 cancelButtonAriaLabel: '',
9366 cancelButtonColor: undefined,
9367 buttonsStyling: true,
9368 reverseButtons: false,
9369 focusConfirm: true,
9370 focusDeny: false,
9371 focusCancel: false,
9372 returnFocus: true,
9373 showCloseButton: false,
9374 closeButtonHtml: '&times;',
9375 closeButtonAriaLabel: 'Close this dialog',
9376 loaderHtml: '',
9377 showLoaderOnConfirm: false,
9378 showLoaderOnDeny: false,
9379 imageUrl: undefined,
9380 imageWidth: undefined,
9381 imageHeight: undefined,
9382 imageAlt: '',
9383 timer: undefined,
9384 timerProgressBar: false,
9385 width: undefined,
9386 padding: undefined,
9387 background: undefined,
9388 input: undefined,
9389 inputPlaceholder: '',
9390 inputLabel: '',
9391 inputValue: '',
9392 inputOptions: {},
9393 inputAutoFocus: true,
9394 inputAutoTrim: true,
9395 inputAttributes: {},
9396 inputValidator: undefined,
9397 returnInputValueOnDeny: false,
9398 validationMessage: undefined,
9399 grow: false,
9400 position: 'center',
9401 progressSteps: [],
9402 currentProgressStep: undefined,
9403 progressStepsDistance: undefined,
9404 willOpen: undefined,
9405 didOpen: undefined,
9406 didRender: undefined,
9407 willClose: undefined,
9408 didClose: undefined,
9409 didDestroy: undefined,
9410 scrollbarPadding: true,
9411 topLayer: false
9412 };
9413 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'];
9414
9415 /** @type {Record<string, string | undefined>} */
9416 const deprecatedParams = {
9417 allowEnterKey: undefined
9418 };
9419 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9420
9421 /**
9422 * Is valid parameter
9423 *
9424 * @param {string} paramName
9425 * @returns {boolean}
9426 */
9427 const isValidParameter = paramName => {
9428 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9429 };
9430
9431 /**
9432 * Is valid parameter for Swal.update() method
9433 *
9434 * @param {string} paramName
9435 * @returns {boolean}
9436 */
9437 const isUpdatableParameter = paramName => {
9438 return updatableParams.indexOf(paramName) !== -1;
9439 };
9440
9441 /**
9442 * Is deprecated parameter
9443 *
9444 * @param {string} paramName
9445 * @returns {string | undefined}
9446 */
9447 const isDeprecatedParameter = paramName => {
9448 return deprecatedParams[paramName];
9449 };
9450
9451 /**
9452 * @param {string} param
9453 */
9454 const checkIfParamIsValid = param => {
9455 if (!isValidParameter(param)) {
9456 warn(`Unknown parameter "${param}"`);
9457 }
9458 };
9459
9460 /**
9461 * @param {string} param
9462 */
9463 const checkIfToastParamIsValid = param => {
9464 if (toastIncompatibleParams.includes(param)) {
9465 warn(`The parameter "${param}" is incompatible with toasts`);
9466 }
9467 };
9468
9469 /**
9470 * @param {string} param
9471 */
9472 const checkIfParamIsDeprecated = param => {
9473 const isDeprecated = isDeprecatedParameter(param);
9474 if (isDeprecated) {
9475 warnAboutDeprecation(param, isDeprecated);
9476 }
9477 };
9478
9479 /**
9480 * Show relevant warnings for given params
9481 *
9482 * @param {SweetAlertOptions} params
9483 */
9484 const showWarningsForParams = params => {
9485 if (params.backdrop === false && params.allowOutsideClick) {
9486 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9487 }
9488 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)) {
9489 warn(`Invalid theme "${params.theme}"`);
9490 }
9491 for (const param in params) {
9492 checkIfParamIsValid(param);
9493 if (params.toast) {
9494 checkIfToastParamIsValid(param);
9495 }
9496 checkIfParamIsDeprecated(param);
9497 }
9498 };
9499
9500 /**
9501 * Updates popup parameters.
9502 *
9503 * @this {any}
9504 * @param {SweetAlertOptions} params
9505 */
9506 function update(params) {
9507 const container = getContainer();
9508 const popup = getPopup();
9509 const innerParams = privateProps.innerParams.get(this);
9510 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9511 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.`);
9512 return;
9513 }
9514 const validUpdatableParams = filterValidParams(params);
9515 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9516 showWarningsForParams(updatedParams);
9517 if (container) {
9518 container.dataset['swal2Theme'] = updatedParams.theme;
9519 }
9520 render(this, updatedParams);
9521 privateProps.innerParams.set(this, updatedParams);
9522 Object.defineProperties(this, {
9523 params: {
9524 value: Object.assign({}, this.params, params),
9525 writable: false,
9526 enumerable: true
9527 }
9528 });
9529 }
9530
9531 /**
9532 * @param {SweetAlertOptions} params
9533 * @returns {SweetAlertOptions}
9534 */
9535 const filterValidParams = params => {
9536 /** @type {Record<string, any>} */
9537 const validUpdatableParams = {};
9538 Object.keys(params).forEach(param => {
9539 if (isUpdatableParameter(param)) {
9540 const typedParams = /** @type {Record<string, any>} */params;
9541 validUpdatableParams[param] = typedParams[param];
9542 } else {
9543 warn(`Invalid parameter to update: ${param}`);
9544 }
9545 });
9546 return validUpdatableParams;
9547 };
9548
9549 /**
9550 * Dispose the current SweetAlert2 instance
9551 * @this {SweetAlert}
9552 */
9553 function _destroy() {
9554 var _globalState$eventEmi;
9555 const domCache = privateProps.domCache.get(this);
9556 const innerParams = privateProps.innerParams.get(this);
9557 if (!innerParams) {
9558 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9559 return; // This instance has already been destroyed
9560 }
9561
9562 // Check if there is another Swal closing
9563 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9564 globalState.swalCloseEventFinishedCallback();
9565 delete globalState.swalCloseEventFinishedCallback;
9566 }
9567 if (typeof innerParams.didDestroy === 'function') {
9568 innerParams.didDestroy();
9569 }
9570 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9571 disposeSwal(this);
9572 }
9573
9574 /**
9575 * @param {SweetAlert} instance
9576 */
9577 const disposeSwal = instance => {
9578 disposeWeakMaps(instance);
9579 // Unset this.params so GC will dispose it (#1569)
9580 // @ts-ignore
9581 delete instance.params;
9582 // Unset globalState props so GC will dispose globalState (#1569)
9583 delete globalState.keydownHandler;
9584 delete globalState.keydownTarget;
9585 // Unset currentInstance
9586 delete globalState.currentInstance;
9587 };
9588
9589 /**
9590 * @param {SweetAlert} instance
9591 */
9592 const disposeWeakMaps = instance => {
9593 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9594 if (instance.isAwaitingPromise) {
9595 unsetWeakMaps(privateProps, instance);
9596 instance.isAwaitingPromise = true;
9597 } else {
9598 unsetWeakMaps(privateMethods, instance);
9599 unsetWeakMaps(privateProps, instance);
9600
9601 // @ts-ignore
9602 delete instance.isAwaitingPromise;
9603 // Unset instance methods
9604 // @ts-ignore
9605 delete instance.disableButtons;
9606 // @ts-ignore
9607 delete instance.enableButtons;
9608 // @ts-ignore
9609 delete instance.getInput;
9610 // @ts-ignore
9611 delete instance.disableInput;
9612 // @ts-ignore
9613 delete instance.enableInput;
9614 // @ts-ignore
9615 delete instance.hideLoading;
9616 // @ts-ignore
9617 delete instance.disableLoading;
9618 // @ts-ignore
9619 delete instance.showValidationMessage;
9620 // @ts-ignore
9621 delete instance.resetValidationMessage;
9622 // @ts-ignore
9623 delete instance.close;
9624 // @ts-ignore
9625 delete instance.closePopup;
9626 // @ts-ignore
9627 delete instance.closeModal;
9628 // @ts-ignore
9629 delete instance.closeToast;
9630 // @ts-ignore
9631 delete instance.rejectPromise;
9632 // @ts-ignore
9633 delete instance.update;
9634 // @ts-ignore
9635 delete instance._destroy;
9636 }
9637 };
9638
9639 /**
9640 * @param {Record<string, WeakMap<any, any>>} obj
9641 * @param {SweetAlert} instance
9642 */
9643 const unsetWeakMaps = (obj, instance) => {
9644 for (const i in obj) {
9645 obj[i].delete(instance);
9646 }
9647 };
9648
9649 var instanceMethods = /*#__PURE__*/Object.freeze({
9650 __proto__: null,
9651 _destroy: _destroy,
9652 close: close,
9653 closeModal: close,
9654 closePopup: close,
9655 closeToast: close,
9656 disableButtons: disableButtons,
9657 disableInput: disableInput,
9658 disableLoading: hideLoading,
9659 enableButtons: enableButtons,
9660 enableInput: enableInput,
9661 getInput: getInput,
9662 handleAwaitingPromise: handleAwaitingPromise,
9663 hideLoading: hideLoading,
9664 rejectPromise: rejectPromise,
9665 resetValidationMessage: resetValidationMessage,
9666 showValidationMessage: showValidationMessage,
9667 update: update
9668 });
9669
9670 /**
9671 * @param {SweetAlertOptions} innerParams
9672 * @param {DomCache} domCache
9673 * @param {(dismiss: DismissReason) => void} dismissWith
9674 */
9675 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9676 if (innerParams.toast) {
9677 handleToastClick(innerParams, domCache, dismissWith);
9678 } else {
9679 // Ignore click events that had mousedown on the popup but mouseup on the container
9680 // This can happen when the user drags a slider
9681 handleModalMousedown(domCache);
9682
9683 // Ignore click events that had mousedown on the container but mouseup on the popup
9684 handleContainerMousedown(domCache);
9685 handleModalClick(innerParams, domCache, dismissWith);
9686 }
9687 };
9688
9689 /**
9690 * @param {SweetAlertOptions} innerParams
9691 * @param {DomCache} domCache
9692 * @param {(dismiss: DismissReason) => void} dismissWith
9693 */
9694 const handleToastClick = (innerParams, domCache, dismissWith) => {
9695 // Closing toast by internal click
9696 domCache.popup.onclick = () => {
9697 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9698 return;
9699 }
9700 dismissWith(DismissReason.close);
9701 };
9702 };
9703
9704 /**
9705 * @param {SweetAlertOptions} innerParams
9706 * @returns {boolean}
9707 */
9708 const isAnyButtonShown = innerParams => {
9709 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9710 };
9711 let ignoreOutsideClick = false;
9712
9713 /**
9714 * @param {DomCache} domCache
9715 */
9716 const handleModalMousedown = domCache => {
9717 domCache.popup.onmousedown = () => {
9718 domCache.container.onmouseup = function (e) {
9719 domCache.container.onmouseup = () => {};
9720 // We only check if the mouseup target is the container because usually it doesn't
9721 // have any other direct children aside of the popup
9722 if (e.target === domCache.container) {
9723 ignoreOutsideClick = true;
9724 }
9725 };
9726 };
9727 };
9728
9729 /**
9730 * @param {DomCache} domCache
9731 */
9732 const handleContainerMousedown = domCache => {
9733 domCache.container.onmousedown = e => {
9734 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9735 if (e.target === domCache.container) {
9736 e.preventDefault();
9737 }
9738 domCache.popup.onmouseup = function (e) {
9739 domCache.popup.onmouseup = () => {};
9740 // We also need to check if the mouseup target is a child of the popup
9741 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9742 ignoreOutsideClick = true;
9743 }
9744 };
9745 };
9746 };
9747
9748 /**
9749 * @param {SweetAlertOptions} innerParams
9750 * @param {DomCache} domCache
9751 * @param {(dismiss: DismissReason) => void} dismissWith
9752 */
9753 const handleModalClick = (innerParams, domCache, dismissWith) => {
9754 domCache.container.onclick = e => {
9755 if (ignoreOutsideClick) {
9756 ignoreOutsideClick = false;
9757 return;
9758 }
9759 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9760 dismissWith(DismissReason.backdrop);
9761 }
9762 };
9763 };
9764
9765 /**
9766 * @param {unknown} elem
9767 * @returns {boolean}
9768 */
9769 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
9770
9771 /**
9772 * @param {unknown} elem
9773 * @returns {boolean}
9774 */
9775 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9776
9777 /**
9778 * @param {ReadonlyArray<unknown>} args
9779 * @returns {SweetAlertOptions}
9780 */
9781 const argsToParams = args => {
9782 /** @type {Record<string, unknown>} */
9783 const params = {};
9784 if (typeof args[0] === 'object' && !isElement(args[0])) {
9785 Object.assign(params, args[0]);
9786 } else {
9787 ['title', 'html', 'icon'].forEach((name, index) => {
9788 const arg = args[index];
9789 if (typeof arg === 'string' || isElement(arg)) {
9790 params[name] = arg;
9791 } else if (arg !== undefined) {
9792 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9793 }
9794 });
9795 }
9796 return /** @type {SweetAlertOptions} */params;
9797 };
9798
9799 /**
9800 * Main method to create a new SweetAlert2 popup
9801 *
9802 * @this {new (...args: any[]) => any}
9803 * @param {...SweetAlertOptions} args
9804 * @returns {Promise<SweetAlertResult>}
9805 */
9806 function fire(...args) {
9807 return new this(...args);
9808 }
9809
9810 /**
9811 * Returns an extended version of `Swal` containing `params` as defaults.
9812 * Useful for reusing Swal configuration.
9813 *
9814 * For example:
9815 *
9816 * Before:
9817 * const textPromptOptions = { input: 'text', showCancelButton: true }
9818 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9819 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9820 *
9821 * After:
9822 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9823 * const {value: firstName} = await TextPrompt('What is your first name?')
9824 * const {value: lastName} = await TextPrompt('What is your last name?')
9825 *
9826 * @param {SweetAlertOptions} mixinParams
9827 * @returns {SweetAlert}
9828 * @this {typeof import('../SweetAlert.js').SweetAlert}
9829 */
9830 function mixin(mixinParams) {
9831 // @ts-ignore: 'this' refers to the SweetAlert constructor
9832 class MixinSwal extends this {
9833 /**
9834 * @param {any} params
9835 * @param {any} priorityMixinParams
9836 */
9837 _main(params, priorityMixinParams) {
9838 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9839 }
9840 }
9841 // @ts-ignore
9842 return MixinSwal;
9843 }
9844
9845 /**
9846 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9847 * Otherwise, returns undefined.
9848 *
9849 * @returns {number | undefined}
9850 */
9851 const getTimerLeft = () => {
9852 return globalState.timeout && globalState.timeout.getTimerLeft();
9853 };
9854
9855 /**
9856 * Stop timer. Returns number of milliseconds of timer remained.
9857 * If `timer` parameter isn't set, returns undefined.
9858 *
9859 * @returns {number | undefined}
9860 */
9861 const stopTimer = () => {
9862 if (globalState.timeout) {
9863 stopTimerProgressBar();
9864 return globalState.timeout.stop();
9865 }
9866 };
9867
9868 /**
9869 * Resume timer. Returns number of milliseconds of timer remained.
9870 * If `timer` parameter isn't set, returns undefined.
9871 *
9872 * @returns {number | undefined}
9873 */
9874 const resumeTimer = () => {
9875 if (globalState.timeout) {
9876 const remaining = globalState.timeout.start();
9877 animateTimerProgressBar(remaining);
9878 return remaining;
9879 }
9880 };
9881
9882 /**
9883 * Resume timer. Returns number of milliseconds of timer remained.
9884 * If `timer` parameter isn't set, returns undefined.
9885 *
9886 * @returns {number | undefined}
9887 */
9888 const toggleTimer = () => {
9889 const timer = globalState.timeout;
9890 return timer && (timer.running ? stopTimer() : resumeTimer());
9891 };
9892
9893 /**
9894 * Increase timer. Returns number of milliseconds of an updated timer.
9895 * If `timer` parameter isn't set, returns undefined.
9896 *
9897 * @param {number} ms
9898 * @returns {number | undefined}
9899 */
9900 const increaseTimer = ms => {
9901 if (globalState.timeout) {
9902 const remaining = globalState.timeout.increase(ms);
9903 animateTimerProgressBar(remaining, true);
9904 return remaining;
9905 }
9906 };
9907
9908 /**
9909 * Check if timer is running. Returns true if timer is running
9910 * or false if timer is paused or stopped.
9911 * If `timer` parameter isn't set, returns undefined
9912 *
9913 * @returns {boolean}
9914 */
9915 const isTimerRunning = () => {
9916 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9917 };
9918
9919 let bodyClickListenerAdded = false;
9920 /** @type {Record<string, any>} */
9921 const clickHandlers = {};
9922
9923 /**
9924 * @this {any}
9925 * @param {string} attr
9926 */
9927 function bindClickHandler(attr = 'data-swal-template') {
9928 clickHandlers[attr] = this;
9929 if (!bodyClickListenerAdded) {
9930 document.body.addEventListener('click', bodyClickListener);
9931 bodyClickListenerAdded = true;
9932 }
9933 }
9934
9935 /**
9936 * @param {MouseEvent} event
9937 */
9938 const bodyClickListener = event => {
9939 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9940 for (const attr in clickHandlers) {
9941 const template = el.getAttribute && el.getAttribute(attr);
9942 if (template) {
9943 clickHandlers[attr].fire({
9944 template
9945 });
9946 return;
9947 }
9948 }
9949 }
9950 };
9951
9952 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9953
9954 class EventEmitter {
9955 constructor() {
9956 /** @type {Events} */
9957 this.events = {};
9958 }
9959
9960 /**
9961 * @param {string} eventName
9962 * @returns {EventHandlers}
9963 */
9964 _getHandlersByEventName(eventName) {
9965 if (typeof this.events[eventName] === 'undefined') {
9966 // not Set because we need to keep the FIFO order
9967 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9968 this.events[eventName] = [];
9969 }
9970 return this.events[eventName];
9971 }
9972
9973 /**
9974 * @param {string} eventName
9975 * @param {EventHandler} eventHandler
9976 */
9977 on(eventName, eventHandler) {
9978 const currentHandlers = this._getHandlersByEventName(eventName);
9979 if (!currentHandlers.includes(eventHandler)) {
9980 currentHandlers.push(eventHandler);
9981 }
9982 }
9983
9984 /**
9985 * @param {string} eventName
9986 * @param {EventHandler} eventHandler
9987 */
9988 once(eventName, eventHandler) {
9989 /**
9990 * @param {...any} args
9991 */
9992 const onceFn = (...args) => {
9993 this.removeListener(eventName, onceFn);
9994 // @ts-ignore
9995 eventHandler.apply(this, args);
9996 };
9997 this.on(eventName, onceFn);
9998 }
9999
10000 /**
10001 * @param {string} eventName
10002 * @param {...any} args
10003 */
10004 emit(eventName, ...args) {
10005 this._getHandlersByEventName(eventName).forEach(
10006 /**
10007 * @param {EventHandler} eventHandler
10008 */
10009 eventHandler => {
10010 try {
10011 // @ts-ignore
10012 eventHandler.apply(this, args);
10013 } catch (error) {
10014 console.error(error);
10015 }
10016 });
10017 }
10018
10019 /**
10020 * @param {string} eventName
10021 * @param {EventHandler} eventHandler
10022 */
10023 removeListener(eventName, eventHandler) {
10024 const currentHandlers = this._getHandlersByEventName(eventName);
10025 const index = currentHandlers.indexOf(eventHandler);
10026 if (index > -1) {
10027 currentHandlers.splice(index, 1);
10028 }
10029 }
10030
10031 /**
10032 * @param {string} eventName
10033 */
10034 removeAllListeners(eventName) {
10035 if (this.events[eventName] !== undefined) {
10036 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
10037 this.events[eventName].length = 0;
10038 }
10039 }
10040 reset() {
10041 this.events = {};
10042 }
10043 }
10044
10045 globalState.eventEmitter = new EventEmitter();
10046
10047 /**
10048 * @param {string} eventName
10049 * @param {EventHandler} eventHandler
10050 */
10051 const on = (eventName, eventHandler) => {
10052 if (globalState.eventEmitter) {
10053 globalState.eventEmitter.on(eventName, eventHandler);
10054 }
10055 };
10056
10057 /**
10058 * @param {string} eventName
10059 * @param {EventHandler} eventHandler
10060 */
10061 const once = (eventName, eventHandler) => {
10062 if (globalState.eventEmitter) {
10063 globalState.eventEmitter.once(eventName, eventHandler);
10064 }
10065 };
10066
10067 /**
10068 * @param {string} [eventName]
10069 * @param {EventHandler} [eventHandler]
10070 */
10071 const off = (eventName, eventHandler) => {
10072 if (!globalState.eventEmitter) {
10073 return;
10074 }
10075
10076 // Remove all handlers for all events
10077 if (!eventName) {
10078 globalState.eventEmitter.reset();
10079 return;
10080 }
10081 if (eventHandler) {
10082 // Remove a specific handler
10083 globalState.eventEmitter.removeListener(eventName, eventHandler);
10084 } else {
10085 // Remove all handlers for a specific event
10086 globalState.eventEmitter.removeAllListeners(eventName);
10087 }
10088 };
10089
10090 var staticMethods = /*#__PURE__*/Object.freeze({
10091 __proto__: null,
10092 argsToParams: argsToParams,
10093 bindClickHandler: bindClickHandler,
10094 clickCancel: clickCancel,
10095 clickConfirm: clickConfirm,
10096 clickDeny: clickDeny,
10097 enableLoading: showLoading,
10098 fire: fire,
10099 getActions: getActions,
10100 getCancelButton: getCancelButton,
10101 getCloseButton: getCloseButton,
10102 getConfirmButton: getConfirmButton,
10103 getContainer: getContainer,
10104 getDenyButton: getDenyButton,
10105 getFocusableElements: getFocusableElements,
10106 getFooter: getFooter,
10107 getHtmlContainer: getHtmlContainer,
10108 getIcon: getIcon,
10109 getIconContent: getIconContent,
10110 getImage: getImage,
10111 getInputLabel: getInputLabel,
10112 getLoader: getLoader,
10113 getPopup: getPopup,
10114 getProgressSteps: getProgressSteps,
10115 getTimerLeft: getTimerLeft,
10116 getTimerProgressBar: getTimerProgressBar,
10117 getTitle: getTitle,
10118 getValidationMessage: getValidationMessage,
10119 increaseTimer: increaseTimer,
10120 isDeprecatedParameter: isDeprecatedParameter,
10121 isLoading: isLoading,
10122 isTimerRunning: isTimerRunning,
10123 isUpdatableParameter: isUpdatableParameter,
10124 isValidParameter: isValidParameter,
10125 isVisible: isVisible,
10126 mixin: mixin,
10127 off: off,
10128 on: on,
10129 once: once,
10130 resumeTimer: resumeTimer,
10131 showLoading: showLoading,
10132 stopTimer: stopTimer,
10133 toggleTimer: toggleTimer
10134 });
10135
10136 class Timer {
10137 /**
10138 * @param {() => void} callback
10139 * @param {number} delay
10140 */
10141 constructor(callback, delay) {
10142 this.callback = callback;
10143 this.remaining = delay;
10144 this.running = false;
10145 this.start();
10146 }
10147
10148 /**
10149 * @returns {number}
10150 */
10151 start() {
10152 if (!this.running) {
10153 this.running = true;
10154 this.started = new Date();
10155 this.id = setTimeout(this.callback, this.remaining);
10156 }
10157 return this.remaining;
10158 }
10159
10160 /**
10161 * @returns {number}
10162 */
10163 stop() {
10164 if (this.started && this.running) {
10165 this.running = false;
10166 clearTimeout(this.id);
10167 this.remaining -= new Date().getTime() - this.started.getTime();
10168 }
10169 return this.remaining;
10170 }
10171
10172 /**
10173 * @param {number} n
10174 * @returns {number}
10175 */
10176 increase(n) {
10177 const running = this.running;
10178 if (running) {
10179 this.stop();
10180 }
10181 this.remaining += n;
10182 if (running) {
10183 this.start();
10184 }
10185 return this.remaining;
10186 }
10187
10188 /**
10189 * @returns {number}
10190 */
10191 getTimerLeft() {
10192 if (this.running) {
10193 this.stop();
10194 this.start();
10195 }
10196 return this.remaining;
10197 }
10198
10199 /**
10200 * @returns {boolean}
10201 */
10202 isRunning() {
10203 return this.running;
10204 }
10205 }
10206
10207 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10208
10209 /**
10210 * @param {SweetAlertOptions} params
10211 * @returns {SweetAlertOptions}
10212 */
10213 const getTemplateParams = params => {
10214 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10215 if (!template) {
10216 return {};
10217 }
10218 /** @type {DocumentFragment} */
10219 const templateContent = template.content;
10220 showWarningsForElements(templateContent);
10221 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10222 return result;
10223 };
10224
10225 /**
10226 * @param {DocumentFragment} templateContent
10227 * @returns {Record<string, string | boolean | number>}
10228 */
10229 const getSwalParams = templateContent => {
10230 /** @type {Record<string, string | boolean | number>} */
10231 const result = {};
10232 /** @type {HTMLElement[]} */
10233 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10234 swalParams.forEach(param => {
10235 showWarningsForAttributes(param, ['name', 'value']);
10236 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10237 const value = param.getAttribute('value');
10238 if (!paramName || !value) {
10239 return;
10240 }
10241 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10242 result[paramName] = value !== 'false';
10243 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10244 result[paramName] = JSON.parse(value);
10245 } else {
10246 result[paramName] = value;
10247 }
10248 });
10249 return result;
10250 };
10251
10252 /**
10253 * @param {DocumentFragment} templateContent
10254 * @returns {Record<string, () => void>}
10255 */
10256 const getSwalFunctionParams = templateContent => {
10257 /** @type {Record<string, () => void>} */
10258 const result = {};
10259 /** @type {HTMLElement[]} */
10260 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10261 swalFunctions.forEach(param => {
10262 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10263 const value = param.getAttribute('value');
10264 if (!paramName || !value) {
10265 return;
10266 }
10267 result[paramName] = new Function(`return ${value}`)();
10268 });
10269 return result;
10270 };
10271
10272 /**
10273 * @param {DocumentFragment} templateContent
10274 * @returns {Record<string, string | boolean>}
10275 */
10276 const getSwalButtons = templateContent => {
10277 /** @type {Record<string, string | boolean>} */
10278 const result = {};
10279 /** @type {HTMLElement[]} */
10280 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10281 swalButtons.forEach(button => {
10282 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10283 const type = button.getAttribute('type');
10284 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10285 return;
10286 }
10287 result[`${type}ButtonText`] = button.innerHTML;
10288 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10289 const color = button.getAttribute('color');
10290 if (color !== null) {
10291 result[`${type}ButtonColor`] = color;
10292 }
10293 const ariaLabel = button.getAttribute('aria-label');
10294 if (ariaLabel !== null) {
10295 result[`${type}ButtonAriaLabel`] = ariaLabel;
10296 }
10297 });
10298 return result;
10299 };
10300
10301 /**
10302 * @param {DocumentFragment} templateContent
10303 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10304 */
10305 const getSwalImage = templateContent => {
10306 const result = {};
10307 /** @type {HTMLElement | null} */
10308 const image = templateContent.querySelector('swal-image');
10309 if (image) {
10310 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10311 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
10312 const src = image.getAttribute('src');
10313 if (src !== null) result.imageUrl = src || undefined;
10314 const width = image.getAttribute('width');
10315 if (width !== null) result.imageWidth = width || undefined;
10316 const height = image.getAttribute('height');
10317 if (height !== null) result.imageHeight = height || undefined;
10318 const alt = image.getAttribute('alt');
10319 if (alt !== null) result.imageAlt = alt || undefined;
10320 }
10321 return result;
10322 };
10323
10324 /**
10325 * @param {DocumentFragment} templateContent
10326 * @returns {object}
10327 */
10328 const getSwalIcon = templateContent => {
10329 const result = {};
10330 /** @type {HTMLElement | null} */
10331 const icon = templateContent.querySelector('swal-icon');
10332 if (icon) {
10333 showWarningsForAttributes(icon, ['type', 'color']);
10334 if (icon.hasAttribute('type')) {
10335 result.icon = icon.getAttribute('type');
10336 }
10337 if (icon.hasAttribute('color')) {
10338 result.iconColor = icon.getAttribute('color');
10339 }
10340 result.iconHtml = icon.innerHTML;
10341 }
10342 return result;
10343 };
10344
10345 /**
10346 * @param {DocumentFragment} templateContent
10347 * @returns {object}
10348 */
10349 const getSwalInput = templateContent => {
10350 /** @type {Record<string, any>} */
10351 const result = {};
10352 /** @type {HTMLElement | null} */
10353 const input = templateContent.querySelector('swal-input');
10354 if (input) {
10355 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10356 result.input = input.getAttribute('type') || 'text';
10357 if (input.hasAttribute('label')) {
10358 result.inputLabel = input.getAttribute('label');
10359 }
10360 if (input.hasAttribute('placeholder')) {
10361 result.inputPlaceholder = input.getAttribute('placeholder');
10362 }
10363 if (input.hasAttribute('value')) {
10364 result.inputValue = input.getAttribute('value');
10365 }
10366 }
10367 /** @type {HTMLElement[]} */
10368 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10369 if (inputOptions.length) {
10370 result.inputOptions = {};
10371 inputOptions.forEach(option => {
10372 showWarningsForAttributes(option, ['value']);
10373 const optionValue = option.getAttribute('value');
10374 if (!optionValue) {
10375 return;
10376 }
10377 const optionName = option.innerHTML;
10378 result.inputOptions[optionValue] = optionName;
10379 });
10380 }
10381 return result;
10382 };
10383
10384 /**
10385 * @param {DocumentFragment} templateContent
10386 * @param {string[]} paramNames
10387 * @returns {Record<string, string>}
10388 */
10389 const getSwalStringParams = (templateContent, paramNames) => {
10390 /** @type {Record<string, string>} */
10391 const result = {};
10392 for (const i in paramNames) {
10393 const paramName = paramNames[i];
10394 /** @type {HTMLElement | null} */
10395 const tag = templateContent.querySelector(paramName);
10396 if (tag) {
10397 showWarningsForAttributes(tag, []);
10398 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10399 }
10400 }
10401 return result;
10402 };
10403
10404 /**
10405 * @param {DocumentFragment} templateContent
10406 */
10407 const showWarningsForElements = templateContent => {
10408 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10409 Array.from(templateContent.children).forEach(el => {
10410 const tagName = el.tagName.toLowerCase();
10411 if (!allowedElements.includes(tagName)) {
10412 warn(`Unrecognized element <${tagName}>`);
10413 }
10414 });
10415 };
10416
10417 /**
10418 * @param {HTMLElement} el
10419 * @param {string[]} allowedAttributes
10420 */
10421 const showWarningsForAttributes = (el, allowedAttributes) => {
10422 Array.from(el.attributes).forEach(attribute => {
10423 if (allowedAttributes.indexOf(attribute.name) === -1) {
10424 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.'}`]);
10425 }
10426 });
10427 };
10428
10429 const SHOW_CLASS_TIMEOUT = 10;
10430
10431 /**
10432 * Open popup, add necessary classes and styles, fix scrollbar
10433 *
10434 * @param {SweetAlertOptions} params
10435 */
10436 const openPopup = params => {
10437 var _globalState$eventEmi, _globalState$eventEmi2;
10438 const container = getContainer();
10439 const popup = getPopup();
10440 if (!container || !popup) {
10441 return;
10442 }
10443 if (typeof params.willOpen === 'function') {
10444 params.willOpen(popup);
10445 }
10446 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10447 const bodyStyles = window.getComputedStyle(document.body);
10448 const initialBodyOverflow = bodyStyles.overflowY;
10449 addClasses(container, popup, params);
10450
10451 // scrolling is 'hidden' until animation is done, after that 'auto'
10452 setTimeout(() => {
10453 setScrollingVisibility(container, popup);
10454 }, SHOW_CLASS_TIMEOUT);
10455 if (isModal()) {
10456 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10457 setAriaHidden();
10458 }
10459
10460 // https://github.com/sweetalert2/sweetalert2/issues/2923
10461 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
10462 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
10463 container.style.pointerEvents = 'auto';
10464 }
10465 if (!isToast() && !globalState.previousActiveElement) {
10466 globalState.previousActiveElement = document.activeElement;
10467 }
10468 if (typeof params.didOpen === 'function') {
10469 const didOpen = params.didOpen;
10470 setTimeout(() => didOpen(popup));
10471 }
10472 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10473 };
10474
10475 /**
10476 * @param {Event} event
10477 */
10478 const swalOpenAnimationFinished = event => {
10479 const popup = getPopup();
10480 if (!popup || event.target !== popup) {
10481 return;
10482 }
10483 const container = getContainer();
10484 if (!container) {
10485 return;
10486 }
10487 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10488 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10489 container.style.overflowY = 'auto';
10490
10491 // no-transition is added in init() in case one swal is opened right after another
10492 removeClass(container, swalClasses['no-transition']);
10493 };
10494
10495 /**
10496 * @param {HTMLElement} container
10497 * @param {HTMLElement} popup
10498 */
10499 const setScrollingVisibility = (container, popup) => {
10500 if (hasCssAnimation(popup)) {
10501 container.style.overflowY = 'hidden';
10502 popup.addEventListener('animationend', swalOpenAnimationFinished);
10503 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10504 } else {
10505 container.style.overflowY = 'auto';
10506 }
10507 };
10508
10509 /**
10510 * @param {HTMLElement} container
10511 * @param {boolean} scrollbarPadding
10512 * @param {string} initialBodyOverflow
10513 */
10514 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10515 iOSfix();
10516 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10517 replaceScrollbarWithPadding(initialBodyOverflow);
10518 }
10519
10520 // sweetalert2/issues/1247
10521 setTimeout(() => {
10522 container.scrollTop = 0;
10523 });
10524 };
10525
10526 /**
10527 * @param {HTMLElement} container
10528 * @param {HTMLElement} popup
10529 * @param {SweetAlertOptions} params
10530 */
10531 const addClasses = (container, popup, params) => {
10532 var _params$showClass;
10533 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10534 addClass(container, params.showClass.backdrop);
10535 }
10536 if (params.animation) {
10537 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10538 popup.style.setProperty('opacity', '0', 'important');
10539 show(popup, 'grid');
10540 setTimeout(() => {
10541 var _params$showClass2;
10542 // Animate popup right after showing it
10543 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10544 addClass(popup, params.showClass.popup);
10545 }
10546 // and remove the opacity workaround
10547 popup.style.removeProperty('opacity');
10548 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10549 } else {
10550 show(popup, 'grid');
10551 }
10552 addClass([document.documentElement, document.body], swalClasses.shown);
10553 if (params.heightAuto && params.backdrop && !params.toast) {
10554 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10555 }
10556 };
10557
10558 var defaultInputValidators = {
10559 /**
10560 * @param {string} string
10561 * @param {string} [validationMessage]
10562 * @returns {Promise<string | void>}
10563 */
10564 email: (string, validationMessage) => {
10565 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10566 },
10567 /**
10568 * @param {string} string
10569 * @param {string} [validationMessage]
10570 * @returns {Promise<string | void>}
10571 */
10572 url: (string, validationMessage) => {
10573 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10574 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');
10575 }
10576 };
10577
10578 /**
10579 * @param {SweetAlertOptions} params
10580 */
10581 function setDefaultInputValidators(params) {
10582 // Use default `inputValidator` for supported input types if not provided
10583 if (params.inputValidator) {
10584 return;
10585 }
10586 if (params.input === 'email') {
10587 params.inputValidator = defaultInputValidators['email'];
10588 }
10589 if (params.input === 'url') {
10590 params.inputValidator = defaultInputValidators['url'];
10591 }
10592 }
10593
10594 /**
10595 * @param {SweetAlertOptions} params
10596 */
10597 function validateCustomTargetElement(params) {
10598 // Determine if the custom target element is valid
10599 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10600 warn('Target parameter is not valid, defaulting to "body"');
10601 params.target = 'body';
10602 }
10603 }
10604
10605 /**
10606 * Set type, text and actions on popup
10607 *
10608 * @param {SweetAlertOptions} params
10609 */
10610 function setParameters(params) {
10611 setDefaultInputValidators(params);
10612
10613 // showLoaderOnConfirm && preConfirm
10614 if (params.showLoaderOnConfirm && !params.preConfirm) {
10615 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');
10616 }
10617 validateCustomTargetElement(params);
10618
10619 // Replace newlines with <br> in title
10620 if (typeof params.title === 'string') {
10621 params.title = params.title.split('\n').join('<br />');
10622 }
10623 init(params);
10624 }
10625
10626 /** @type {SweetAlert} */
10627 let currentInstance;
10628 var _promise = /*#__PURE__*/new WeakMap();
10629 class SweetAlert {
10630 /**
10631 * @param {...(SweetAlertOptions | string)} args
10632 * @this {SweetAlert}
10633 */
10634 constructor(...args) {
10635 /**
10636 * @type {Promise<SweetAlertResult>}
10637 */
10638 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
10639 Promise.resolve({
10640 isConfirmed: false,
10641 isDenied: false,
10642 isDismissed: true
10643 }));
10644 // Prevent run in Node env
10645 if (typeof window === 'undefined') {
10646 return;
10647 }
10648 currentInstance = this;
10649
10650 // @ts-ignore
10651 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10652
10653 /** @type {Readonly<SweetAlertOptions>} */
10654 this.params = outerParams;
10655
10656 /** @type {boolean} */
10657 this.isAwaitingPromise = false;
10658 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10659 }
10660
10661 /**
10662 * @param {any} userParams
10663 * @param {any} mixinParams
10664 */
10665 _main(userParams, mixinParams = {}) {
10666 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10667 if (globalState.currentInstance) {
10668 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10669 const {
10670 isAwaitingPromise
10671 } = globalState.currentInstance;
10672 globalState.currentInstance._destroy();
10673 if (!isAwaitingPromise) {
10674 swalPromiseResolve({
10675 isDismissed: true
10676 });
10677 }
10678 if (isModal()) {
10679 unsetAriaHidden();
10680 }
10681 }
10682 globalState.currentInstance = currentInstance;
10683 const innerParams = prepareParams(userParams, mixinParams);
10684 setParameters(innerParams);
10685 Object.freeze(innerParams);
10686
10687 // clear the previous timer
10688 if (globalState.timeout) {
10689 globalState.timeout.stop();
10690 delete globalState.timeout;
10691 }
10692
10693 // clear the restore focus timeout
10694 clearTimeout(globalState.restoreFocusTimeout);
10695 const domCache = populateDomCache(currentInstance);
10696 render(currentInstance, innerParams);
10697 privateProps.innerParams.set(currentInstance, innerParams);
10698 return swalPromise(currentInstance, domCache, innerParams);
10699 }
10700
10701 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10702 /**
10703 * @param {any} onFulfilled
10704 */
10705 // oxlint-disable-next-line unicorn/no-thenable
10706 then(onFulfilled) {
10707 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10708 }
10709
10710 /**
10711 * @param {any} onFinally
10712 */
10713 finally(onFinally) {
10714 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10715 }
10716 }
10717
10718 /**
10719 * @param {SweetAlert} instance
10720 * @param {DomCache} domCache
10721 * @param {SweetAlertOptions} innerParams
10722 * @returns {Promise<SweetAlertResult>}
10723 */
10724 const swalPromise = (instance, domCache, innerParams) => {
10725 return new Promise((resolve, reject) => {
10726 // functions to handle all closings/dismissals
10727 /**
10728 * @param {DismissReason} dismiss
10729 */
10730 const dismissWith = dismiss => {
10731 instance.close({
10732 isDismissed: true,
10733 dismiss,
10734 isConfirmed: false,
10735 isDenied: false
10736 });
10737 };
10738 privateMethods.swalPromiseResolve.set(instance, resolve);
10739 privateMethods.swalPromiseReject.set(instance, reject);
10740 domCache.confirmButton.onclick = () => {
10741 handleConfirmButtonClick(instance);
10742 };
10743 domCache.denyButton.onclick = () => {
10744 handleDenyButtonClick(instance);
10745 };
10746 domCache.cancelButton.onclick = () => {
10747 handleCancelButtonClick(instance, dismissWith);
10748 };
10749 domCache.closeButton.onclick = () => {
10750 dismissWith(DismissReason.close);
10751 };
10752 handlePopupClick(innerParams, domCache, dismissWith);
10753 addKeydownHandler(globalState, innerParams, dismissWith);
10754 handleInputOptionsAndValue(instance, innerParams);
10755 openPopup(innerParams);
10756 setupTimer(globalState, innerParams, dismissWith);
10757 initFocus(domCache, innerParams);
10758
10759 // Scroll container to top on open (#1247, #1946)
10760 setTimeout(() => {
10761 domCache.container.scrollTop = 0;
10762 });
10763 });
10764 };
10765
10766 /**
10767 * @param {SweetAlertOptions} userParams
10768 * @param {SweetAlertOptions} mixinParams
10769 * @returns {SweetAlertOptions}
10770 */
10771 const prepareParams = (userParams, mixinParams) => {
10772 const templateParams = getTemplateParams(userParams);
10773 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10774 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10775 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10776 if (params.animation === false) {
10777 params.showClass = {
10778 backdrop: 'swal2-noanimation'
10779 };
10780 params.hideClass = {};
10781 }
10782 return params;
10783 };
10784
10785 /**
10786 * @param {SweetAlert} instance
10787 * @returns {DomCache}
10788 */
10789 const populateDomCache = instance => {
10790 const domCache = /** @type {DomCache} */{
10791 popup: (/** @type {HTMLElement} */getPopup()),
10792 container: (/** @type {HTMLElement} */getContainer()),
10793 actions: (/** @type {HTMLElement} */getActions()),
10794 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10795 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10796 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10797 loader: (/** @type {HTMLElement} */getLoader()),
10798 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10799 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10800 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10801 };
10802 privateProps.domCache.set(instance, domCache);
10803 return domCache;
10804 };
10805
10806 /**
10807 * @param {GlobalState} globalState
10808 * @param {SweetAlertOptions} innerParams
10809 * @param {(dismiss: DismissReason) => void} dismissWith
10810 */
10811 const setupTimer = (globalState, innerParams, dismissWith) => {
10812 const timerProgressBar = getTimerProgressBar();
10813 hide(timerProgressBar);
10814 if (innerParams.timer) {
10815 globalState.timeout = new Timer(() => {
10816 dismissWith('timer');
10817 delete globalState.timeout;
10818 }, innerParams.timer);
10819 if (innerParams.timerProgressBar && timerProgressBar) {
10820 show(timerProgressBar);
10821 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10822 setTimeout(() => {
10823 if (globalState.timeout && globalState.timeout.running) {
10824 // timer can be already stopped or unset at this point
10825 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10826 }
10827 });
10828 }
10829 }
10830 };
10831
10832 /**
10833 * Initialize focus in the popup:
10834 *
10835 * 1. If `toast` is `true`, don't steal focus from the document.
10836 * 2. Else if there is an [autofocus] element, focus it.
10837 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10838 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10839 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10840 * 6. Else focus the first focusable element in a popup (if any).
10841 *
10842 * @param {DomCache} domCache
10843 * @param {SweetAlertOptions} innerParams
10844 */
10845 const initFocus = (domCache, innerParams) => {
10846 if (innerParams.toast) {
10847 return;
10848 }
10849 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10850 if (!callIfFunction(innerParams.allowEnterKey)) {
10851 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
10852 domCache.popup.focus();
10853 return;
10854 }
10855 if (focusAutofocus(domCache)) {
10856 return;
10857 }
10858 if (focusButton(domCache, innerParams)) {
10859 return;
10860 }
10861 setFocus(-1, 1);
10862 };
10863
10864 /**
10865 * @param {DomCache} domCache
10866 * @returns {boolean}
10867 */
10868 const focusAutofocus = domCache => {
10869 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10870 for (const autofocusElement of autofocusElements) {
10871 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10872 autofocusElement.focus();
10873 return true;
10874 }
10875 }
10876 return false;
10877 };
10878
10879 /**
10880 * @param {DomCache} domCache
10881 * @param {SweetAlertOptions} innerParams
10882 * @returns {boolean}
10883 */
10884 const focusButton = (domCache, innerParams) => {
10885 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10886 domCache.denyButton.focus();
10887 return true;
10888 }
10889 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10890 domCache.cancelButton.focus();
10891 return true;
10892 }
10893 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10894 domCache.confirmButton.focus();
10895 return true;
10896 }
10897 return false;
10898 };
10899
10900 // Assign instance methods from src/instanceMethods/*.js to prototype
10901 SweetAlert.prototype.disableButtons = disableButtons;
10902 SweetAlert.prototype.enableButtons = enableButtons;
10903 SweetAlert.prototype.getInput = getInput;
10904 SweetAlert.prototype.disableInput = disableInput;
10905 SweetAlert.prototype.enableInput = enableInput;
10906 SweetAlert.prototype.hideLoading = hideLoading;
10907 SweetAlert.prototype.disableLoading = hideLoading;
10908 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10909 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10910 SweetAlert.prototype.close = close;
10911 SweetAlert.prototype.closePopup = close;
10912 SweetAlert.prototype.closeModal = close;
10913 SweetAlert.prototype.closeToast = close;
10914 SweetAlert.prototype.rejectPromise = rejectPromise;
10915 SweetAlert.prototype.update = update;
10916 SweetAlert.prototype._destroy = _destroy;
10917
10918 // Assign static methods from src/staticMethods/*.js to constructor
10919 Object.assign(SweetAlert, staticMethods);
10920
10921 // Proxy to instance methods to constructor, for now, for backwards compatibility
10922 Object.keys(instanceMethods).forEach(key => {
10923 /**
10924 * @param {...(SweetAlertOptions | string | undefined)} args
10925 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10926 */
10927 // @ts-ignore: Dynamic property assignment for backwards compatibility
10928 SweetAlert[key] = function (...args) {
10929 // @ts-ignore
10930 if (currentInstance && currentInstance[key]) {
10931 // @ts-ignore
10932 return currentInstance[key](...args);
10933 }
10934 return undefined;
10935 };
10936 });
10937 SweetAlert.DismissReason = DismissReason;
10938 SweetAlert.version = '11.26.25';
10939
10940 const Swal = SweetAlert;
10941 // @ts-ignore
10942 Swal.default = Swal;
10943
10944 return Swal;
10945
10946 }));
10947 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10948 "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}}");
10949
10950 /***/ },
10951
10952 /***/ "./node_modules/toastify-js/src/toastify.js"
10953 /*!**************************************************!*\
10954 !*** ./node_modules/toastify-js/src/toastify.js ***!
10955 \**************************************************/
10956 (module) {
10957
10958 /*!
10959 * Toastify js 1.12.0
10960 * https://github.com/apvarun/toastify-js
10961 * @license MIT licensed
10962 *
10963 * Copyright (C) 2018 Varun A P
10964 */
10965 (function(root, factory) {
10966 if ( true && module.exports) {
10967 module.exports = factory();
10968 } else {
10969 root.Toastify = factory();
10970 }
10971 })(this, function(global) {
10972 // Object initialization
10973 var Toastify = function(options) {
10974 // Returning a new init object
10975 return new Toastify.lib.init(options);
10976 },
10977 // Library version
10978 version = "1.12.0";
10979
10980 // Set the default global options
10981 Toastify.defaults = {
10982 oldestFirst: true,
10983 text: "Toastify is awesome!",
10984 node: undefined,
10985 duration: 3000,
10986 selector: undefined,
10987 callback: function () {
10988 },
10989 destination: undefined,
10990 newWindow: false,
10991 close: false,
10992 gravity: "toastify-top",
10993 positionLeft: false,
10994 position: '',
10995 backgroundColor: '',
10996 avatar: "",
10997 className: "",
10998 stopOnFocus: true,
10999 onClick: function () {
11000 },
11001 offset: {x: 0, y: 0},
11002 escapeMarkup: true,
11003 ariaLive: 'polite',
11004 style: {background: ''}
11005 };
11006
11007 // Defining the prototype of the object
11008 Toastify.lib = Toastify.prototype = {
11009 toastify: version,
11010
11011 constructor: Toastify,
11012
11013 // Initializing the object with required parameters
11014 init: function(options) {
11015 // Verifying and validating the input object
11016 if (!options) {
11017 options = {};
11018 }
11019
11020 // Creating the options object
11021 this.options = {};
11022
11023 this.toastElement = null;
11024
11025 // Validating the options
11026 this.options.text = options.text || Toastify.defaults.text; // Display message
11027 this.options.node = options.node || Toastify.defaults.node; // Display content as node
11028 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
11029 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
11030 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
11031 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
11032 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
11033 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
11034 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
11035 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
11036 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
11037 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
11038 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
11039 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
11040 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
11041 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
11042 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
11043 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
11044 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
11045 this.options.style = options.style || Toastify.defaults.style;
11046 if(options.backgroundColor) {
11047 this.options.style.background = options.backgroundColor;
11048 }
11049
11050 // Returning the current object for chaining functions
11051 return this;
11052 },
11053
11054 // Building the DOM element
11055 buildToast: function() {
11056 // Validating if the options are defined
11057 if (!this.options) {
11058 throw "Toastify is not initialized";
11059 }
11060
11061 // Creating the DOM object
11062 var divElement = document.createElement("div");
11063 divElement.className = "toastify on " + this.options.className;
11064
11065 // Positioning toast to left or right or center
11066 if (!!this.options.position) {
11067 divElement.className += " toastify-" + this.options.position;
11068 } else {
11069 // To be depreciated in further versions
11070 if (this.options.positionLeft === true) {
11071 divElement.className += " toastify-left";
11072 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
11073 } else {
11074 // Default position
11075 divElement.className += " toastify-right";
11076 }
11077 }
11078
11079 // Assigning gravity of element
11080 divElement.className += " " + this.options.gravity;
11081
11082 if (this.options.backgroundColor) {
11083 // This is being deprecated in favor of using the style HTML DOM property
11084 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
11085 }
11086
11087 // Loop through our style object and apply styles to divElement
11088 for (var property in this.options.style) {
11089 divElement.style[property] = this.options.style[property];
11090 }
11091
11092 // Announce the toast to screen readers
11093 if (this.options.ariaLive) {
11094 divElement.setAttribute('aria-live', this.options.ariaLive)
11095 }
11096
11097 // Adding the toast message/node
11098 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
11099 // If we have a valid node, we insert it
11100 divElement.appendChild(this.options.node)
11101 } else {
11102 if (this.options.escapeMarkup) {
11103 divElement.innerText = this.options.text;
11104 } else {
11105 divElement.innerHTML = this.options.text;
11106 }
11107
11108 if (this.options.avatar !== "") {
11109 var avatarElement = document.createElement("img");
11110 avatarElement.src = this.options.avatar;
11111
11112 avatarElement.className = "toastify-avatar";
11113
11114 if (this.options.position == "left" || this.options.positionLeft === true) {
11115 // Adding close icon on the left of content
11116 divElement.appendChild(avatarElement);
11117 } else {
11118 // Adding close icon on the right of content
11119 divElement.insertAdjacentElement("afterbegin", avatarElement);
11120 }
11121 }
11122 }
11123
11124 // Adding a close icon to the toast
11125 if (this.options.close === true) {
11126 // Create a span for close element
11127 var closeElement = document.createElement("button");
11128 closeElement.type = "button";
11129 closeElement.setAttribute("aria-label", "Close");
11130 closeElement.className = "toast-close";
11131 closeElement.innerHTML = "&#10006;";
11132
11133 // Triggering the removal of toast from DOM on close click
11134 closeElement.addEventListener(
11135 "click",
11136 function(event) {
11137 event.stopPropagation();
11138 this.removeElement(this.toastElement);
11139 window.clearTimeout(this.toastElement.timeOutValue);
11140 }.bind(this)
11141 );
11142
11143 //Calculating screen width
11144 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11145
11146 // Adding the close icon to the toast element
11147 // Display on the right if screen width is less than or equal to 360px
11148 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11149 // Adding close icon on the left of content
11150 divElement.insertAdjacentElement("afterbegin", closeElement);
11151 } else {
11152 // Adding close icon on the right of content
11153 divElement.appendChild(closeElement);
11154 }
11155 }
11156
11157 // Clear timeout while toast is focused
11158 if (this.options.stopOnFocus && this.options.duration > 0) {
11159 var self = this;
11160 // stop countdown
11161 divElement.addEventListener(
11162 "mouseover",
11163 function(event) {
11164 window.clearTimeout(divElement.timeOutValue);
11165 }
11166 )
11167 // add back the timeout
11168 divElement.addEventListener(
11169 "mouseleave",
11170 function() {
11171 divElement.timeOutValue = window.setTimeout(
11172 function() {
11173 // Remove the toast from DOM
11174 self.removeElement(divElement);
11175 },
11176 self.options.duration
11177 )
11178 }
11179 )
11180 }
11181
11182 // Adding an on-click destination path
11183 if (typeof this.options.destination !== "undefined") {
11184 divElement.addEventListener(
11185 "click",
11186 function(event) {
11187 event.stopPropagation();
11188 if (this.options.newWindow === true) {
11189 window.open(this.options.destination, "_blank");
11190 } else {
11191 window.location = this.options.destination;
11192 }
11193 }.bind(this)
11194 );
11195 }
11196
11197 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11198 divElement.addEventListener(
11199 "click",
11200 function(event) {
11201 event.stopPropagation();
11202 this.options.onClick();
11203 }.bind(this)
11204 );
11205 }
11206
11207 // Adding offset
11208 if(typeof this.options.offset === "object") {
11209
11210 var x = getAxisOffsetAValue("x", this.options);
11211 var y = getAxisOffsetAValue("y", this.options);
11212
11213 var xOffset = this.options.position == "left" ? x : "-" + x;
11214 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11215
11216 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11217
11218 }
11219
11220 // Returning the generated element
11221 return divElement;
11222 },
11223
11224 // Displaying the toast
11225 showToast: function() {
11226 // Creating the DOM object for the toast
11227 this.toastElement = this.buildToast();
11228
11229 // Getting the root element to with the toast needs to be added
11230 var rootElement;
11231 if (typeof this.options.selector === "string") {
11232 rootElement = document.getElementById(this.options.selector);
11233 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11234 rootElement = this.options.selector;
11235 } else {
11236 rootElement = document.body;
11237 }
11238
11239 // Validating if root element is present in DOM
11240 if (!rootElement) {
11241 throw "Root element is not defined";
11242 }
11243
11244 // Adding the DOM element
11245 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11246 rootElement.insertBefore(this.toastElement, elementToInsert);
11247
11248 // Repositioning the toasts in case multiple toasts are present
11249 Toastify.reposition();
11250
11251 if (this.options.duration > 0) {
11252 this.toastElement.timeOutValue = window.setTimeout(
11253 function() {
11254 // Remove the toast from DOM
11255 this.removeElement(this.toastElement);
11256 }.bind(this),
11257 this.options.duration
11258 ); // Binding `this` for function invocation
11259 }
11260
11261 // Supporting function chaining
11262 return this;
11263 },
11264
11265 hideToast: function() {
11266 if (this.toastElement.timeOutValue) {
11267 clearTimeout(this.toastElement.timeOutValue);
11268 }
11269 this.removeElement(this.toastElement);
11270 },
11271
11272 // Removing the element from the DOM
11273 removeElement: function(toastElement) {
11274 // Hiding the element
11275 // toastElement.classList.remove("on");
11276 toastElement.className = toastElement.className.replace(" on", "");
11277
11278 // Removing the element from DOM after transition end
11279 window.setTimeout(
11280 function() {
11281 // remove options node if any
11282 if (this.options.node && this.options.node.parentNode) {
11283 this.options.node.parentNode.removeChild(this.options.node);
11284 }
11285
11286 // Remove the element from the DOM, only when the parent node was not removed before.
11287 if (toastElement.parentNode) {
11288 toastElement.parentNode.removeChild(toastElement);
11289 }
11290
11291 // Calling the callback function
11292 this.options.callback.call(toastElement);
11293
11294 // Repositioning the toasts again
11295 Toastify.reposition();
11296 }.bind(this),
11297 400
11298 ); // Binding `this` for function invocation
11299 },
11300 };
11301
11302 // Positioning the toasts on the DOM
11303 Toastify.reposition = function() {
11304
11305 // Top margins with gravity
11306 var topLeftOffsetSize = {
11307 top: 15,
11308 bottom: 15,
11309 };
11310 var topRightOffsetSize = {
11311 top: 15,
11312 bottom: 15,
11313 };
11314 var offsetSize = {
11315 top: 15,
11316 bottom: 15,
11317 };
11318
11319 // Get all toast messages on the DOM
11320 var allToasts = document.getElementsByClassName("toastify");
11321
11322 var classUsed;
11323
11324 // Modifying the position of each toast element
11325 for (var i = 0; i < allToasts.length; i++) {
11326 // Getting the applied gravity
11327 if (containsClass(allToasts[i], "toastify-top") === true) {
11328 classUsed = "toastify-top";
11329 } else {
11330 classUsed = "toastify-bottom";
11331 }
11332
11333 var height = allToasts[i].offsetHeight;
11334 classUsed = classUsed.substr(9, classUsed.length-1)
11335 // Spacing between toasts
11336 var offset = 15;
11337
11338 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11339
11340 // Show toast in center if screen with less than or equal to 360px
11341 if (width <= 360) {
11342 // Setting the position
11343 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11344
11345 offsetSize[classUsed] += height + offset;
11346 } else {
11347 if (containsClass(allToasts[i], "toastify-left") === true) {
11348 // Setting the position
11349 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11350
11351 topLeftOffsetSize[classUsed] += height + offset;
11352 } else {
11353 // Setting the position
11354 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11355
11356 topRightOffsetSize[classUsed] += height + offset;
11357 }
11358 }
11359 }
11360
11361 // Supporting function chaining
11362 return this;
11363 };
11364
11365 // Helper function to get offset.
11366 function getAxisOffsetAValue(axis, options) {
11367
11368 if(options.offset[axis]) {
11369 if(isNaN(options.offset[axis])) {
11370 return options.offset[axis];
11371 }
11372 else {
11373 return options.offset[axis] + 'px';
11374 }
11375 }
11376
11377 return '0px';
11378
11379 }
11380
11381 function containsClass(elem, yourClass) {
11382 if (!elem || typeof yourClass !== "string") {
11383 return false;
11384 } else if (
11385 elem.className &&
11386 elem.className
11387 .trim()
11388 .split(/\s+/gi)
11389 .indexOf(yourClass) > -1
11390 ) {
11391 return true;
11392 } else {
11393 return false;
11394 }
11395 }
11396
11397 // Setting up the prototype for the init object
11398 Toastify.lib.init.prototype = Toastify.lib;
11399
11400 // Returning the Toastify function to be assigned to the window object/module
11401 return Toastify;
11402 });
11403
11404
11405 /***/ },
11406
11407 /***/ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"
11408 /*!**************************************************************************************************************************************************************************************************************************************************************!*\
11409 !*** data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC ***!
11410 \**************************************************************************************************************************************************************************************************************************************************************/
11411 (module) {
11412
11413 "use strict";
11414 module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC";
11415
11416 /***/ }
11417
11418 /******/ });
11419 /************************************************************************/
11420 /******/ // The module cache
11421 /******/ const __webpack_module_cache__ = {};
11422 /******/
11423 /******/ // The require function
11424 /******/ function __webpack_require__(moduleId) {
11425 /******/ // Check if module is in cache
11426 /******/ const cachedModule = __webpack_module_cache__[moduleId];
11427 /******/ if (cachedModule !== undefined) {
11428 /******/ return cachedModule.exports;
11429 /******/ }
11430 /******/ // Create a new module (and put it into the cache)
11431 /******/ const module = __webpack_module_cache__[moduleId] = {
11432 /******/ id: moduleId,
11433 /******/ // no module.loaded needed
11434 /******/ exports: {}
11435 /******/ };
11436 /******/
11437 /******/ // Execute the module function
11438 /******/ if (!(moduleId in __webpack_modules__)) {
11439 /******/ delete __webpack_module_cache__[moduleId];
11440 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
11441 /******/ e.code = 'MODULE_NOT_FOUND';
11442 /******/ throw e;
11443 /******/ }
11444 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11445 /******/
11446 /******/ // Return the exports of the module
11447 /******/ return module.exports;
11448 /******/ }
11449 /******/
11450 /******/ // expose the modules object (__webpack_modules__)
11451 /******/ __webpack_require__.m = __webpack_modules__;
11452 /******/
11453 /************************************************************************/
11454 /******/ /* webpack/runtime/compat get default export */
11455 /******/ (() => {
11456 /******/ // getDefaultExport function for compatibility with non-harmony modules
11457 /******/ __webpack_require__.n = (module) => {
11458 /******/ const getter = module && module.__esModule ?
11459 /******/ () => (module['default']) :
11460 /******/ () => (module);
11461 /******/ __webpack_require__.d(getter, { a: getter });
11462 /******/ return getter;
11463 /******/ };
11464 /******/ })();
11465 /******/
11466 /******/ /* webpack/runtime/define property getters */
11467 /******/ (() => {
11468 /******/ // define getter/value functions for harmony exports
11469 /******/ __webpack_require__.d = (exports, definition) => {
11470 /******/ if(Array.isArray(definition)) {
11471 /******/ var i = 0;
11472 /******/ while(i < definition.length) {
11473 /******/ var key = definition[i++];
11474 /******/ var binding = definition[i++];
11475 /******/ if(!__webpack_require__.o(exports, key)) {
11476 /******/ if(binding === 0) {
11477 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
11478 /******/ } else {
11479 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
11480 /******/ }
11481 /******/ } else if(binding === 0) { i++; }
11482 /******/ }
11483 /******/ } else {
11484 /******/ for(var key in definition) {
11485 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11486 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11487 /******/ }
11488 /******/ }
11489 /******/ }
11490 /******/ };
11491 /******/ })();
11492 /******/
11493 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11494 /******/ (() => {
11495 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
11496 /******/ })();
11497 /******/
11498 /******/ /* webpack/runtime/make namespace object */
11499 /******/ (() => {
11500 /******/ // define __esModule on exports
11501 /******/ __webpack_require__.r = (exports) => {
11502 /******/ if(Symbol.toStringTag) {
11503 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11504 /******/ }
11505 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11506 /******/ };
11507 /******/ })();
11508 /******/
11509 /******/ /* webpack/runtime/jsonp chunk loading */
11510 /******/ (() => {
11511 /******/ __webpack_require__.b = (typeof document !== 'undefined' && document.baseURI) || self.location.href;
11512 /******/
11513 /******/ // object to store loaded and loading chunks
11514 /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
11515 /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
11516 /******/ const installedChunks = {
11517 /******/ "./assets/js/dist/frontend/profile": 0
11518 /******/ };
11519 /******/
11520 /******/ // no chunk on demand loading
11521 /******/
11522 /******/ // no prefetching
11523 /******/
11524 /******/ // no preloaded
11525 /******/
11526 /******/ // no HMR
11527 /******/
11528 /******/ // no HMR manifest
11529 /******/
11530 /******/ // no on chunks loaded
11531 /******/
11532 /******/ // no jsonp function
11533 /******/ })();
11534 /******/
11535 /******/ /* webpack/runtime/nonce */
11536 /******/ (() => {
11537 /******/ __webpack_require__.nc = undefined;
11538 /******/ })();
11539 /******/
11540 /************************************************************************/
11541 let __webpack_exports__ = {};
11542 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11543 (() => {
11544 "use strict";
11545 /*!*******************************************!*\
11546 !*** ./assets/src/js/frontend/profile.js ***!
11547 \*******************************************/
11548 __webpack_require__.r(__webpack_exports__);
11549 /* harmony import */ var _profile_course_tab__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./profile/course-tab */ "./assets/src/js/frontend/profile/course-tab.js");
11550 /* harmony import */ var _profile_statistic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./profile/statistic */ "./assets/src/js/frontend/profile/statistic.js");
11551 /* harmony import */ var _profile_order_recover__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./profile/order-recover */ "./assets/src/js/frontend/profile/order-recover.js");
11552 /* harmony import */ var _profile_cover_image__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./profile/cover-image */ "./assets/src/js/frontend/profile/cover-image.js");
11553 /* harmony import */ var _profile_avatar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./profile/avatar */ "./assets/src/js/frontend/profile/avatar.js");
11554 /* harmony import */ var _profile_quiz__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./profile/quiz */ "./assets/src/js/frontend/profile/quiz.js");
11555 /* harmony import */ var _profile_order_refund__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./profile/order-refund */ "./assets/src/js/frontend/profile/order-refund.js");
11556 /* harmony import */ var _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../admin/courses/view-students-modal */ "./assets/src/js/admin/courses/view-students-modal.js");
11557
11558
11559
11560
11561
11562
11563
11564
11565 (0,_profile_cover_image__WEBPACK_IMPORTED_MODULE_3__["default"])();
11566 (0,_profile_quiz__WEBPACK_IMPORTED_MODULE_5__["default"])();
11567 (0,_profile_statistic__WEBPACK_IMPORTED_MODULE_1__["default"])();
11568 (0,_profile_order_recover__WEBPACK_IMPORTED_MODULE_2__["default"])();
11569 (0,_profile_order_refund__WEBPACK_IMPORTED_MODULE_6__["default"])();
11570 new _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__.ViewStudentsModal();
11571 document.addEventListener('DOMContentLoaded', function (event) {
11572 (0,_profile_course_tab__WEBPACK_IMPORTED_MODULE_0__["default"])();
11573 });
11574 if (document.getElementById('learnpress-avatar-upload')) {
11575 (0,_profile_avatar__WEBPACK_IMPORTED_MODULE_4__["default"])();
11576 }
11577 })();
11578
11579 /******/ })()
11580 ;
11581 //# sourceMappingURL=profile.js.map