PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9.1
4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 All 141 releases
learnpress / assets / js / dist / frontend / profile.js

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

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