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

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

11,601 lines 416.5 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.17
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 * Gets the popup container which contains the backdrop and the popup itself.
6333 *
6334 * @returns {HTMLElement | null}
6335 */
6336 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6337
6338 /**
6339 * @param {string} selectorString
6340 * @returns {HTMLElement | null}
6341 */
6342 const elementBySelector = selectorString => {
6343 const container = getContainer();
6344 return container ? container.querySelector(selectorString) : null;
6345 };
6346
6347 /**
6348 * @param {string} className
6349 * @returns {HTMLElement | null}
6350 */
6351 const elementByClass = className => {
6352 return elementBySelector(`.${className}`);
6353 };
6354
6355 /**
6356 * @returns {HTMLElement | null}
6357 */
6358 const getPopup = () => elementByClass(swalClasses.popup);
6359
6360 /**
6361 * @returns {HTMLElement | null}
6362 */
6363 const getIcon = () => elementByClass(swalClasses.icon);
6364
6365 /**
6366 * @returns {HTMLElement | null}
6367 */
6368 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6369
6370 /**
6371 * @returns {HTMLElement | null}
6372 */
6373 const getTitle = () => elementByClass(swalClasses.title);
6374
6375 /**
6376 * @returns {HTMLElement | null}
6377 */
6378 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6379
6380 /**
6381 * @returns {HTMLElement | null}
6382 */
6383 const getImage = () => elementByClass(swalClasses.image);
6384
6385 /**
6386 * @returns {HTMLElement | null}
6387 */
6388 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6389
6390 /**
6391 * @returns {HTMLElement | null}
6392 */
6393 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6394
6395 /**
6396 * @returns {HTMLButtonElement | null}
6397 */
6398 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6399
6400 /**
6401 * @returns {HTMLButtonElement | null}
6402 */
6403 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6404
6405 /**
6406 * @returns {HTMLButtonElement | null}
6407 */
6408 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6409
6410 /**
6411 * @returns {HTMLElement | null}
6412 */
6413 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6414
6415 /**
6416 * @returns {HTMLElement | null}
6417 */
6418 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6419
6420 /**
6421 * @returns {HTMLElement | null}
6422 */
6423 const getActions = () => elementByClass(swalClasses.actions);
6424
6425 /**
6426 * @returns {HTMLElement | null}
6427 */
6428 const getFooter = () => elementByClass(swalClasses.footer);
6429
6430 /**
6431 * @returns {HTMLElement | null}
6432 */
6433 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6434
6435 /**
6436 * @returns {HTMLElement | null}
6437 */
6438 const getCloseButton = () => elementByClass(swalClasses.close);
6439
6440 // https://github.com/jkup/focusable/blob/master/index.js
6441 const focusable = `
6442 a[href],
6443 area[href],
6444 input:not([disabled]),
6445 select:not([disabled]),
6446 textarea:not([disabled]),
6447 button:not([disabled]),
6448 iframe,
6449 object,
6450 embed,
6451 [tabindex="0"],
6452 [contenteditable],
6453 audio[controls],
6454 video[controls],
6455 summary
6456 `;
6457 /**
6458 * @returns {HTMLElement[]}
6459 */
6460 const getFocusableElements = () => {
6461 const popup = getPopup();
6462 if (!popup) {
6463 return [];
6464 }
6465 /** @type {NodeListOf<HTMLElement>} */
6466 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6467 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6468 // sort according to tabindex
6469 .sort((a, b) => {
6470 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6471 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6472 if (tabindexA > tabindexB) {
6473 return 1;
6474 } else if (tabindexA < tabindexB) {
6475 return -1;
6476 }
6477 return 0;
6478 });
6479
6480 /** @type {NodeListOf<HTMLElement>} */
6481 const otherFocusableElements = popup.querySelectorAll(focusable);
6482 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6483 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6484 };
6485
6486 /**
6487 * @returns {boolean}
6488 */
6489 const isModal = () => {
6490 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6491 };
6492
6493 /**
6494 * @returns {boolean}
6495 */
6496 const isToast = () => {
6497 const popup = getPopup();
6498 if (!popup) {
6499 return false;
6500 }
6501 return hasClass(popup, swalClasses.toast);
6502 };
6503
6504 /**
6505 * @returns {boolean}
6506 */
6507 const isLoading = () => {
6508 const popup = getPopup();
6509 if (!popup) {
6510 return false;
6511 }
6512 return popup.hasAttribute('data-loading');
6513 };
6514
6515 /**
6516 * Securely set innerHTML of an element
6517 * https://github.com/sweetalert2/sweetalert2/issues/1926
6518 *
6519 * @param {HTMLElement} elem
6520 * @param {string} html
6521 */
6522 const setInnerHtml = (elem, html) => {
6523 elem.textContent = '';
6524 if (html) {
6525 const parser = new DOMParser();
6526 const parsed = parser.parseFromString(html, `text/html`);
6527 const head = parsed.querySelector('head');
6528 if (head) {
6529 Array.from(head.childNodes).forEach(child => {
6530 elem.appendChild(child);
6531 });
6532 }
6533 const body = parsed.querySelector('body');
6534 if (body) {
6535 Array.from(body.childNodes).forEach(child => {
6536 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6537 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6538 } else {
6539 elem.appendChild(child);
6540 }
6541 });
6542 }
6543 }
6544 };
6545
6546 /**
6547 * @param {HTMLElement} elem
6548 * @param {string} className
6549 * @returns {boolean}
6550 */
6551 const hasClass = (elem, className) => {
6552 if (!className) {
6553 return false;
6554 }
6555 const classList = className.split(/\s+/);
6556 for (let i = 0; i < classList.length; i++) {
6557 if (!elem.classList.contains(classList[i])) {
6558 return false;
6559 }
6560 }
6561 return true;
6562 };
6563
6564 /**
6565 * @param {HTMLElement} elem
6566 * @param {SweetAlertOptions} params
6567 */
6568 const removeCustomClasses = (elem, params) => {
6569 Array.from(elem.classList).forEach(className => {
6570 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6571 elem.classList.remove(className);
6572 }
6573 });
6574 };
6575
6576 /**
6577 * @param {HTMLElement} elem
6578 * @param {SweetAlertOptions} params
6579 * @param {string} className
6580 */
6581 const applyCustomClass = (elem, params, className) => {
6582 removeCustomClasses(elem, params);
6583 if (!params.customClass) {
6584 return;
6585 }
6586 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6587 if (!customClass) {
6588 return;
6589 }
6590 if (typeof customClass !== 'string' && !customClass.forEach) {
6591 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6592 return;
6593 }
6594 addClass(elem, customClass);
6595 };
6596
6597 /**
6598 * @param {HTMLElement} popup
6599 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6600 * @returns {HTMLInputElement | null}
6601 */
6602 const getInput$1 = (popup, inputClass) => {
6603 if (!inputClass) {
6604 return null;
6605 }
6606 switch (inputClass) {
6607 case 'select':
6608 case 'textarea':
6609 case 'file':
6610 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6611 case 'checkbox':
6612 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6613 case 'radio':
6614 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6615 case 'range':
6616 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6617 default:
6618 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6619 }
6620 };
6621
6622 /**
6623 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6624 */
6625 const focusInput = input => {
6626 input.focus();
6627
6628 // place cursor at end of text in text input
6629 if (input.type !== 'file') {
6630 // http://stackoverflow.com/a/2345915
6631 const val = input.value;
6632 input.value = '';
6633 input.value = val;
6634 }
6635 };
6636
6637 /**
6638 * @param {HTMLElement | HTMLElement[] | null} target
6639 * @param {string | string[] | readonly string[] | undefined} classList
6640 * @param {boolean} condition
6641 */
6642 const toggleClass = (target, classList, condition) => {
6643 if (!target || !classList) {
6644 return;
6645 }
6646 if (typeof classList === 'string') {
6647 classList = classList.split(/\s+/).filter(Boolean);
6648 }
6649 classList.forEach(className => {
6650 if (Array.isArray(target)) {
6651 target.forEach(elem => {
6652 if (condition) {
6653 elem.classList.add(className);
6654 } else {
6655 elem.classList.remove(className);
6656 }
6657 });
6658 } else {
6659 if (condition) {
6660 target.classList.add(className);
6661 } else {
6662 target.classList.remove(className);
6663 }
6664 }
6665 });
6666 };
6667
6668 /**
6669 * @param {HTMLElement | HTMLElement[] | null} target
6670 * @param {string | string[] | readonly string[] | undefined} classList
6671 */
6672 const addClass = (target, classList) => {
6673 toggleClass(target, classList, true);
6674 };
6675
6676 /**
6677 * @param {HTMLElement | HTMLElement[] | null} target
6678 * @param {string | string[] | readonly string[] | undefined} classList
6679 */
6680 const removeClass = (target, classList) => {
6681 toggleClass(target, classList, false);
6682 };
6683
6684 /**
6685 * Get direct child of an element by class name
6686 *
6687 * @param {HTMLElement} elem
6688 * @param {string} className
6689 * @returns {HTMLElement | undefined}
6690 */
6691 const getDirectChildByClass = (elem, className) => {
6692 const children = Array.from(elem.children);
6693 for (let i = 0; i < children.length; i++) {
6694 const child = children[i];
6695 if (child instanceof HTMLElement && hasClass(child, className)) {
6696 return child;
6697 }
6698 }
6699 };
6700
6701 /**
6702 * @param {HTMLElement} elem
6703 * @param {string} property
6704 * @param {string | number | null | undefined} value
6705 */
6706 const applyNumericalStyle = (elem, property, value) => {
6707 if (value === `${parseInt(`${value}`)}`) {
6708 value = parseInt(value);
6709 }
6710 if (value || parseInt(`${value}`) === 0) {
6711 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6712 } else {
6713 elem.style.removeProperty(property);
6714 }
6715 };
6716
6717 /**
6718 * @param {HTMLElement | null} elem
6719 * @param {string} display
6720 */
6721 const show = (elem, display = 'flex') => {
6722 if (!elem) {
6723 return;
6724 }
6725 elem.style.display = display;
6726 };
6727
6728 /**
6729 * @param {HTMLElement | null} elem
6730 */
6731 const hide = elem => {
6732 if (!elem) {
6733 return;
6734 }
6735 elem.style.display = 'none';
6736 };
6737
6738 /**
6739 * @param {HTMLElement | null} elem
6740 * @param {string} display
6741 */
6742 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6743 if (!elem) {
6744 return;
6745 }
6746 new MutationObserver(() => {
6747 toggle(elem, elem.innerHTML, display);
6748 }).observe(elem, {
6749 childList: true,
6750 subtree: true
6751 });
6752 };
6753
6754 /**
6755 * @param {HTMLElement} parent
6756 * @param {string} selector
6757 * @param {string} property
6758 * @param {string} value
6759 */
6760 const setStyle = (parent, selector, property, value) => {
6761 /** @type {HTMLElement | null} */
6762 const el = parent.querySelector(selector);
6763 if (el) {
6764 el.style.setProperty(property, value);
6765 }
6766 };
6767
6768 /**
6769 * @param {HTMLElement} elem
6770 * @param {boolean | string | null | undefined} condition
6771 * @param {string} display
6772 */
6773 const toggle = (elem, condition, display = 'flex') => {
6774 if (condition) {
6775 show(elem, display);
6776 } else {
6777 hide(elem);
6778 }
6779 };
6780
6781 /**
6782 * borrowed from jquery $(elem).is(':visible') implementation
6783 *
6784 * @param {HTMLElement | null} elem
6785 * @returns {boolean}
6786 */
6787 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6788
6789 /**
6790 * @returns {boolean}
6791 */
6792 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6793
6794 /**
6795 * @param {HTMLElement} elem
6796 * @returns {boolean}
6797 */
6798 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6799
6800 /**
6801 * @param {HTMLElement} element
6802 * @param {HTMLElement} stopElement
6803 * @returns {boolean}
6804 */
6805 const selfOrParentIsScrollable = (element, stopElement) => {
6806 let parent = /** @type {HTMLElement | null} */element;
6807 while (parent && parent !== stopElement) {
6808 if (isScrollable(parent)) {
6809 return true;
6810 }
6811 parent = parent.parentElement;
6812 }
6813 return false;
6814 };
6815
6816 /**
6817 * borrowed from https://stackoverflow.com/a/46352119
6818 *
6819 * @param {HTMLElement} elem
6820 * @returns {boolean}
6821 */
6822 const hasCssAnimation = elem => {
6823 const style = window.getComputedStyle(elem);
6824 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6825 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6826 return animDuration > 0 || transDuration > 0;
6827 };
6828
6829 /**
6830 * @param {number} timer
6831 * @param {boolean} reset
6832 */
6833 const animateTimerProgressBar = (timer, reset = false) => {
6834 const timerProgressBar = getTimerProgressBar();
6835 if (!timerProgressBar) {
6836 return;
6837 }
6838 if (isVisible$1(timerProgressBar)) {
6839 if (reset) {
6840 timerProgressBar.style.transition = 'none';
6841 timerProgressBar.style.width = '100%';
6842 }
6843 setTimeout(() => {
6844 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6845 timerProgressBar.style.width = '0%';
6846 }, 10);
6847 }
6848 };
6849 const stopTimerProgressBar = () => {
6850 const timerProgressBar = getTimerProgressBar();
6851 if (!timerProgressBar) {
6852 return;
6853 }
6854 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6855 timerProgressBar.style.removeProperty('transition');
6856 timerProgressBar.style.width = '100%';
6857 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6858 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6859 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6860 };
6861
6862 /**
6863 * Detect Node env
6864 *
6865 * @returns {boolean}
6866 */
6867 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6868
6869 const sweetHTML = `
6870 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6871 <button type="button" class="${swalClasses.close}"></button>
6872 <ul class="${swalClasses['progress-steps']}"></ul>
6873 <div class="${swalClasses.icon}"></div>
6874 <img class="${swalClasses.image}" />
6875 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6876 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6877 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6878 <input type="file" class="${swalClasses.file}" />
6879 <div class="${swalClasses.range}">
6880 <input type="range" />
6881 <output></output>
6882 </div>
6883 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6884 <div class="${swalClasses.radio}"></div>
6885 <label class="${swalClasses.checkbox}">
6886 <input type="checkbox" id="${swalClasses.checkbox}" />
6887 <span class="${swalClasses.label}"></span>
6888 </label>
6889 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6890 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6891 <div class="${swalClasses.actions}">
6892 <div class="${swalClasses.loader}"></div>
6893 <button type="button" class="${swalClasses.confirm}"></button>
6894 <button type="button" class="${swalClasses.deny}"></button>
6895 <button type="button" class="${swalClasses.cancel}"></button>
6896 </div>
6897 <div class="${swalClasses.footer}"></div>
6898 <div class="${swalClasses['timer-progress-bar-container']}">
6899 <div class="${swalClasses['timer-progress-bar']}"></div>
6900 </div>
6901 </div>
6902 `.replace(/(^|\n)\s*/g, '');
6903
6904 /**
6905 * @returns {boolean}
6906 */
6907 const resetOldContainer = () => {
6908 const oldContainer = getContainer();
6909 if (!oldContainer) {
6910 return false;
6911 }
6912 oldContainer.remove();
6913 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6914 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6915 swalClasses['has-column']]);
6916 return true;
6917 };
6918 const resetValidationMessage$1 = () => {
6919 if (globalState.currentInstance) {
6920 globalState.currentInstance.resetValidationMessage();
6921 }
6922 };
6923 const addInputChangeListeners = () => {
6924 const popup = getPopup();
6925 if (!popup) {
6926 return;
6927 }
6928 const input = getDirectChildByClass(popup, swalClasses.input);
6929 const file = getDirectChildByClass(popup, swalClasses.file);
6930 /** @type {HTMLInputElement | null} */
6931 const range = popup.querySelector(`.${swalClasses.range} input`);
6932 /** @type {HTMLOutputElement | null} */
6933 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6934 const select = getDirectChildByClass(popup, swalClasses.select);
6935 /** @type {HTMLInputElement | null} */
6936 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6937 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6938 if (input) {
6939 input.oninput = resetValidationMessage$1;
6940 }
6941 if (file) {
6942 file.onchange = resetValidationMessage$1;
6943 }
6944 if (select) {
6945 select.onchange = resetValidationMessage$1;
6946 }
6947 if (checkbox) {
6948 checkbox.onchange = resetValidationMessage$1;
6949 }
6950 if (textarea) {
6951 textarea.oninput = resetValidationMessage$1;
6952 }
6953 if (range && rangeOutput) {
6954 range.oninput = () => {
6955 resetValidationMessage$1();
6956 rangeOutput.value = range.value;
6957 };
6958 range.onchange = () => {
6959 resetValidationMessage$1();
6960 rangeOutput.value = range.value;
6961 };
6962 }
6963 };
6964
6965 /**
6966 * @param {string | HTMLElement} target
6967 * @returns {HTMLElement}
6968 */
6969 const getTarget = target => {
6970 if (typeof target === 'string') {
6971 const element = document.querySelector(target);
6972 if (!element) {
6973 throw new Error(`Target element "${target}" not found`);
6974 }
6975 return /** @type {HTMLElement} */element;
6976 }
6977 return target;
6978 };
6979
6980 /**
6981 * @param {SweetAlertOptions} params
6982 */
6983 const setupAccessibility = params => {
6984 const popup = getPopup();
6985 if (!popup) {
6986 return;
6987 }
6988 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6989 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6990 if (!params.toast) {
6991 popup.setAttribute('aria-modal', 'true');
6992 }
6993 };
6994
6995 /**
6996 * @param {HTMLElement} targetElement
6997 */
6998 const setupRTL = targetElement => {
6999 if (window.getComputedStyle(targetElement).direction === 'rtl') {
7000 addClass(getContainer(), swalClasses.rtl);
7001 globalState.isRTL = true;
7002 }
7003 };
7004
7005 /**
7006 * Add modal + backdrop to DOM
7007 *
7008 * @param {SweetAlertOptions} params
7009 */
7010 const init = params => {
7011 // Clean up the old popup container if it exists
7012 const oldContainerExisted = resetOldContainer();
7013 if (isNodeEnv()) {
7014 error('SweetAlert2 requires document to initialize');
7015 return;
7016 }
7017 const container = document.createElement('div');
7018 container.className = swalClasses.container;
7019 if (oldContainerExisted) {
7020 addClass(container, swalClasses['no-transition']);
7021 }
7022 setInnerHtml(container, sweetHTML);
7023 container.dataset['swal2Theme'] = params.theme;
7024 const targetElement = getTarget(params.target || 'body');
7025 targetElement.appendChild(container);
7026 if (params.topLayer) {
7027 container.setAttribute('popover', '');
7028 container.showPopover();
7029 }
7030 setupAccessibility(params);
7031 setupRTL(targetElement);
7032 addInputChangeListeners();
7033 };
7034
7035 /**
7036 * @param {HTMLElement | object | string} param
7037 * @param {HTMLElement} target
7038 */
7039 const parseHtmlToContainer = (param, target) => {
7040 // DOM element
7041 if (param instanceof HTMLElement) {
7042 target.appendChild(param);
7043 }
7044
7045 // Object
7046 else if (typeof param === 'object') {
7047 handleObject(param, target);
7048 }
7049
7050 // Plain string
7051 else if (param) {
7052 setInnerHtml(target, param);
7053 }
7054 };
7055
7056 /**
7057 * @param {object} param
7058 * @param {HTMLElement} target
7059 */
7060 const handleObject = (param, target) => {
7061 // JQuery element(s)
7062 if ('jquery' in param) {
7063 handleJqueryElem(target, param);
7064 }
7065
7066 // For other objects use their string representation
7067 else {
7068 setInnerHtml(target, param.toString());
7069 }
7070 };
7071
7072 /**
7073 * @param {HTMLElement} target
7074 * @param {any} elem
7075 */
7076 const handleJqueryElem = (target, elem) => {
7077 target.textContent = '';
7078 if (0 in elem) {
7079 for (let i = 0; i in elem; i++) {
7080 target.appendChild(elem[i].cloneNode(true));
7081 }
7082 } else {
7083 target.appendChild(elem.cloneNode(true));
7084 }
7085 };
7086
7087 /**
7088 * @param {SweetAlert} instance
7089 * @param {SweetAlertOptions} params
7090 */
7091 const renderActions = (instance, params) => {
7092 const actions = getActions();
7093 const loader = getLoader();
7094 if (!actions || !loader) {
7095 return;
7096 }
7097
7098 // Actions (buttons) wrapper
7099 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
7100 hide(actions);
7101 } else {
7102 show(actions);
7103 }
7104
7105 // Custom class
7106 applyCustomClass(actions, params, 'actions');
7107
7108 // Render all the buttons
7109 renderButtons(actions, loader, params);
7110
7111 // Loader
7112 setInnerHtml(loader, params.loaderHtml || '');
7113 applyCustomClass(loader, params, 'loader');
7114 };
7115
7116 /**
7117 * @param {HTMLElement} actions
7118 * @param {HTMLElement} loader
7119 * @param {SweetAlertOptions} params
7120 */
7121 function renderButtons(actions, loader, params) {
7122 const confirmButton = getConfirmButton();
7123 const denyButton = getDenyButton();
7124 const cancelButton = getCancelButton();
7125 if (!confirmButton || !denyButton || !cancelButton) {
7126 return;
7127 }
7128
7129 // Render buttons
7130 renderButton(confirmButton, 'confirm', params);
7131 renderButton(denyButton, 'deny', params);
7132 renderButton(cancelButton, 'cancel', params);
7133 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
7134 if (params.reverseButtons) {
7135 if (params.toast) {
7136 actions.insertBefore(cancelButton, confirmButton);
7137 actions.insertBefore(denyButton, confirmButton);
7138 } else {
7139 actions.insertBefore(cancelButton, loader);
7140 actions.insertBefore(denyButton, loader);
7141 actions.insertBefore(confirmButton, loader);
7142 }
7143 }
7144 }
7145
7146 /**
7147 * @param {HTMLElement} confirmButton
7148 * @param {HTMLElement} denyButton
7149 * @param {HTMLElement} cancelButton
7150 * @param {SweetAlertOptions} params
7151 */
7152 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
7153 if (!params.buttonsStyling) {
7154 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7155 return;
7156 }
7157 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7158
7159 // Apply custom background colors to action buttons
7160 if (params.confirmButtonColor) {
7161 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
7162 }
7163 if (params.denyButtonColor) {
7164 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
7165 }
7166 if (params.cancelButtonColor) {
7167 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
7168 }
7169
7170 // Apply the outline color to action buttons
7171 applyOutlineColor(confirmButton);
7172 applyOutlineColor(denyButton);
7173 applyOutlineColor(cancelButton);
7174 }
7175
7176 /**
7177 * @param {HTMLElement} button
7178 */
7179 function applyOutlineColor(button) {
7180 const buttonStyle = window.getComputedStyle(button);
7181 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7182 // If the button already has a custom outline color, no need to change it
7183 return;
7184 }
7185 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7186 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7187 }
7188
7189 /**
7190 * @param {HTMLElement} button
7191 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7192 * @param {SweetAlertOptions} params
7193 */
7194 function renderButton(button, buttonType, params) {
7195 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7196 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7197 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7198 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7199
7200 // Add buttons custom classes
7201 button.className = swalClasses[buttonType];
7202 applyCustomClass(button, params, `${buttonType}Button`);
7203 }
7204
7205 /**
7206 * @param {SweetAlert} instance
7207 * @param {SweetAlertOptions} params
7208 */
7209 const renderCloseButton = (instance, params) => {
7210 const closeButton = getCloseButton();
7211 if (!closeButton) {
7212 return;
7213 }
7214 setInnerHtml(closeButton, params.closeButtonHtml || '');
7215
7216 // Custom class
7217 applyCustomClass(closeButton, params, 'closeButton');
7218 toggle(closeButton, params.showCloseButton);
7219 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7220 };
7221
7222 /**
7223 * @param {SweetAlert} instance
7224 * @param {SweetAlertOptions} params
7225 */
7226 const renderContainer = (instance, params) => {
7227 const container = getContainer();
7228 if (!container) {
7229 return;
7230 }
7231 handleBackdropParam(container, params.backdrop);
7232 handlePositionParam(container, params.position);
7233 handleGrowParam(container, params.grow);
7234
7235 // Custom class
7236 applyCustomClass(container, params, 'container');
7237 };
7238
7239 /**
7240 * @param {HTMLElement} container
7241 * @param {SweetAlertOptions['backdrop']} backdrop
7242 */
7243 function handleBackdropParam(container, backdrop) {
7244 if (typeof backdrop === 'string') {
7245 container.style.background = backdrop;
7246 } else if (!backdrop) {
7247 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7248 }
7249 }
7250
7251 /**
7252 * @param {HTMLElement} container
7253 * @param {SweetAlertOptions['position']} position
7254 */
7255 function handlePositionParam(container, position) {
7256 if (!position) {
7257 return;
7258 }
7259 if (position in swalClasses) {
7260 addClass(container, swalClasses[position]);
7261 } else {
7262 warn('The "position" parameter is not valid, defaulting to "center"');
7263 addClass(container, swalClasses.center);
7264 }
7265 }
7266
7267 /**
7268 * @param {HTMLElement} container
7269 * @param {SweetAlertOptions['grow']} grow
7270 */
7271 function handleGrowParam(container, grow) {
7272 if (!grow) {
7273 return;
7274 }
7275 addClass(container, swalClasses[`grow-${grow}`]);
7276 }
7277
7278 /**
7279 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7280 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7281 * This is the approach that Babel will probably take to implement private methods/fields
7282 * https://github.com/tc39/proposal-private-methods
7283 * https://github.com/babel/babel/pull/7555
7284 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7285 * then we can use that language feature.
7286 */
7287
7288 var privateProps = {
7289 innerParams: new WeakMap(),
7290 domCache: new WeakMap()
7291 };
7292
7293 /// <reference path="../../../../sweetalert2.d.ts"/>
7294
7295
7296 /** @type {InputClass[]} */
7297 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7298
7299 /**
7300 * @param {SweetAlert} instance
7301 * @param {SweetAlertOptions} params
7302 */
7303 const renderInput = (instance, params) => {
7304 const popup = getPopup();
7305 if (!popup) {
7306 return;
7307 }
7308 const innerParams = privateProps.innerParams.get(instance);
7309 const rerender = !innerParams || params.input !== innerParams.input;
7310 inputClasses.forEach(inputClass => {
7311 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7312 if (!inputContainer) {
7313 return;
7314 }
7315
7316 // set attributes
7317 setAttributes(inputClass, params.inputAttributes);
7318
7319 // set class
7320 inputContainer.className = swalClasses[inputClass];
7321 if (rerender) {
7322 hide(inputContainer);
7323 }
7324 });
7325 if (params.input) {
7326 if (rerender) {
7327 showInput(params);
7328 }
7329 // set custom class
7330 setCustomClass(params);
7331 }
7332 };
7333
7334 /**
7335 * @param {SweetAlertOptions} params
7336 */
7337 const showInput = params => {
7338 if (!params.input) {
7339 return;
7340 }
7341 if (!renderInputType[params.input]) {
7342 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7343 return;
7344 }
7345 const inputContainer = getInputContainer(params.input);
7346 if (!inputContainer) {
7347 return;
7348 }
7349 const input = renderInputType[params.input](inputContainer, params);
7350 show(inputContainer);
7351
7352 // input autofocus
7353 if (params.inputAutoFocus) {
7354 setTimeout(() => {
7355 focusInput(input);
7356 });
7357 }
7358 };
7359
7360 /**
7361 * @param {HTMLInputElement} input
7362 */
7363 const removeAttributes = input => {
7364 for (let i = 0; i < input.attributes.length; i++) {
7365 const attrName = input.attributes[i].name;
7366 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
7367 input.removeAttribute(attrName);
7368 }
7369 }
7370 };
7371
7372 /**
7373 * @param {InputClass} inputClass
7374 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7375 */
7376 const setAttributes = (inputClass, inputAttributes) => {
7377 const popup = getPopup();
7378 if (!popup) {
7379 return;
7380 }
7381 const input = getInput$1(popup, inputClass);
7382 if (!input) {
7383 return;
7384 }
7385 removeAttributes(input);
7386 for (const attr in inputAttributes) {
7387 input.setAttribute(attr, inputAttributes[attr]);
7388 }
7389 };
7390
7391 /**
7392 * @param {SweetAlertOptions} params
7393 */
7394 const setCustomClass = params => {
7395 if (!params.input) {
7396 return;
7397 }
7398 const inputContainer = getInputContainer(params.input);
7399 if (inputContainer) {
7400 applyCustomClass(inputContainer, params, 'input');
7401 }
7402 };
7403
7404 /**
7405 * @param {HTMLInputElement | HTMLTextAreaElement} input
7406 * @param {SweetAlertOptions} params
7407 */
7408 const setInputPlaceholder = (input, params) => {
7409 if (!input.placeholder && params.inputPlaceholder) {
7410 input.placeholder = params.inputPlaceholder;
7411 }
7412 };
7413
7414 /**
7415 * @param {Input} input
7416 * @param {Input} prependTo
7417 * @param {SweetAlertOptions} params
7418 */
7419 const setInputLabel = (input, prependTo, params) => {
7420 if (params.inputLabel) {
7421 const label = document.createElement('label');
7422 const labelClass = swalClasses['input-label'];
7423 label.setAttribute('for', input.id);
7424 label.className = labelClass;
7425 if (typeof params.customClass === 'object') {
7426 addClass(label, params.customClass.inputLabel);
7427 }
7428 label.innerText = params.inputLabel;
7429 prependTo.insertAdjacentElement('beforebegin', label);
7430 }
7431 };
7432
7433 /**
7434 * @param {SweetAlertInput} inputType
7435 * @returns {HTMLElement | undefined}
7436 */
7437 const getInputContainer = inputType => {
7438 const popup = getPopup();
7439 if (!popup) {
7440 return;
7441 }
7442 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7443 };
7444
7445 /**
7446 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7447 * @param {SweetAlertOptions['inputValue']} inputValue
7448 */
7449 const checkAndSetInputValue = (input, inputValue) => {
7450 if (['string', 'number'].includes(typeof inputValue)) {
7451 input.value = `${inputValue}`;
7452 } else if (!isPromise(inputValue)) {
7453 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7454 }
7455 };
7456
7457 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7458 const renderInputType = {};
7459
7460 /**
7461 * @param {Input | HTMLElement} input
7462 * @param {SweetAlertOptions} params
7463 * @returns {Input}
7464 */
7465 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} */
7466 (input, params) => {
7467 const inputElement = /** @type {HTMLInputElement} */input;
7468 checkAndSetInputValue(inputElement, params.inputValue);
7469 setInputLabel(inputElement, inputElement, params);
7470 setInputPlaceholder(inputElement, params);
7471 inputElement.type = /** @type {string} */params.input;
7472 return inputElement;
7473 };
7474
7475 /**
7476 * @param {Input | HTMLElement} input
7477 * @param {SweetAlertOptions} params
7478 * @returns {Input}
7479 */
7480 renderInputType.file = (input, params) => {
7481 const inputElement = /** @type {HTMLInputElement} */input;
7482 setInputLabel(inputElement, inputElement, params);
7483 setInputPlaceholder(inputElement, params);
7484 return inputElement;
7485 };
7486
7487 /**
7488 * @param {Input | HTMLElement} range
7489 * @param {SweetAlertOptions} params
7490 * @returns {Input}
7491 */
7492 renderInputType.range = (range, params) => {
7493 const rangeContainer = /** @type {HTMLElement} */range;
7494 const rangeInput = rangeContainer.querySelector('input');
7495 const rangeOutput = rangeContainer.querySelector('output');
7496 if (rangeInput) {
7497 checkAndSetInputValue(rangeInput, params.inputValue);
7498 rangeInput.type = /** @type {string} */params.input;
7499 setInputLabel(rangeInput, /** @type {Input} */range, params);
7500 }
7501 if (rangeOutput) {
7502 checkAndSetInputValue(rangeOutput, params.inputValue);
7503 }
7504 return /** @type {Input} */range;
7505 };
7506
7507 /**
7508 * @param {Input | HTMLElement} select
7509 * @param {SweetAlertOptions} params
7510 * @returns {Input}
7511 */
7512 renderInputType.select = (select, params) => {
7513 const selectElement = /** @type {HTMLSelectElement} */select;
7514 selectElement.textContent = '';
7515 if (params.inputPlaceholder) {
7516 const placeholder = document.createElement('option');
7517 setInnerHtml(placeholder, params.inputPlaceholder);
7518 placeholder.value = '';
7519 placeholder.disabled = true;
7520 placeholder.selected = true;
7521 selectElement.appendChild(placeholder);
7522 }
7523 setInputLabel(selectElement, selectElement, params);
7524 return selectElement;
7525 };
7526
7527 /**
7528 * @param {Input | HTMLElement} radio
7529 * @returns {Input}
7530 */
7531 renderInputType.radio = radio => {
7532 const radioElement = /** @type {HTMLElement} */radio;
7533 radioElement.textContent = '';
7534 return /** @type {Input} */radio;
7535 };
7536
7537 /**
7538 * @param {Input | HTMLElement} checkboxContainer
7539 * @param {SweetAlertOptions} params
7540 * @returns {Input}
7541 */
7542 renderInputType.checkbox = (checkboxContainer, params) => {
7543 const popup = getPopup();
7544 if (!popup) {
7545 throw new Error('Popup not found');
7546 }
7547 const checkbox = getInput$1(popup, 'checkbox');
7548 if (!checkbox) {
7549 throw new Error('Checkbox input not found');
7550 }
7551 checkbox.value = '1';
7552 checkbox.checked = Boolean(params.inputValue);
7553 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7554 const label = containerElement.querySelector('span');
7555 if (label) {
7556 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7557 if (placeholderOrLabel) {
7558 setInnerHtml(label, placeholderOrLabel);
7559 }
7560 }
7561 return checkbox;
7562 };
7563
7564 /**
7565 * @param {Input | HTMLElement} textarea
7566 * @param {SweetAlertOptions} params
7567 * @returns {Input}
7568 */
7569 renderInputType.textarea = (textarea, params) => {
7570 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7571 checkAndSetInputValue(textareaElement, params.inputValue);
7572 setInputPlaceholder(textareaElement, params);
7573 setInputLabel(textareaElement, textareaElement, params);
7574
7575 /**
7576 * @param {HTMLElement} el
7577 * @returns {number}
7578 */
7579 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7580
7581 // https://github.com/sweetalert2/sweetalert2/issues/2291
7582 setTimeout(() => {
7583 // https://github.com/sweetalert2/sweetalert2/issues/1699
7584 if ('MutationObserver' in window) {
7585 const popup = getPopup();
7586 if (!popup) {
7587 return;
7588 }
7589 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7590 const textareaResizeHandler = () => {
7591 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7592 if (!document.body.contains(textareaElement)) {
7593 return;
7594 }
7595 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7596 const popupElement = getPopup();
7597 if (popupElement) {
7598 if (textareaWidth > initialPopupWidth) {
7599 popupElement.style.width = `${textareaWidth}px`;
7600 } else {
7601 applyNumericalStyle(popupElement, 'width', params.width);
7602 }
7603 }
7604 };
7605 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7606 attributes: true,
7607 attributeFilter: ['style']
7608 });
7609 }
7610 });
7611 return textareaElement;
7612 };
7613
7614 /**
7615 * @param {SweetAlert} instance
7616 * @param {SweetAlertOptions} params
7617 */
7618 const renderContent = (instance, params) => {
7619 const htmlContainer = getHtmlContainer();
7620 if (!htmlContainer) {
7621 return;
7622 }
7623 showWhenInnerHtmlPresent(htmlContainer);
7624 applyCustomClass(htmlContainer, params, 'htmlContainer');
7625
7626 // Content as HTML
7627 if (params.html) {
7628 parseHtmlToContainer(params.html, htmlContainer);
7629 show(htmlContainer, 'block');
7630 }
7631
7632 // Content as plain text
7633 else if (params.text) {
7634 htmlContainer.textContent = params.text;
7635 show(htmlContainer, 'block');
7636 }
7637
7638 // No content
7639 else {
7640 hide(htmlContainer);
7641 }
7642 renderInput(instance, params);
7643 };
7644
7645 /**
7646 * @param {SweetAlert} instance
7647 * @param {SweetAlertOptions} params
7648 */
7649 const renderFooter = (instance, params) => {
7650 const footer = getFooter();
7651 if (!footer) {
7652 return;
7653 }
7654 showWhenInnerHtmlPresent(footer);
7655 toggle(footer, Boolean(params.footer), 'block');
7656 if (params.footer) {
7657 parseHtmlToContainer(params.footer, footer);
7658 }
7659
7660 // Custom class
7661 applyCustomClass(footer, params, 'footer');
7662 };
7663
7664 /**
7665 * @param {SweetAlert} instance
7666 * @param {SweetAlertOptions} params
7667 */
7668 const renderIcon = (instance, params) => {
7669 const innerParams = privateProps.innerParams.get(instance);
7670 const icon = getIcon();
7671 if (!icon) {
7672 return;
7673 }
7674
7675 // if the given icon already rendered, apply the styling without re-rendering the icon
7676 if (innerParams && params.icon === innerParams.icon) {
7677 // Custom or default content
7678 setContent(icon, params);
7679 applyStyles(icon, params);
7680 return;
7681 }
7682 if (!params.icon && !params.iconHtml) {
7683 hide(icon);
7684 return;
7685 }
7686 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7687 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7688 hide(icon);
7689 return;
7690 }
7691 show(icon);
7692
7693 // Custom or default content
7694 setContent(icon, params);
7695 applyStyles(icon, params);
7696
7697 // Animate icon
7698 addClass(icon, params.showClass && params.showClass.icon);
7699
7700 // Re-adjust the success icon on system theme change
7701 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7702 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7703 };
7704
7705 /**
7706 * @param {HTMLElement} icon
7707 * @param {SweetAlertOptions} params
7708 */
7709 const applyStyles = (icon, params) => {
7710 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7711 if (params.icon !== iconType) {
7712 removeClass(icon, iconClassName);
7713 }
7714 }
7715 addClass(icon, params.icon && iconTypes[params.icon]);
7716
7717 // Icon color
7718 setColor(icon, params);
7719
7720 // Success icon background color
7721 adjustSuccessIconBackgroundColor();
7722
7723 // Custom class
7724 applyCustomClass(icon, params, 'icon');
7725 };
7726
7727 // Adjust success icon background color to match the popup background color
7728 const adjustSuccessIconBackgroundColor = () => {
7729 const popup = getPopup();
7730 if (!popup) {
7731 return;
7732 }
7733 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7734 /** @type {NodeListOf<HTMLElement>} */
7735 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7736 for (let i = 0; i < successIconParts.length; i++) {
7737 successIconParts[i].style.backgroundColor = popupBackgroundColor;
7738 }
7739 };
7740
7741 /**
7742 *
7743 * @param {SweetAlertOptions} params
7744 * @returns {string}
7745 */
7746 const successIconHtml = params => `
7747 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7748 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7749 <div class="swal2-success-ring"></div>
7750 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7751 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7752 `;
7753 const errorIconHtml = `
7754 <span class="swal2-x-mark">
7755 <span class="swal2-x-mark-line-left"></span>
7756 <span class="swal2-x-mark-line-right"></span>
7757 </span>
7758 `;
7759
7760 /**
7761 * @param {HTMLElement} icon
7762 * @param {SweetAlertOptions} params
7763 */
7764 const setContent = (icon, params) => {
7765 if (!params.icon && !params.iconHtml) {
7766 return;
7767 }
7768 let oldContent = icon.innerHTML;
7769 let newContent = '';
7770 if (params.iconHtml) {
7771 newContent = iconContent(params.iconHtml);
7772 } else if (params.icon === 'success') {
7773 newContent = successIconHtml(params);
7774 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7775 } else if (params.icon === 'error') {
7776 newContent = errorIconHtml;
7777 } else if (params.icon) {
7778 const defaultIconHtml = {
7779 question: '?',
7780 warning: '!',
7781 info: 'i'
7782 };
7783 newContent = iconContent(defaultIconHtml[params.icon]);
7784 }
7785 if (oldContent.trim() !== newContent.trim()) {
7786 setInnerHtml(icon, newContent);
7787 }
7788 };
7789
7790 /**
7791 * @param {HTMLElement} icon
7792 * @param {SweetAlertOptions} params
7793 */
7794 const setColor = (icon, params) => {
7795 if (!params.iconColor) {
7796 return;
7797 }
7798 icon.style.color = params.iconColor;
7799 icon.style.borderColor = params.iconColor;
7800 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7801 setStyle(icon, sel, 'background-color', params.iconColor);
7802 }
7803 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7804 };
7805
7806 /**
7807 * @param {string} content
7808 * @returns {string}
7809 */
7810 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7811
7812 /**
7813 * @param {SweetAlert} instance
7814 * @param {SweetAlertOptions} params
7815 */
7816 const renderImage = (instance, params) => {
7817 const image = getImage();
7818 if (!image) {
7819 return;
7820 }
7821 if (!params.imageUrl) {
7822 hide(image);
7823 return;
7824 }
7825 show(image, '');
7826
7827 // Src, alt
7828 image.setAttribute('src', params.imageUrl);
7829 image.setAttribute('alt', params.imageAlt || '');
7830
7831 // Width, height
7832 applyNumericalStyle(image, 'width', params.imageWidth);
7833 applyNumericalStyle(image, 'height', params.imageHeight);
7834
7835 // Class
7836 image.className = swalClasses.image;
7837 applyCustomClass(image, params, 'image');
7838 };
7839
7840 let dragging = false;
7841 let mousedownX = 0;
7842 let mousedownY = 0;
7843 let initialX = 0;
7844 let initialY = 0;
7845
7846 /**
7847 * @param {HTMLElement} popup
7848 */
7849 const addDraggableListeners = popup => {
7850 popup.addEventListener('mousedown', down);
7851 document.body.addEventListener('mousemove', move);
7852 popup.addEventListener('mouseup', up);
7853 popup.addEventListener('touchstart', down);
7854 document.body.addEventListener('touchmove', move);
7855 popup.addEventListener('touchend', up);
7856 };
7857
7858 /**
7859 * @param {HTMLElement} popup
7860 */
7861 const removeDraggableListeners = popup => {
7862 popup.removeEventListener('mousedown', down);
7863 document.body.removeEventListener('mousemove', move);
7864 popup.removeEventListener('mouseup', up);
7865 popup.removeEventListener('touchstart', down);
7866 document.body.removeEventListener('touchmove', move);
7867 popup.removeEventListener('touchend', up);
7868 };
7869
7870 /**
7871 * @param {MouseEvent | TouchEvent} event
7872 */
7873 const down = event => {
7874 const popup = getPopup();
7875 if (!popup) {
7876 return;
7877 }
7878 const icon = getIcon();
7879 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7880 dragging = true;
7881 const clientXY = getClientXY(event);
7882 mousedownX = clientXY.clientX;
7883 mousedownY = clientXY.clientY;
7884 initialX = parseInt(popup.style.insetInlineStart) || 0;
7885 initialY = parseInt(popup.style.insetBlockStart) || 0;
7886 addClass(popup, 'swal2-dragging');
7887 }
7888 };
7889
7890 /**
7891 * @param {MouseEvent | TouchEvent} event
7892 */
7893 const move = event => {
7894 const popup = getPopup();
7895 if (!popup) {
7896 return;
7897 }
7898 if (dragging) {
7899 let {
7900 clientX,
7901 clientY
7902 } = getClientXY(event);
7903 const deltaX = clientX - mousedownX;
7904 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7905 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7906 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7907 }
7908 };
7909 const up = () => {
7910 const popup = getPopup();
7911 dragging = false;
7912 removeClass(popup, 'swal2-dragging');
7913 };
7914
7915 /**
7916 * @param {MouseEvent | TouchEvent} event
7917 * @returns {{ clientX: number, clientY: number }}
7918 */
7919 const getClientXY = event => {
7920 let clientX = 0,
7921 clientY = 0;
7922 if (event.type.startsWith('mouse')) {
7923 clientX = /** @type {MouseEvent} */event.clientX;
7924 clientY = /** @type {MouseEvent} */event.clientY;
7925 } else if (event.type.startsWith('touch')) {
7926 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
7927 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
7928 }
7929 return {
7930 clientX,
7931 clientY
7932 };
7933 };
7934
7935 /**
7936 * @param {SweetAlert} instance
7937 * @param {SweetAlertOptions} params
7938 */
7939 const renderPopup = (instance, params) => {
7940 const container = getContainer();
7941 const popup = getPopup();
7942 if (!container || !popup) {
7943 return;
7944 }
7945
7946 // Width
7947 // https://github.com/sweetalert2/sweetalert2/issues/2170
7948 if (params.toast) {
7949 applyNumericalStyle(container, 'width', params.width);
7950 popup.style.width = '100%';
7951 const loader = getLoader();
7952 if (loader) {
7953 popup.insertBefore(loader, getIcon());
7954 }
7955 } else {
7956 applyNumericalStyle(popup, 'width', params.width);
7957 }
7958
7959 // Padding
7960 applyNumericalStyle(popup, 'padding', params.padding);
7961
7962 // Color
7963 if (params.color) {
7964 popup.style.color = params.color;
7965 }
7966
7967 // Background
7968 if (params.background) {
7969 popup.style.background = params.background;
7970 }
7971 hide(getValidationMessage());
7972
7973 // Classes
7974 addClasses$1(popup, params);
7975 if (params.draggable && !params.toast) {
7976 addClass(popup, swalClasses.draggable);
7977 addDraggableListeners(popup);
7978 } else {
7979 removeClass(popup, swalClasses.draggable);
7980 removeDraggableListeners(popup);
7981 }
7982 };
7983
7984 /**
7985 * @param {HTMLElement} popup
7986 * @param {SweetAlertOptions} params
7987 */
7988 const addClasses$1 = (popup, params) => {
7989 const showClass = params.showClass || {};
7990 // Default Class + showClass when updating Swal.update({})
7991 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7992 if (params.toast) {
7993 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7994 addClass(popup, swalClasses.toast);
7995 } else {
7996 addClass(popup, swalClasses.modal);
7997 }
7998
7999 // Custom class
8000 applyCustomClass(popup, params, 'popup');
8001 // TODO: remove in the next major
8002 if (typeof params.customClass === 'string') {
8003 addClass(popup, params.customClass);
8004 }
8005
8006 // Icon class (#1842)
8007 if (params.icon) {
8008 addClass(popup, swalClasses[`icon-${params.icon}`]);
8009 }
8010 };
8011
8012 /**
8013 * @param {SweetAlert} instance
8014 * @param {SweetAlertOptions} params
8015 */
8016 const renderProgressSteps = (instance, params) => {
8017 const progressStepsContainer = getProgressSteps();
8018 if (!progressStepsContainer) {
8019 return;
8020 }
8021 const {
8022 progressSteps,
8023 currentProgressStep
8024 } = params;
8025 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8026 hide(progressStepsContainer);
8027 return;
8028 }
8029 show(progressStepsContainer);
8030 progressStepsContainer.textContent = '';
8031 if (currentProgressStep >= progressSteps.length) {
8032 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
8033 }
8034 progressSteps.forEach((step, index) => {
8035 const stepEl = createStepElement(step);
8036 progressStepsContainer.appendChild(stepEl);
8037 if (index === currentProgressStep) {
8038 addClass(stepEl, swalClasses['active-progress-step']);
8039 }
8040 if (index !== progressSteps.length - 1) {
8041 const lineEl = createLineElement(params);
8042 progressStepsContainer.appendChild(lineEl);
8043 }
8044 });
8045 };
8046
8047 /**
8048 * @param {string} step
8049 * @returns {HTMLLIElement}
8050 */
8051 const createStepElement = step => {
8052 const stepEl = document.createElement('li');
8053 addClass(stepEl, swalClasses['progress-step']);
8054 setInnerHtml(stepEl, step);
8055 return stepEl;
8056 };
8057
8058 /**
8059 * @param {SweetAlertOptions} params
8060 * @returns {HTMLLIElement}
8061 */
8062 const createLineElement = params => {
8063 const lineEl = document.createElement('li');
8064 addClass(lineEl, swalClasses['progress-step-line']);
8065 if (params.progressStepsDistance) {
8066 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
8067 }
8068 return lineEl;
8069 };
8070
8071 /**
8072 * @param {SweetAlert} instance
8073 * @param {SweetAlertOptions} params
8074 */
8075 const renderTitle = (instance, params) => {
8076 const title = getTitle();
8077 if (!title) {
8078 return;
8079 }
8080 showWhenInnerHtmlPresent(title);
8081 toggle(title, Boolean(params.title || params.titleText), 'block');
8082 if (params.title) {
8083 parseHtmlToContainer(params.title, title);
8084 }
8085 if (params.titleText) {
8086 title.innerText = params.titleText;
8087 }
8088
8089 // Custom class
8090 applyCustomClass(title, params, 'title');
8091 };
8092
8093 /**
8094 * @param {SweetAlert} instance
8095 * @param {SweetAlertOptions} params
8096 */
8097 const render = (instance, params) => {
8098 var _globalState$eventEmi;
8099 renderPopup(instance, params);
8100 renderContainer(instance, params);
8101 renderProgressSteps(instance, params);
8102 renderIcon(instance, params);
8103 renderImage(instance, params);
8104 renderTitle(instance, params);
8105 renderCloseButton(instance, params);
8106 renderContent(instance, params);
8107 renderActions(instance, params);
8108 renderFooter(instance, params);
8109 const popup = getPopup();
8110 if (typeof params.didRender === 'function' && popup) {
8111 params.didRender(popup);
8112 }
8113 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
8114 };
8115
8116 /*
8117 * Global function to determine if SweetAlert2 popup is shown
8118 */
8119 const isVisible = () => {
8120 return isVisible$1(getPopup());
8121 };
8122
8123 /*
8124 * Global function to click 'Confirm' button
8125 */
8126 const clickConfirm = () => {
8127 var _dom$getConfirmButton;
8128 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
8129 };
8130
8131 /*
8132 * Global function to click 'Deny' button
8133 */
8134 const clickDeny = () => {
8135 var _dom$getDenyButton;
8136 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
8137 };
8138
8139 /*
8140 * Global function to click 'Cancel' button
8141 */
8142 const clickCancel = () => {
8143 var _dom$getCancelButton;
8144 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
8145 };
8146
8147 /** @type {Record<DismissReason, DismissReason>} */
8148 const DismissReason = Object.freeze({
8149 cancel: 'cancel',
8150 backdrop: 'backdrop',
8151 close: 'close',
8152 esc: 'esc',
8153 timer: 'timer'
8154 });
8155
8156 /**
8157 * @param {GlobalState} globalState
8158 */
8159 const removeKeydownHandler = globalState => {
8160 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8161 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
8162 globalState.keydownTarget.removeEventListener('keydown', handler, {
8163 capture: globalState.keydownListenerCapture
8164 });
8165 globalState.keydownHandlerAdded = false;
8166 }
8167 };
8168
8169 /**
8170 * @param {GlobalState} globalState
8171 * @param {SweetAlertOptions} innerParams
8172 * @param {(dismiss: DismissReason) => void} dismissWith
8173 */
8174 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8175 removeKeydownHandler(globalState);
8176 if (!innerParams.toast) {
8177 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8178 const handler = e => keydownHandler(innerParams, e, dismissWith);
8179 globalState.keydownHandler = handler;
8180 const target = innerParams.keydownListenerCapture ? window : getPopup();
8181 if (target) {
8182 globalState.keydownTarget = target;
8183 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8184 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8185 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8186 capture: globalState.keydownListenerCapture
8187 });
8188 globalState.keydownHandlerAdded = true;
8189 }
8190 }
8191 };
8192
8193 /**
8194 * @param {number} index
8195 * @param {number} increment
8196 */
8197 const setFocus = (index, increment) => {
8198 var _dom$getPopup;
8199 const focusableElements = getFocusableElements();
8200 // search for visible elements and select the next possible match
8201 if (focusableElements.length) {
8202 index = index + increment;
8203
8204 // shift + tab when .swal2-popup is focused
8205 if (index === -2) {
8206 index = focusableElements.length - 1;
8207 }
8208
8209 // rollover to first item
8210 if (index === focusableElements.length) {
8211 index = 0;
8212
8213 // go to last item
8214 } else if (index === -1) {
8215 index = focusableElements.length - 1;
8216 }
8217 focusableElements[index].focus();
8218 return;
8219 }
8220 // no visible focusable elements, focus the popup
8221 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8222 };
8223 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8224 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8225
8226 /**
8227 * @param {SweetAlertOptions} innerParams
8228 * @param {KeyboardEvent} event
8229 * @param {(dismiss: DismissReason) => void} dismissWith
8230 */
8231 const keydownHandler = (innerParams, event, dismissWith) => {
8232 if (!innerParams) {
8233 return; // This instance has already been destroyed
8234 }
8235
8236 // Ignore keydown during IME composition
8237 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8238 // https://github.com/sweetalert2/sweetalert2/issues/720
8239 // https://github.com/sweetalert2/sweetalert2/issues/2406
8240 if (event.isComposing || event.keyCode === 229) {
8241 return;
8242 }
8243 if (innerParams.stopKeydownPropagation) {
8244 event.stopPropagation();
8245 }
8246
8247 // ENTER
8248 if (event.key === 'Enter') {
8249 handleEnter(event, innerParams);
8250 }
8251
8252 // TAB
8253 else if (event.key === 'Tab') {
8254 handleTab(event);
8255 }
8256
8257 // ARROWS - switch focus between buttons
8258 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8259 handleArrows(event.key);
8260 }
8261
8262 // ESC
8263 else if (event.key === 'Escape') {
8264 handleEsc(event, innerParams, dismissWith);
8265 }
8266 };
8267
8268 /**
8269 * @param {KeyboardEvent} event
8270 * @param {SweetAlertOptions} innerParams
8271 */
8272 const handleEnter = (event, innerParams) => {
8273 // https://github.com/sweetalert2/sweetalert2/issues/2386
8274 if (!callIfFunction(innerParams.allowEnterKey)) {
8275 return;
8276 }
8277 const popup = getPopup();
8278 if (!popup || !innerParams.input) {
8279 return;
8280 }
8281 const input = getInput$1(popup, innerParams.input);
8282 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8283 if (['textarea', 'file'].includes(innerParams.input)) {
8284 return; // do not submit
8285 }
8286 clickConfirm();
8287 event.preventDefault();
8288 }
8289 };
8290
8291 /**
8292 * @param {KeyboardEvent} event
8293 */
8294 const handleTab = event => {
8295 const targetElement = event.target;
8296 const focusableElements = getFocusableElements();
8297 let btnIndex = -1;
8298 for (let i = 0; i < focusableElements.length; i++) {
8299 if (targetElement === focusableElements[i]) {
8300 btnIndex = i;
8301 break;
8302 }
8303 }
8304
8305 // Cycle to the next button
8306 if (!event.shiftKey) {
8307 setFocus(btnIndex, 1);
8308 }
8309
8310 // Cycle to the prev button
8311 else {
8312 setFocus(btnIndex, -1);
8313 }
8314 event.stopPropagation();
8315 event.preventDefault();
8316 };
8317
8318 /**
8319 * @param {string} key
8320 */
8321 const handleArrows = key => {
8322 const actions = getActions();
8323 const confirmButton = getConfirmButton();
8324 const denyButton = getDenyButton();
8325 const cancelButton = getCancelButton();
8326 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8327 return;
8328 }
8329 /** @type HTMLElement[] */
8330 const buttons = [confirmButton, denyButton, cancelButton];
8331 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8332 return;
8333 }
8334 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8335 let buttonToFocus = document.activeElement;
8336 if (!buttonToFocus) {
8337 return;
8338 }
8339 for (let i = 0; i < actions.children.length; i++) {
8340 buttonToFocus = buttonToFocus[sibling];
8341 if (!buttonToFocus) {
8342 return;
8343 }
8344 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8345 break;
8346 }
8347 }
8348 if (buttonToFocus instanceof HTMLButtonElement) {
8349 buttonToFocus.focus();
8350 }
8351 };
8352
8353 /**
8354 * @param {KeyboardEvent} event
8355 * @param {SweetAlertOptions} innerParams
8356 * @param {(dismiss: DismissReason) => void} dismissWith
8357 */
8358 const handleEsc = (event, innerParams, dismissWith) => {
8359 event.preventDefault();
8360 if (callIfFunction(innerParams.allowEscapeKey)) {
8361 dismissWith(DismissReason.esc);
8362 }
8363 };
8364
8365 /**
8366 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8367 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8368 * This is the approach that Babel will probably take to implement private methods/fields
8369 * https://github.com/tc39/proposal-private-methods
8370 * https://github.com/babel/babel/pull/7555
8371 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8372 * then we can use that language feature.
8373 */
8374
8375 var privateMethods = {
8376 swalPromiseResolve: new WeakMap(),
8377 swalPromiseReject: new WeakMap()
8378 };
8379
8380 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8381 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8382 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8383 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8384
8385 const setAriaHidden = () => {
8386 const container = getContainer();
8387 const bodyChildren = Array.from(document.body.children);
8388 bodyChildren.forEach(el => {
8389 if (el.contains(container)) {
8390 return;
8391 }
8392 if (el.hasAttribute('aria-hidden')) {
8393 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8394 }
8395 el.setAttribute('aria-hidden', 'true');
8396 });
8397 };
8398 const unsetAriaHidden = () => {
8399 const bodyChildren = Array.from(document.body.children);
8400 bodyChildren.forEach(el => {
8401 if (el.hasAttribute('data-previous-aria-hidden')) {
8402 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8403 el.removeAttribute('data-previous-aria-hidden');
8404 } else {
8405 el.removeAttribute('aria-hidden');
8406 }
8407 });
8408 };
8409
8410 // @ts-ignore
8411 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8412
8413 /**
8414 * Fix iOS scrolling
8415 * http://stackoverflow.com/q/39626302
8416 */
8417 const iOSfix = () => {
8418 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8419 const offset = document.body.scrollTop;
8420 document.body.style.top = `${offset * -1}px`;
8421 addClass(document.body, swalClasses.iosfix);
8422 lockBodyScroll();
8423 }
8424 };
8425
8426 /**
8427 * https://github.com/sweetalert2/sweetalert2/issues/1246
8428 */
8429 const lockBodyScroll = () => {
8430 const container = getContainer();
8431 if (!container) {
8432 return;
8433 }
8434 /** @type {boolean} */
8435 let preventTouchMove;
8436 /**
8437 * @param {TouchEvent} event
8438 */
8439 container.ontouchstart = event => {
8440 preventTouchMove = shouldPreventTouchMove(event);
8441 };
8442 /**
8443 * @param {TouchEvent} event
8444 */
8445 container.ontouchmove = event => {
8446 if (preventTouchMove) {
8447 event.preventDefault();
8448 event.stopPropagation();
8449 }
8450 };
8451 };
8452
8453 /**
8454 * @param {TouchEvent} event
8455 * @returns {boolean}
8456 */
8457 const shouldPreventTouchMove = event => {
8458 const target = event.target;
8459 const container = getContainer();
8460 const htmlContainer = getHtmlContainer();
8461 if (!container || !htmlContainer) {
8462 return false;
8463 }
8464 if (isStylus(event) || isZoom(event)) {
8465 return false;
8466 }
8467 if (target === container) {
8468 return true;
8469 }
8470 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8471 // #2823
8472 target.tagName !== 'INPUT' &&
8473 // #1603
8474 target.tagName !== 'TEXTAREA' &&
8475 // #2266
8476 !(isScrollable(htmlContainer) &&
8477 // #1944
8478 htmlContainer.contains(target))) {
8479 return true;
8480 }
8481 return false;
8482 };
8483
8484 /**
8485 * https://github.com/sweetalert2/sweetalert2/issues/1786
8486 *
8487 * @param {TouchEvent} event
8488 * @returns {boolean}
8489 */
8490 const isStylus = event => {
8491 return Boolean(event.touches && event.touches.length &&
8492 // @ts-ignore - touchType is not a standard property
8493 event.touches[0].touchType === 'stylus');
8494 };
8495
8496 /**
8497 * https://github.com/sweetalert2/sweetalert2/issues/1891
8498 *
8499 * @param {TouchEvent} event
8500 * @returns {boolean}
8501 */
8502 const isZoom = event => {
8503 return event.touches && event.touches.length > 1;
8504 };
8505 const undoIOSfix = () => {
8506 if (hasClass(document.body, swalClasses.iosfix)) {
8507 const offset = parseInt(document.body.style.top, 10);
8508 removeClass(document.body, swalClasses.iosfix);
8509 document.body.style.top = '';
8510 document.body.scrollTop = offset * -1;
8511 }
8512 };
8513
8514 /**
8515 * Measure scrollbar width for padding body during modal show/hide
8516 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8517 *
8518 * @returns {number}
8519 */
8520 const measureScrollbar = () => {
8521 const scrollDiv = document.createElement('div');
8522 scrollDiv.className = swalClasses['scrollbar-measure'];
8523 document.body.appendChild(scrollDiv);
8524 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8525 document.body.removeChild(scrollDiv);
8526 return scrollbarWidth;
8527 };
8528
8529 /**
8530 * Remember state in cases where opening and handling a modal will fiddle with it.
8531 * @type {number | null}
8532 */
8533 let previousBodyPadding = null;
8534
8535 /**
8536 * @param {string} initialBodyOverflow
8537 */
8538 const replaceScrollbarWithPadding = initialBodyOverflow => {
8539 // for queues, do not do this more than once
8540 if (previousBodyPadding !== null) {
8541 return;
8542 }
8543 // if the body has overflow
8544 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8545 ) {
8546 // add padding so the content doesn't shift after removal of scrollbar
8547 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8548 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8549 }
8550 };
8551 const undoReplaceScrollbarWithPadding = () => {
8552 if (previousBodyPadding !== null) {
8553 document.body.style.paddingRight = `${previousBodyPadding}px`;
8554 previousBodyPadding = null;
8555 }
8556 };
8557
8558 /**
8559 * @param {SweetAlert} instance
8560 * @param {HTMLElement} container
8561 * @param {boolean} returnFocus
8562 * @param {(() => void) | undefined} didClose
8563 */
8564 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8565 if (isToast()) {
8566 triggerDidCloseAndDispose(instance, didClose);
8567 } else {
8568 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8569 removeKeydownHandler(globalState);
8570 }
8571
8572 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8573 // for some reason removing the container in Safari will scroll the document to bottom
8574 if (isSafariOrIOS) {
8575 container.setAttribute('style', 'display:none !important');
8576 container.removeAttribute('class');
8577 container.innerHTML = '';
8578 } else {
8579 container.remove();
8580 }
8581 if (isModal()) {
8582 undoReplaceScrollbarWithPadding();
8583 undoIOSfix();
8584 unsetAriaHidden();
8585 }
8586 removeBodyClasses();
8587 }
8588
8589 /**
8590 * Remove SweetAlert2 classes from body
8591 */
8592 function removeBodyClasses() {
8593 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8594 }
8595
8596 /**
8597 * Instance method to close sweetAlert
8598 *
8599 * @param {SweetAlertResult | undefined} resolveValue
8600 * @this {SweetAlert}
8601 */
8602 function close(resolveValue) {
8603 resolveValue = prepareResolveValue(resolveValue);
8604 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8605 const didClose = triggerClosePopup(this);
8606 if (this.isAwaitingPromise) {
8607 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8608 if (!resolveValue.isDismissed) {
8609 handleAwaitingPromise(this);
8610 swalPromiseResolve(resolveValue);
8611 }
8612 } else if (didClose) {
8613 // Resolve Swal promise
8614 swalPromiseResolve(resolveValue);
8615 }
8616 }
8617
8618 /**
8619 * @param {SweetAlert} instance
8620 * @returns {boolean}
8621 */
8622 const triggerClosePopup = instance => {
8623 const popup = getPopup();
8624 if (!popup) {
8625 return false;
8626 }
8627 const innerParams = privateProps.innerParams.get(instance);
8628 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8629 return false;
8630 }
8631 removeClass(popup, innerParams.showClass.popup);
8632 addClass(popup, innerParams.hideClass.popup);
8633 const backdrop = getContainer();
8634 removeClass(backdrop, innerParams.showClass.backdrop);
8635 addClass(backdrop, innerParams.hideClass.backdrop);
8636 handlePopupAnimation(instance, popup, innerParams);
8637 return true;
8638 };
8639
8640 /**
8641 * @param {Error | string} error
8642 * @this {SweetAlert}
8643 */
8644 function rejectPromise(error) {
8645 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8646 handleAwaitingPromise(this);
8647 if (rejectPromise) {
8648 // Reject Swal promise
8649 rejectPromise(error);
8650 }
8651 }
8652
8653 /**
8654 * @param {SweetAlert} instance
8655 */
8656 const handleAwaitingPromise = instance => {
8657 if (instance.isAwaitingPromise) {
8658 // @ts-ignore
8659 delete instance.isAwaitingPromise;
8660 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8661 if (!privateProps.innerParams.get(instance)) {
8662 instance._destroy();
8663 }
8664 }
8665 };
8666
8667 /**
8668 * @param {SweetAlertResult | undefined} resolveValue
8669 * @returns {SweetAlertResult}
8670 */
8671 const prepareResolveValue = resolveValue => {
8672 // When user calls Swal.close()
8673 if (typeof resolveValue === 'undefined') {
8674 return {
8675 isConfirmed: false,
8676 isDenied: false,
8677 isDismissed: true
8678 };
8679 }
8680 return Object.assign({
8681 isConfirmed: false,
8682 isDenied: false,
8683 isDismissed: false
8684 }, resolveValue);
8685 };
8686
8687 /**
8688 * @param {SweetAlert} instance
8689 * @param {HTMLElement} popup
8690 * @param {SweetAlertOptions} innerParams
8691 */
8692 const handlePopupAnimation = (instance, popup, innerParams) => {
8693 var _globalState$eventEmi;
8694 const container = getContainer();
8695 // If animation is supported, animate
8696 const animationIsSupported = hasCssAnimation(popup);
8697 if (typeof innerParams.willClose === 'function') {
8698 innerParams.willClose(popup);
8699 }
8700 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8701 if (animationIsSupported && container) {
8702 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8703 } else if (container) {
8704 // Otherwise, remove immediately
8705 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8706 }
8707 };
8708
8709 /**
8710 * @param {SweetAlert} instance
8711 * @param {HTMLElement} popup
8712 * @param {HTMLElement} container
8713 * @param {boolean} returnFocus
8714 * @param {(() => void) | undefined} didClose
8715 */
8716 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8717 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8718 /**
8719 * @param {AnimationEvent | TransitionEvent} e
8720 */
8721 const swalCloseAnimationFinished = function (e) {
8722 if (e.target === popup) {
8723 var _globalState$swalClos;
8724 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8725 delete globalState.swalCloseEventFinishedCallback;
8726 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8727 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8728 }
8729 };
8730 popup.addEventListener('animationend', swalCloseAnimationFinished);
8731 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8732 };
8733
8734 /**
8735 * @param {SweetAlert} instance
8736 * @param {(() => void) | undefined} didClose
8737 */
8738 const triggerDidCloseAndDispose = (instance, didClose) => {
8739 setTimeout(() => {
8740 var _globalState$eventEmi2;
8741 if (typeof didClose === 'function') {
8742 didClose.bind(instance.params)();
8743 }
8744 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8745 // instance might have been destroyed already
8746 if (instance._destroy) {
8747 instance._destroy();
8748 }
8749 });
8750 };
8751
8752 /**
8753 * Shows loader (spinner), this is useful with AJAX requests.
8754 * By default the loader be shown instead of the "Confirm" button.
8755 *
8756 * @param {HTMLButtonElement | null} [buttonToReplace]
8757 */
8758 const showLoading = buttonToReplace => {
8759 let popup = getPopup();
8760 if (!popup) {
8761 new Swal();
8762 }
8763 popup = getPopup();
8764 if (!popup) {
8765 return;
8766 }
8767 const loader = getLoader();
8768 if (isToast()) {
8769 hide(getIcon());
8770 } else {
8771 replaceButton(popup, buttonToReplace);
8772 }
8773 show(loader);
8774 popup.setAttribute('data-loading', 'true');
8775 popup.setAttribute('aria-busy', 'true');
8776 popup.focus();
8777 };
8778
8779 /**
8780 * @param {HTMLElement} popup
8781 * @param {HTMLButtonElement | null} [buttonToReplace]
8782 */
8783 const replaceButton = (popup, buttonToReplace) => {
8784 const actions = getActions();
8785 const loader = getLoader();
8786 if (!actions || !loader) {
8787 return;
8788 }
8789 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8790 buttonToReplace = getConfirmButton();
8791 }
8792 show(actions);
8793 if (buttonToReplace) {
8794 hide(buttonToReplace);
8795 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8796 actions.insertBefore(loader, buttonToReplace);
8797 }
8798 addClass([popup, actions], swalClasses.loading);
8799 };
8800
8801 /**
8802 * @param {SweetAlert} instance
8803 * @param {SweetAlertOptions} params
8804 */
8805 const handleInputOptionsAndValue = (instance, params) => {
8806 if (params.input === 'select' || params.input === 'radio') {
8807 handleInputOptions(instance, params);
8808 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8809 showLoading(getConfirmButton());
8810 handleInputValue(instance, params);
8811 }
8812 };
8813
8814 /**
8815 * @param {SweetAlert} instance
8816 * @param {SweetAlertOptions} innerParams
8817 * @returns {SweetAlertInputValue}
8818 */
8819 const getInputValue = (instance, innerParams) => {
8820 const input = instance.getInput();
8821 if (!input) {
8822 return null;
8823 }
8824 switch (innerParams.input) {
8825 case 'checkbox':
8826 return getCheckboxValue(input);
8827 case 'radio':
8828 return getRadioValue(input);
8829 case 'file':
8830 return getFileValue(input);
8831 default:
8832 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8833 }
8834 };
8835
8836 /**
8837 * @param {HTMLInputElement} input
8838 * @returns {number}
8839 */
8840 const getCheckboxValue = input => input.checked ? 1 : 0;
8841
8842 /**
8843 * @param {HTMLInputElement} input
8844 * @returns {string | null}
8845 */
8846 const getRadioValue = input => input.checked ? input.value : null;
8847
8848 /**
8849 * @param {HTMLInputElement} input
8850 * @returns {FileList | File | null}
8851 */
8852 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8853
8854 /**
8855 * @param {SweetAlert} instance
8856 * @param {SweetAlertOptions} params
8857 */
8858 const handleInputOptions = (instance, params) => {
8859 const popup = getPopup();
8860 if (!popup) {
8861 return;
8862 }
8863 /**
8864 * @param {*} inputOptions
8865 */
8866 const processInputOptions = inputOptions => {
8867 if (params.input === 'select') {
8868 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8869 } else if (params.input === 'radio') {
8870 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8871 }
8872 };
8873 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8874 showLoading(getConfirmButton());
8875 asPromise(params.inputOptions).then(inputOptions => {
8876 instance.hideLoading();
8877 processInputOptions(inputOptions);
8878 });
8879 } else if (typeof params.inputOptions === 'object') {
8880 processInputOptions(params.inputOptions);
8881 } else {
8882 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8883 }
8884 };
8885
8886 /**
8887 * @param {SweetAlert} instance
8888 * @param {SweetAlertOptions} params
8889 */
8890 const handleInputValue = (instance, params) => {
8891 const input = instance.getInput();
8892 if (!input) {
8893 return;
8894 }
8895 hide(input);
8896 asPromise(params.inputValue).then(inputValue => {
8897 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8898 show(input);
8899 input.focus();
8900 instance.hideLoading();
8901 }).catch(err => {
8902 error(`Error in inputValue promise: ${err}`);
8903 input.value = '';
8904 show(input);
8905 input.focus();
8906 instance.hideLoading();
8907 });
8908 };
8909
8910 /**
8911 * @param {HTMLElement} popup
8912 * @param {InputOptionFlattened[]} inputOptions
8913 * @param {SweetAlertOptions} params
8914 */
8915 function populateSelectOptions(popup, inputOptions, params) {
8916 const select = getDirectChildByClass(popup, swalClasses.select);
8917 if (!select) {
8918 return;
8919 }
8920 /**
8921 * @param {HTMLElement} parent
8922 * @param {string} optionLabel
8923 * @param {string} optionValue
8924 */
8925 const renderOption = (parent, optionLabel, optionValue) => {
8926 const option = document.createElement('option');
8927 option.value = optionValue;
8928 setInnerHtml(option, optionLabel);
8929 option.selected = isSelected(optionValue, params.inputValue);
8930 parent.appendChild(option);
8931 };
8932 inputOptions.forEach(inputOption => {
8933 const optionValue = inputOption[0];
8934 const optionLabel = inputOption[1];
8935 // <optgroup> spec:
8936 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8937 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8938 // check whether this is a <optgroup>
8939 if (Array.isArray(optionLabel)) {
8940 // if it is an array, then it is an <optgroup>
8941 const optgroup = document.createElement('optgroup');
8942 optgroup.label = optionValue;
8943 optgroup.disabled = false; // not configurable for now
8944 select.appendChild(optgroup);
8945 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8946 } else {
8947 // case of <option>
8948 renderOption(select, optionLabel, optionValue);
8949 }
8950 });
8951 select.focus();
8952 }
8953
8954 /**
8955 * @param {HTMLElement} popup
8956 * @param {InputOptionFlattened[]} inputOptions
8957 * @param {SweetAlertOptions} params
8958 */
8959 function populateRadioOptions(popup, inputOptions, params) {
8960 const radio = getDirectChildByClass(popup, swalClasses.radio);
8961 if (!radio) {
8962 return;
8963 }
8964 inputOptions.forEach(inputOption => {
8965 const radioValue = inputOption[0];
8966 const radioLabel = inputOption[1];
8967 const radioInput = document.createElement('input');
8968 const radioLabelElement = document.createElement('label');
8969 radioInput.type = 'radio';
8970 radioInput.name = swalClasses.radio;
8971 radioInput.value = radioValue;
8972 if (isSelected(radioValue, params.inputValue)) {
8973 radioInput.checked = true;
8974 }
8975 const label = document.createElement('span');
8976 setInnerHtml(label, radioLabel);
8977 label.className = swalClasses.label;
8978 radioLabelElement.appendChild(radioInput);
8979 radioLabelElement.appendChild(label);
8980 radio.appendChild(radioLabelElement);
8981 });
8982 const radios = radio.querySelectorAll('input');
8983 if (radios.length) {
8984 radios[0].focus();
8985 }
8986 }
8987
8988 /**
8989 * Converts `inputOptions` into an array of `[value, label]`s
8990 *
8991 * @param {*} inputOptions
8992 * @typedef {string[]} InputOptionFlattened
8993 * @returns {InputOptionFlattened[]}
8994 */
8995 const formatInputOptions = inputOptions => {
8996 /** @type {InputOptionFlattened[]} */
8997 const result = [];
8998 if (inputOptions instanceof Map) {
8999 inputOptions.forEach((value, key) => {
9000 let valueFormatted = value;
9001 if (typeof valueFormatted === 'object') {
9002 // case of <optgroup>
9003 valueFormatted = formatInputOptions(valueFormatted);
9004 }
9005 result.push([key, valueFormatted]);
9006 });
9007 } else {
9008 Object.keys(inputOptions).forEach(key => {
9009 let valueFormatted = inputOptions[key];
9010 if (typeof valueFormatted === 'object') {
9011 // case of <optgroup>
9012 valueFormatted = formatInputOptions(valueFormatted);
9013 }
9014 result.push([key, valueFormatted]);
9015 });
9016 }
9017 return result;
9018 };
9019
9020 /**
9021 * @param {string} optionValue
9022 * @param {SweetAlertInputValue} inputValue
9023 * @returns {boolean}
9024 */
9025 const isSelected = (optionValue, inputValue) => {
9026 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
9027 };
9028
9029 /**
9030 * @param {SweetAlert} instance
9031 */
9032 const handleConfirmButtonClick = instance => {
9033 const innerParams = privateProps.innerParams.get(instance);
9034 instance.disableButtons();
9035 if (innerParams.input) {
9036 handleConfirmOrDenyWithInput(instance, 'confirm');
9037 } else {
9038 confirm(instance, true);
9039 }
9040 };
9041
9042 /**
9043 * @param {SweetAlert} instance
9044 */
9045 const handleDenyButtonClick = instance => {
9046 const innerParams = privateProps.innerParams.get(instance);
9047 instance.disableButtons();
9048 if (innerParams.returnInputValueOnDeny) {
9049 handleConfirmOrDenyWithInput(instance, 'deny');
9050 } else {
9051 deny(instance, false);
9052 }
9053 };
9054
9055 /**
9056 * @param {SweetAlert} instance
9057 * @param {(dismiss: DismissReason) => void} dismissWith
9058 */
9059 const handleCancelButtonClick = (instance, dismissWith) => {
9060 instance.disableButtons();
9061 dismissWith(DismissReason.cancel);
9062 };
9063
9064 /**
9065 * @param {SweetAlert} instance
9066 * @param {'confirm' | 'deny'} type
9067 */
9068 const handleConfirmOrDenyWithInput = (instance, type) => {
9069 const innerParams = privateProps.innerParams.get(instance);
9070 if (!innerParams.input) {
9071 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
9072 return;
9073 }
9074 const input = instance.getInput();
9075 const inputValue = getInputValue(instance, innerParams);
9076 if (innerParams.inputValidator) {
9077 handleInputValidator(instance, inputValue, type);
9078 } else if (input && !input.checkValidity()) {
9079 instance.enableButtons();
9080 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
9081 } else if (type === 'deny') {
9082 deny(instance, inputValue);
9083 } else {
9084 confirm(instance, inputValue);
9085 }
9086 };
9087
9088 /**
9089 * @param {SweetAlert} instance
9090 * @param {SweetAlertInputValue} inputValue
9091 * @param {'confirm' | 'deny'} type
9092 */
9093 const handleInputValidator = (instance, inputValue, type) => {
9094 const innerParams = privateProps.innerParams.get(instance);
9095 instance.disableInput();
9096 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
9097 validationPromise.then(validationMessage => {
9098 instance.enableButtons();
9099 instance.enableInput();
9100 if (validationMessage) {
9101 instance.showValidationMessage(validationMessage);
9102 } else if (type === 'deny') {
9103 deny(instance, inputValue);
9104 } else {
9105 confirm(instance, inputValue);
9106 }
9107 });
9108 };
9109
9110 /**
9111 * @param {SweetAlert} instance
9112 * @param {*} value
9113 */
9114 const deny = (instance, value) => {
9115 const innerParams = privateProps.innerParams.get(instance);
9116 if (innerParams.showLoaderOnDeny) {
9117 showLoading(getDenyButton());
9118 }
9119 if (innerParams.preDeny) {
9120 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
9121 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
9122 preDenyPromise.then(preDenyValue => {
9123 if (preDenyValue === false) {
9124 instance.hideLoading();
9125 handleAwaitingPromise(instance);
9126 } else {
9127 instance.close(/** @type SweetAlertResult */{
9128 isDenied: true,
9129 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
9130 });
9131 }
9132 }).catch(error => rejectWith(instance, error));
9133 } else {
9134 instance.close(/** @type SweetAlertResult */{
9135 isDenied: true,
9136 value
9137 });
9138 }
9139 };
9140
9141 /**
9142 * @param {SweetAlert} instance
9143 * @param {*} value
9144 */
9145 const succeedWith = (instance, value) => {
9146 instance.close(/** @type SweetAlertResult */{
9147 isConfirmed: true,
9148 value
9149 });
9150 };
9151
9152 /**
9153 *
9154 * @param {SweetAlert} instance
9155 * @param {string} error
9156 */
9157 const rejectWith = (instance, error) => {
9158 instance.rejectPromise(error);
9159 };
9160
9161 /**
9162 *
9163 * @param {SweetAlert} instance
9164 * @param {*} value
9165 */
9166 const confirm = (instance, value) => {
9167 const innerParams = privateProps.innerParams.get(instance);
9168 if (innerParams.showLoaderOnConfirm) {
9169 showLoading();
9170 }
9171 if (innerParams.preConfirm) {
9172 instance.resetValidationMessage();
9173 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
9174 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9175 preConfirmPromise.then(preConfirmValue => {
9176 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9177 instance.hideLoading();
9178 handleAwaitingPromise(instance);
9179 } else {
9180 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9181 }
9182 }).catch(error => rejectWith(instance, error));
9183 } else {
9184 succeedWith(instance, value);
9185 }
9186 };
9187
9188 /**
9189 * Hides loader and shows back the button which was hidden by .showLoading()
9190 * @this {SweetAlert}
9191 */
9192 function hideLoading() {
9193 // do nothing if popup is closed
9194 const innerParams = privateProps.innerParams.get(this);
9195 if (!innerParams) {
9196 return;
9197 }
9198 const domCache = privateProps.domCache.get(this);
9199 hide(domCache.loader);
9200 if (isToast()) {
9201 if (innerParams.icon) {
9202 show(getIcon());
9203 }
9204 } else {
9205 showRelatedButton(domCache);
9206 }
9207 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9208 domCache.popup.removeAttribute('aria-busy');
9209 domCache.popup.removeAttribute('data-loading');
9210 domCache.confirmButton.disabled = false;
9211 domCache.denyButton.disabled = false;
9212 domCache.cancelButton.disabled = false;
9213 }
9214
9215 /**
9216 * @param {DomCache} domCache
9217 */
9218 const showRelatedButton = domCache => {
9219 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9220 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9221 if (buttonToReplace.length) {
9222 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9223 } else if (allButtonsAreHidden()) {
9224 hide(domCache.actions);
9225 }
9226 };
9227
9228 /**
9229 * Gets the input DOM node, this method works with input parameter.
9230 *
9231 * @returns {HTMLInputElement | null}
9232 * @this {SweetAlert}
9233 */
9234 function getInput() {
9235 const innerParams = privateProps.innerParams.get(this);
9236 const domCache = privateProps.domCache.get(this);
9237 if (!domCache) {
9238 return null;
9239 }
9240 return getInput$1(domCache.popup, innerParams.input);
9241 }
9242
9243 /**
9244 * @param {SweetAlert} instance
9245 * @param {string[]} buttons
9246 * @param {boolean} disabled
9247 */
9248 function setButtonsDisabled(instance, buttons, disabled) {
9249 const domCache = privateProps.domCache.get(instance);
9250 buttons.forEach(button => {
9251 domCache[button].disabled = disabled;
9252 });
9253 }
9254
9255 /**
9256 * @param {HTMLInputElement | null} input
9257 * @param {boolean} disabled
9258 */
9259 function setInputDisabled(input, disabled) {
9260 const popup = getPopup();
9261 if (!popup || !input) {
9262 return;
9263 }
9264 if (input.type === 'radio') {
9265 /** @type {NodeListOf<HTMLInputElement>} */
9266 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9267 for (let i = 0; i < radios.length; i++) {
9268 radios[i].disabled = disabled;
9269 }
9270 } else {
9271 input.disabled = disabled;
9272 }
9273 }
9274
9275 /**
9276 * Enable all the buttons
9277 * @this {SweetAlert}
9278 */
9279 function enableButtons() {
9280 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9281 }
9282
9283 /**
9284 * Disable all the buttons
9285 * @this {SweetAlert}
9286 */
9287 function disableButtons() {
9288 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9289 }
9290
9291 /**
9292 * Enable the input field
9293 * @this {SweetAlert}
9294 */
9295 function enableInput() {
9296 setInputDisabled(this.getInput(), false);
9297 }
9298
9299 /**
9300 * Disable the input field
9301 * @this {SweetAlert}
9302 */
9303 function disableInput() {
9304 setInputDisabled(this.getInput(), true);
9305 }
9306
9307 /**
9308 * Show block with validation message
9309 *
9310 * @param {string} error
9311 * @this {SweetAlert}
9312 */
9313 function showValidationMessage(error) {
9314 const domCache = privateProps.domCache.get(this);
9315 const params = privateProps.innerParams.get(this);
9316 setInnerHtml(domCache.validationMessage, error);
9317 domCache.validationMessage.className = swalClasses['validation-message'];
9318 if (params.customClass && params.customClass.validationMessage) {
9319 addClass(domCache.validationMessage, params.customClass.validationMessage);
9320 }
9321 show(domCache.validationMessage);
9322 const input = this.getInput();
9323 if (input) {
9324 input.setAttribute('aria-invalid', 'true');
9325 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9326 focusInput(input);
9327 addClass(input, swalClasses.inputerror);
9328 }
9329 }
9330
9331 /**
9332 * Hide block with validation message
9333 *
9334 * @this {SweetAlert}
9335 */
9336 function resetValidationMessage() {
9337 const domCache = privateProps.domCache.get(this);
9338 if (domCache.validationMessage) {
9339 hide(domCache.validationMessage);
9340 }
9341 const input = this.getInput();
9342 if (input) {
9343 input.removeAttribute('aria-invalid');
9344 input.removeAttribute('aria-describedby');
9345 removeClass(input, swalClasses.inputerror);
9346 }
9347 }
9348
9349 const defaultParams = {
9350 title: '',
9351 titleText: '',
9352 text: '',
9353 html: '',
9354 footer: '',
9355 icon: undefined,
9356 iconColor: undefined,
9357 iconHtml: undefined,
9358 template: undefined,
9359 toast: false,
9360 draggable: false,
9361 animation: true,
9362 theme: 'light',
9363 showClass: {
9364 popup: 'swal2-show',
9365 backdrop: 'swal2-backdrop-show',
9366 icon: 'swal2-icon-show'
9367 },
9368 hideClass: {
9369 popup: 'swal2-hide',
9370 backdrop: 'swal2-backdrop-hide',
9371 icon: 'swal2-icon-hide'
9372 },
9373 customClass: {},
9374 target: 'body',
9375 color: undefined,
9376 backdrop: true,
9377 heightAuto: true,
9378 allowOutsideClick: true,
9379 allowEscapeKey: true,
9380 allowEnterKey: true,
9381 stopKeydownPropagation: true,
9382 keydownListenerCapture: false,
9383 showConfirmButton: true,
9384 showDenyButton: false,
9385 showCancelButton: false,
9386 preConfirm: undefined,
9387 preDeny: undefined,
9388 confirmButtonText: 'OK',
9389 confirmButtonAriaLabel: '',
9390 confirmButtonColor: undefined,
9391 denyButtonText: 'No',
9392 denyButtonAriaLabel: '',
9393 denyButtonColor: undefined,
9394 cancelButtonText: 'Cancel',
9395 cancelButtonAriaLabel: '',
9396 cancelButtonColor: undefined,
9397 buttonsStyling: true,
9398 reverseButtons: false,
9399 focusConfirm: true,
9400 focusDeny: false,
9401 focusCancel: false,
9402 returnFocus: true,
9403 showCloseButton: false,
9404 closeButtonHtml: '&times;',
9405 closeButtonAriaLabel: 'Close this dialog',
9406 loaderHtml: '',
9407 showLoaderOnConfirm: false,
9408 showLoaderOnDeny: false,
9409 imageUrl: undefined,
9410 imageWidth: undefined,
9411 imageHeight: undefined,
9412 imageAlt: '',
9413 timer: undefined,
9414 timerProgressBar: false,
9415 width: undefined,
9416 padding: undefined,
9417 background: undefined,
9418 input: undefined,
9419 inputPlaceholder: '',
9420 inputLabel: '',
9421 inputValue: '',
9422 inputOptions: {},
9423 inputAutoFocus: true,
9424 inputAutoTrim: true,
9425 inputAttributes: {},
9426 inputValidator: undefined,
9427 returnInputValueOnDeny: false,
9428 validationMessage: undefined,
9429 grow: false,
9430 position: 'center',
9431 progressSteps: [],
9432 currentProgressStep: undefined,
9433 progressStepsDistance: undefined,
9434 willOpen: undefined,
9435 didOpen: undefined,
9436 didRender: undefined,
9437 willClose: undefined,
9438 didClose: undefined,
9439 didDestroy: undefined,
9440 scrollbarPadding: true,
9441 topLayer: false
9442 };
9443 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'];
9444
9445 /** @type {Record<string, string | undefined>} */
9446 const deprecatedParams = {
9447 allowEnterKey: undefined
9448 };
9449 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9450
9451 /**
9452 * Is valid parameter
9453 *
9454 * @param {string} paramName
9455 * @returns {boolean}
9456 */
9457 const isValidParameter = paramName => {
9458 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9459 };
9460
9461 /**
9462 * Is valid parameter for Swal.update() method
9463 *
9464 * @param {string} paramName
9465 * @returns {boolean}
9466 */
9467 const isUpdatableParameter = paramName => {
9468 return updatableParams.indexOf(paramName) !== -1;
9469 };
9470
9471 /**
9472 * Is deprecated parameter
9473 *
9474 * @param {string} paramName
9475 * @returns {string | undefined}
9476 */
9477 const isDeprecatedParameter = paramName => {
9478 return deprecatedParams[paramName];
9479 };
9480
9481 /**
9482 * @param {string} param
9483 */
9484 const checkIfParamIsValid = param => {
9485 if (!isValidParameter(param)) {
9486 warn(`Unknown parameter "${param}"`);
9487 }
9488 };
9489
9490 /**
9491 * @param {string} param
9492 */
9493 const checkIfToastParamIsValid = param => {
9494 if (toastIncompatibleParams.includes(param)) {
9495 warn(`The parameter "${param}" is incompatible with toasts`);
9496 }
9497 };
9498
9499 /**
9500 * @param {string} param
9501 */
9502 const checkIfParamIsDeprecated = param => {
9503 const isDeprecated = isDeprecatedParameter(param);
9504 if (isDeprecated) {
9505 warnAboutDeprecation(param, isDeprecated);
9506 }
9507 };
9508
9509 /**
9510 * Show relevant warnings for given params
9511 *
9512 * @param {SweetAlertOptions} params
9513 */
9514 const showWarningsForParams = params => {
9515 if (params.backdrop === false && params.allowOutsideClick) {
9516 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9517 }
9518 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)) {
9519 warn(`Invalid theme "${params.theme}"`);
9520 }
9521 for (const param in params) {
9522 checkIfParamIsValid(param);
9523 if (params.toast) {
9524 checkIfToastParamIsValid(param);
9525 }
9526 checkIfParamIsDeprecated(param);
9527 }
9528 };
9529
9530 /**
9531 * Updates popup parameters.
9532 *
9533 * @this {any}
9534 * @param {SweetAlertOptions} params
9535 */
9536 function update(params) {
9537 const container = getContainer();
9538 const popup = getPopup();
9539 const innerParams = privateProps.innerParams.get(this);
9540 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9541 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.`);
9542 return;
9543 }
9544 const validUpdatableParams = filterValidParams(params);
9545 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9546 showWarningsForParams(updatedParams);
9547 if (container) {
9548 container.dataset['swal2Theme'] = updatedParams.theme;
9549 }
9550 render(this, updatedParams);
9551 privateProps.innerParams.set(this, updatedParams);
9552 Object.defineProperties(this, {
9553 params: {
9554 value: Object.assign({}, this.params, params),
9555 writable: false,
9556 enumerable: true
9557 }
9558 });
9559 }
9560
9561 /**
9562 * @param {SweetAlertOptions} params
9563 * @returns {SweetAlertOptions}
9564 */
9565 const filterValidParams = params => {
9566 /** @type {Record<string, any>} */
9567 const validUpdatableParams = {};
9568 Object.keys(params).forEach(param => {
9569 if (isUpdatableParameter(param)) {
9570 const typedParams = /** @type {Record<string, any>} */params;
9571 validUpdatableParams[param] = typedParams[param];
9572 } else {
9573 warn(`Invalid parameter to update: ${param}`);
9574 }
9575 });
9576 return validUpdatableParams;
9577 };
9578
9579 /**
9580 * Dispose the current SweetAlert2 instance
9581 * @this {SweetAlert}
9582 */
9583 function _destroy() {
9584 var _globalState$eventEmi;
9585 const domCache = privateProps.domCache.get(this);
9586 const innerParams = privateProps.innerParams.get(this);
9587 if (!innerParams) {
9588 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9589 return; // This instance has already been destroyed
9590 }
9591
9592 // Check if there is another Swal closing
9593 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9594 globalState.swalCloseEventFinishedCallback();
9595 delete globalState.swalCloseEventFinishedCallback;
9596 }
9597 if (typeof innerParams.didDestroy === 'function') {
9598 innerParams.didDestroy();
9599 }
9600 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9601 disposeSwal(this);
9602 }
9603
9604 /**
9605 * @param {SweetAlert} instance
9606 */
9607 const disposeSwal = instance => {
9608 disposeWeakMaps(instance);
9609 // Unset this.params so GC will dispose it (#1569)
9610 // @ts-ignore
9611 delete instance.params;
9612 // Unset globalState props so GC will dispose globalState (#1569)
9613 delete globalState.keydownHandler;
9614 delete globalState.keydownTarget;
9615 // Unset currentInstance
9616 delete globalState.currentInstance;
9617 };
9618
9619 /**
9620 * @param {SweetAlert} instance
9621 */
9622 const disposeWeakMaps = instance => {
9623 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9624 if (instance.isAwaitingPromise) {
9625 unsetWeakMaps(privateProps, instance);
9626 instance.isAwaitingPromise = true;
9627 } else {
9628 unsetWeakMaps(privateMethods, instance);
9629 unsetWeakMaps(privateProps, instance);
9630
9631 // @ts-ignore
9632 delete instance.isAwaitingPromise;
9633 // Unset instance methods
9634 // @ts-ignore
9635 delete instance.disableButtons;
9636 // @ts-ignore
9637 delete instance.enableButtons;
9638 // @ts-ignore
9639 delete instance.getInput;
9640 // @ts-ignore
9641 delete instance.disableInput;
9642 // @ts-ignore
9643 delete instance.enableInput;
9644 // @ts-ignore
9645 delete instance.hideLoading;
9646 // @ts-ignore
9647 delete instance.disableLoading;
9648 // @ts-ignore
9649 delete instance.showValidationMessage;
9650 // @ts-ignore
9651 delete instance.resetValidationMessage;
9652 // @ts-ignore
9653 delete instance.close;
9654 // @ts-ignore
9655 delete instance.closePopup;
9656 // @ts-ignore
9657 delete instance.closeModal;
9658 // @ts-ignore
9659 delete instance.closeToast;
9660 // @ts-ignore
9661 delete instance.rejectPromise;
9662 // @ts-ignore
9663 delete instance.update;
9664 // @ts-ignore
9665 delete instance._destroy;
9666 }
9667 };
9668
9669 /**
9670 * @param {Record<string, WeakMap<any, any>>} obj
9671 * @param {SweetAlert} instance
9672 */
9673 const unsetWeakMaps = (obj, instance) => {
9674 for (const i in obj) {
9675 obj[i].delete(instance);
9676 }
9677 };
9678
9679 var instanceMethods = /*#__PURE__*/Object.freeze({
9680 __proto__: null,
9681 _destroy: _destroy,
9682 close: close,
9683 closeModal: close,
9684 closePopup: close,
9685 closeToast: close,
9686 disableButtons: disableButtons,
9687 disableInput: disableInput,
9688 disableLoading: hideLoading,
9689 enableButtons: enableButtons,
9690 enableInput: enableInput,
9691 getInput: getInput,
9692 handleAwaitingPromise: handleAwaitingPromise,
9693 hideLoading: hideLoading,
9694 rejectPromise: rejectPromise,
9695 resetValidationMessage: resetValidationMessage,
9696 showValidationMessage: showValidationMessage,
9697 update: update
9698 });
9699
9700 /**
9701 * @param {SweetAlertOptions} innerParams
9702 * @param {DomCache} domCache
9703 * @param {(dismiss: DismissReason) => void} dismissWith
9704 */
9705 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9706 if (innerParams.toast) {
9707 handleToastClick(innerParams, domCache, dismissWith);
9708 } else {
9709 // Ignore click events that had mousedown on the popup but mouseup on the container
9710 // This can happen when the user drags a slider
9711 handleModalMousedown(domCache);
9712
9713 // Ignore click events that had mousedown on the container but mouseup on the popup
9714 handleContainerMousedown(domCache);
9715 handleModalClick(innerParams, domCache, dismissWith);
9716 }
9717 };
9718
9719 /**
9720 * @param {SweetAlertOptions} innerParams
9721 * @param {DomCache} domCache
9722 * @param {(dismiss: DismissReason) => void} dismissWith
9723 */
9724 const handleToastClick = (innerParams, domCache, dismissWith) => {
9725 // Closing toast by internal click
9726 domCache.popup.onclick = () => {
9727 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9728 return;
9729 }
9730 dismissWith(DismissReason.close);
9731 };
9732 };
9733
9734 /**
9735 * @param {SweetAlertOptions} innerParams
9736 * @returns {boolean}
9737 */
9738 const isAnyButtonShown = innerParams => {
9739 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9740 };
9741 let ignoreOutsideClick = false;
9742
9743 /**
9744 * @param {DomCache} domCache
9745 */
9746 const handleModalMousedown = domCache => {
9747 domCache.popup.onmousedown = () => {
9748 domCache.container.onmouseup = function (e) {
9749 domCache.container.onmouseup = () => {};
9750 // We only check if the mouseup target is the container because usually it doesn't
9751 // have any other direct children aside of the popup
9752 if (e.target === domCache.container) {
9753 ignoreOutsideClick = true;
9754 }
9755 };
9756 };
9757 };
9758
9759 /**
9760 * @param {DomCache} domCache
9761 */
9762 const handleContainerMousedown = domCache => {
9763 domCache.container.onmousedown = e => {
9764 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9765 if (e.target === domCache.container) {
9766 e.preventDefault();
9767 }
9768 domCache.popup.onmouseup = function (e) {
9769 domCache.popup.onmouseup = () => {};
9770 // We also need to check if the mouseup target is a child of the popup
9771 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9772 ignoreOutsideClick = true;
9773 }
9774 };
9775 };
9776 };
9777
9778 /**
9779 * @param {SweetAlertOptions} innerParams
9780 * @param {DomCache} domCache
9781 * @param {(dismiss: DismissReason) => void} dismissWith
9782 */
9783 const handleModalClick = (innerParams, domCache, dismissWith) => {
9784 domCache.container.onclick = e => {
9785 if (ignoreOutsideClick) {
9786 ignoreOutsideClick = false;
9787 return;
9788 }
9789 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9790 dismissWith(DismissReason.backdrop);
9791 }
9792 };
9793 };
9794
9795 /**
9796 * @param {any} elem
9797 * @returns {boolean}
9798 */
9799 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
9800
9801 /**
9802 * @param {any} elem
9803 * @returns {boolean}
9804 */
9805 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9806
9807 /**
9808 * @param {any[]} args
9809 * @returns {SweetAlertOptions}
9810 */
9811 const argsToParams = args => {
9812 /** @type {Record<string, any>} */
9813 const params = {};
9814 if (typeof args[0] === 'object' && !isElement(args[0])) {
9815 Object.assign(params, args[0]);
9816 } else {
9817 ['title', 'html', 'icon'].forEach((name, index) => {
9818 const arg = args[index];
9819 if (typeof arg === 'string' || isElement(arg)) {
9820 params[name] = arg;
9821 } else if (arg !== undefined) {
9822 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9823 }
9824 });
9825 }
9826 return params;
9827 };
9828
9829 /**
9830 * Main method to create a new SweetAlert2 popup
9831 *
9832 * @this {new (...args: any[]) => any}
9833 * @param {...SweetAlertOptions} args
9834 * @returns {Promise<SweetAlertResult>}
9835 */
9836 function fire(...args) {
9837 return new this(...args);
9838 }
9839
9840 /**
9841 * Returns an extended version of `Swal` containing `params` as defaults.
9842 * Useful for reusing Swal configuration.
9843 *
9844 * For example:
9845 *
9846 * Before:
9847 * const textPromptOptions = { input: 'text', showCancelButton: true }
9848 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9849 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9850 *
9851 * After:
9852 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9853 * const {value: firstName} = await TextPrompt('What is your first name?')
9854 * const {value: lastName} = await TextPrompt('What is your last name?')
9855 *
9856 * @param {SweetAlertOptions} mixinParams
9857 * @returns {SweetAlert}
9858 * @this {typeof import('../SweetAlert.js').SweetAlert}
9859 */
9860 function mixin(mixinParams) {
9861 // @ts-ignore: 'this' refers to the SweetAlert constructor
9862 class MixinSwal extends this {
9863 /**
9864 * @param {any} params
9865 * @param {any} priorityMixinParams
9866 */
9867 _main(params, priorityMixinParams) {
9868 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9869 }
9870 }
9871 // @ts-ignore
9872 return MixinSwal;
9873 }
9874
9875 /**
9876 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9877 * Otherwise, returns undefined.
9878 *
9879 * @returns {number | undefined}
9880 */
9881 const getTimerLeft = () => {
9882 return globalState.timeout && globalState.timeout.getTimerLeft();
9883 };
9884
9885 /**
9886 * Stop timer. Returns number of milliseconds of timer remained.
9887 * If `timer` parameter isn't set, returns undefined.
9888 *
9889 * @returns {number | undefined}
9890 */
9891 const stopTimer = () => {
9892 if (globalState.timeout) {
9893 stopTimerProgressBar();
9894 return globalState.timeout.stop();
9895 }
9896 };
9897
9898 /**
9899 * Resume timer. Returns number of milliseconds of timer remained.
9900 * If `timer` parameter isn't set, returns undefined.
9901 *
9902 * @returns {number | undefined}
9903 */
9904 const resumeTimer = () => {
9905 if (globalState.timeout) {
9906 const remaining = globalState.timeout.start();
9907 animateTimerProgressBar(remaining);
9908 return remaining;
9909 }
9910 };
9911
9912 /**
9913 * Resume timer. Returns number of milliseconds of timer remained.
9914 * If `timer` parameter isn't set, returns undefined.
9915 *
9916 * @returns {number | undefined}
9917 */
9918 const toggleTimer = () => {
9919 const timer = globalState.timeout;
9920 return timer && (timer.running ? stopTimer() : resumeTimer());
9921 };
9922
9923 /**
9924 * Increase timer. Returns number of milliseconds of an updated timer.
9925 * If `timer` parameter isn't set, returns undefined.
9926 *
9927 * @param {number} ms
9928 * @returns {number | undefined}
9929 */
9930 const increaseTimer = ms => {
9931 if (globalState.timeout) {
9932 const remaining = globalState.timeout.increase(ms);
9933 animateTimerProgressBar(remaining, true);
9934 return remaining;
9935 }
9936 };
9937
9938 /**
9939 * Check if timer is running. Returns true if timer is running
9940 * or false if timer is paused or stopped.
9941 * If `timer` parameter isn't set, returns undefined
9942 *
9943 * @returns {boolean}
9944 */
9945 const isTimerRunning = () => {
9946 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9947 };
9948
9949 let bodyClickListenerAdded = false;
9950 /** @type {Record<string, any>} */
9951 const clickHandlers = {};
9952
9953 /**
9954 * @this {any}
9955 * @param {string} attr
9956 */
9957 function bindClickHandler(attr = 'data-swal-template') {
9958 clickHandlers[attr] = this;
9959 if (!bodyClickListenerAdded) {
9960 document.body.addEventListener('click', bodyClickListener);
9961 bodyClickListenerAdded = true;
9962 }
9963 }
9964
9965 /**
9966 * @param {MouseEvent} event
9967 */
9968 const bodyClickListener = event => {
9969 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9970 for (const attr in clickHandlers) {
9971 const template = el.getAttribute && el.getAttribute(attr);
9972 if (template) {
9973 clickHandlers[attr].fire({
9974 template
9975 });
9976 return;
9977 }
9978 }
9979 }
9980 };
9981
9982 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9983
9984 class EventEmitter {
9985 constructor() {
9986 /** @type {Events} */
9987 this.events = {};
9988 }
9989
9990 /**
9991 * @param {string} eventName
9992 * @returns {EventHandlers}
9993 */
9994 _getHandlersByEventName(eventName) {
9995 if (typeof this.events[eventName] === 'undefined') {
9996 // not Set because we need to keep the FIFO order
9997 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9998 this.events[eventName] = [];
9999 }
10000 return this.events[eventName];
10001 }
10002
10003 /**
10004 * @param {string} eventName
10005 * @param {EventHandler} eventHandler
10006 */
10007 on(eventName, eventHandler) {
10008 const currentHandlers = this._getHandlersByEventName(eventName);
10009 if (!currentHandlers.includes(eventHandler)) {
10010 currentHandlers.push(eventHandler);
10011 }
10012 }
10013
10014 /**
10015 * @param {string} eventName
10016 * @param {EventHandler} eventHandler
10017 */
10018 once(eventName, eventHandler) {
10019 /**
10020 * @param {...any} args
10021 */
10022 const onceFn = (...args) => {
10023 this.removeListener(eventName, onceFn);
10024 // @ts-ignore
10025 eventHandler.apply(this, args);
10026 };
10027 this.on(eventName, onceFn);
10028 }
10029
10030 /**
10031 * @param {string} eventName
10032 * @param {...any} args
10033 */
10034 emit(eventName, ...args) {
10035 this._getHandlersByEventName(eventName).forEach(
10036 /**
10037 * @param {EventHandler} eventHandler
10038 */
10039 eventHandler => {
10040 try {
10041 // @ts-ignore
10042 eventHandler.apply(this, args);
10043 } catch (error) {
10044 console.error(error);
10045 }
10046 });
10047 }
10048
10049 /**
10050 * @param {string} eventName
10051 * @param {EventHandler} eventHandler
10052 */
10053 removeListener(eventName, eventHandler) {
10054 const currentHandlers = this._getHandlersByEventName(eventName);
10055 const index = currentHandlers.indexOf(eventHandler);
10056 if (index > -1) {
10057 currentHandlers.splice(index, 1);
10058 }
10059 }
10060
10061 /**
10062 * @param {string} eventName
10063 */
10064 removeAllListeners(eventName) {
10065 if (this.events[eventName] !== undefined) {
10066 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
10067 this.events[eventName].length = 0;
10068 }
10069 }
10070 reset() {
10071 this.events = {};
10072 }
10073 }
10074
10075 globalState.eventEmitter = new EventEmitter();
10076
10077 /**
10078 * @param {string} eventName
10079 * @param {EventHandler} eventHandler
10080 */
10081 const on = (eventName, eventHandler) => {
10082 if (globalState.eventEmitter) {
10083 globalState.eventEmitter.on(eventName, eventHandler);
10084 }
10085 };
10086
10087 /**
10088 * @param {string} eventName
10089 * @param {EventHandler} eventHandler
10090 */
10091 const once = (eventName, eventHandler) => {
10092 if (globalState.eventEmitter) {
10093 globalState.eventEmitter.once(eventName, eventHandler);
10094 }
10095 };
10096
10097 /**
10098 * @param {string} [eventName]
10099 * @param {EventHandler} [eventHandler]
10100 */
10101 const off = (eventName, eventHandler) => {
10102 if (!globalState.eventEmitter) {
10103 return;
10104 }
10105
10106 // Remove all handlers for all events
10107 if (!eventName) {
10108 globalState.eventEmitter.reset();
10109 return;
10110 }
10111 if (eventHandler) {
10112 // Remove a specific handler
10113 globalState.eventEmitter.removeListener(eventName, eventHandler);
10114 } else {
10115 // Remove all handlers for a specific event
10116 globalState.eventEmitter.removeAllListeners(eventName);
10117 }
10118 };
10119
10120 var staticMethods = /*#__PURE__*/Object.freeze({
10121 __proto__: null,
10122 argsToParams: argsToParams,
10123 bindClickHandler: bindClickHandler,
10124 clickCancel: clickCancel,
10125 clickConfirm: clickConfirm,
10126 clickDeny: clickDeny,
10127 enableLoading: showLoading,
10128 fire: fire,
10129 getActions: getActions,
10130 getCancelButton: getCancelButton,
10131 getCloseButton: getCloseButton,
10132 getConfirmButton: getConfirmButton,
10133 getContainer: getContainer,
10134 getDenyButton: getDenyButton,
10135 getFocusableElements: getFocusableElements,
10136 getFooter: getFooter,
10137 getHtmlContainer: getHtmlContainer,
10138 getIcon: getIcon,
10139 getIconContent: getIconContent,
10140 getImage: getImage,
10141 getInputLabel: getInputLabel,
10142 getLoader: getLoader,
10143 getPopup: getPopup,
10144 getProgressSteps: getProgressSteps,
10145 getTimerLeft: getTimerLeft,
10146 getTimerProgressBar: getTimerProgressBar,
10147 getTitle: getTitle,
10148 getValidationMessage: getValidationMessage,
10149 increaseTimer: increaseTimer,
10150 isDeprecatedParameter: isDeprecatedParameter,
10151 isLoading: isLoading,
10152 isTimerRunning: isTimerRunning,
10153 isUpdatableParameter: isUpdatableParameter,
10154 isValidParameter: isValidParameter,
10155 isVisible: isVisible,
10156 mixin: mixin,
10157 off: off,
10158 on: on,
10159 once: once,
10160 resumeTimer: resumeTimer,
10161 showLoading: showLoading,
10162 stopTimer: stopTimer,
10163 toggleTimer: toggleTimer
10164 });
10165
10166 class Timer {
10167 /**
10168 * @param {() => void} callback
10169 * @param {number} delay
10170 */
10171 constructor(callback, delay) {
10172 this.callback = callback;
10173 this.remaining = delay;
10174 this.running = false;
10175 this.start();
10176 }
10177
10178 /**
10179 * @returns {number}
10180 */
10181 start() {
10182 if (!this.running) {
10183 this.running = true;
10184 this.started = new Date();
10185 this.id = setTimeout(this.callback, this.remaining);
10186 }
10187 return this.remaining;
10188 }
10189
10190 /**
10191 * @returns {number}
10192 */
10193 stop() {
10194 if (this.started && this.running) {
10195 this.running = false;
10196 clearTimeout(this.id);
10197 this.remaining -= new Date().getTime() - this.started.getTime();
10198 }
10199 return this.remaining;
10200 }
10201
10202 /**
10203 * @param {number} n
10204 * @returns {number}
10205 */
10206 increase(n) {
10207 const running = this.running;
10208 if (running) {
10209 this.stop();
10210 }
10211 this.remaining += n;
10212 if (running) {
10213 this.start();
10214 }
10215 return this.remaining;
10216 }
10217
10218 /**
10219 * @returns {number}
10220 */
10221 getTimerLeft() {
10222 if (this.running) {
10223 this.stop();
10224 this.start();
10225 }
10226 return this.remaining;
10227 }
10228
10229 /**
10230 * @returns {boolean}
10231 */
10232 isRunning() {
10233 return this.running;
10234 }
10235 }
10236
10237 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10238
10239 /**
10240 * @param {SweetAlertOptions} params
10241 * @returns {SweetAlertOptions}
10242 */
10243 const getTemplateParams = params => {
10244 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10245 if (!template) {
10246 return {};
10247 }
10248 /** @type {DocumentFragment} */
10249 const templateContent = template.content;
10250 showWarningsForElements(templateContent);
10251 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10252 return result;
10253 };
10254
10255 /**
10256 * @param {DocumentFragment} templateContent
10257 * @returns {Record<string, string | boolean | number>}
10258 */
10259 const getSwalParams = templateContent => {
10260 /** @type {Record<string, string | boolean | number>} */
10261 const result = {};
10262 /** @type {HTMLElement[]} */
10263 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10264 swalParams.forEach(param => {
10265 showWarningsForAttributes(param, ['name', 'value']);
10266 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10267 const value = param.getAttribute('value');
10268 if (!paramName || !value) {
10269 return;
10270 }
10271 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10272 result[paramName] = value !== 'false';
10273 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10274 result[paramName] = JSON.parse(value);
10275 } else {
10276 result[paramName] = value;
10277 }
10278 });
10279 return result;
10280 };
10281
10282 /**
10283 * @param {DocumentFragment} templateContent
10284 * @returns {Record<string, () => void>}
10285 */
10286 const getSwalFunctionParams = templateContent => {
10287 /** @type {Record<string, () => void>} */
10288 const result = {};
10289 /** @type {HTMLElement[]} */
10290 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10291 swalFunctions.forEach(param => {
10292 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10293 const value = param.getAttribute('value');
10294 if (!paramName || !value) {
10295 return;
10296 }
10297 result[paramName] = new Function(`return ${value}`)();
10298 });
10299 return result;
10300 };
10301
10302 /**
10303 * @param {DocumentFragment} templateContent
10304 * @returns {Record<string, string | boolean>}
10305 */
10306 const getSwalButtons = templateContent => {
10307 /** @type {Record<string, string | boolean>} */
10308 const result = {};
10309 /** @type {HTMLElement[]} */
10310 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10311 swalButtons.forEach(button => {
10312 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10313 const type = button.getAttribute('type');
10314 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10315 return;
10316 }
10317 result[`${type}ButtonText`] = button.innerHTML;
10318 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10319 if (button.hasAttribute('color')) {
10320 const color = button.getAttribute('color');
10321 if (color !== null) {
10322 result[`${type}ButtonColor`] = color;
10323 }
10324 }
10325 if (button.hasAttribute('aria-label')) {
10326 const ariaLabel = button.getAttribute('aria-label');
10327 if (ariaLabel !== null) {
10328 result[`${type}ButtonAriaLabel`] = ariaLabel;
10329 }
10330 }
10331 });
10332 return result;
10333 };
10334
10335 /**
10336 * @param {DocumentFragment} templateContent
10337 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10338 */
10339 const getSwalImage = templateContent => {
10340 const result = {};
10341 /** @type {HTMLElement | null} */
10342 const image = templateContent.querySelector('swal-image');
10343 if (image) {
10344 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10345 if (image.hasAttribute('src')) {
10346 result.imageUrl = image.getAttribute('src') || undefined;
10347 }
10348 if (image.hasAttribute('width')) {
10349 result.imageWidth = image.getAttribute('width') || undefined;
10350 }
10351 if (image.hasAttribute('height')) {
10352 result.imageHeight = image.getAttribute('height') || undefined;
10353 }
10354 if (image.hasAttribute('alt')) {
10355 result.imageAlt = image.getAttribute('alt') || undefined;
10356 }
10357 }
10358 return result;
10359 };
10360
10361 /**
10362 * @param {DocumentFragment} templateContent
10363 * @returns {object}
10364 */
10365 const getSwalIcon = templateContent => {
10366 const result = {};
10367 /** @type {HTMLElement | null} */
10368 const icon = templateContent.querySelector('swal-icon');
10369 if (icon) {
10370 showWarningsForAttributes(icon, ['type', 'color']);
10371 if (icon.hasAttribute('type')) {
10372 result.icon = icon.getAttribute('type');
10373 }
10374 if (icon.hasAttribute('color')) {
10375 result.iconColor = icon.getAttribute('color');
10376 }
10377 result.iconHtml = icon.innerHTML;
10378 }
10379 return result;
10380 };
10381
10382 /**
10383 * @param {DocumentFragment} templateContent
10384 * @returns {object}
10385 */
10386 const getSwalInput = templateContent => {
10387 /** @type {Record<string, any>} */
10388 const result = {};
10389 /** @type {HTMLElement | null} */
10390 const input = templateContent.querySelector('swal-input');
10391 if (input) {
10392 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10393 result.input = input.getAttribute('type') || 'text';
10394 if (input.hasAttribute('label')) {
10395 result.inputLabel = input.getAttribute('label');
10396 }
10397 if (input.hasAttribute('placeholder')) {
10398 result.inputPlaceholder = input.getAttribute('placeholder');
10399 }
10400 if (input.hasAttribute('value')) {
10401 result.inputValue = input.getAttribute('value');
10402 }
10403 }
10404 /** @type {HTMLElement[]} */
10405 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10406 if (inputOptions.length) {
10407 result.inputOptions = {};
10408 inputOptions.forEach(option => {
10409 showWarningsForAttributes(option, ['value']);
10410 const optionValue = option.getAttribute('value');
10411 if (!optionValue) {
10412 return;
10413 }
10414 const optionName = option.innerHTML;
10415 result.inputOptions[optionValue] = optionName;
10416 });
10417 }
10418 return result;
10419 };
10420
10421 /**
10422 * @param {DocumentFragment} templateContent
10423 * @param {string[]} paramNames
10424 * @returns {Record<string, string>}
10425 */
10426 const getSwalStringParams = (templateContent, paramNames) => {
10427 /** @type {Record<string, string>} */
10428 const result = {};
10429 for (const i in paramNames) {
10430 const paramName = paramNames[i];
10431 /** @type {HTMLElement | null} */
10432 const tag = templateContent.querySelector(paramName);
10433 if (tag) {
10434 showWarningsForAttributes(tag, []);
10435 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10436 }
10437 }
10438 return result;
10439 };
10440
10441 /**
10442 * @param {DocumentFragment} templateContent
10443 */
10444 const showWarningsForElements = templateContent => {
10445 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10446 Array.from(templateContent.children).forEach(el => {
10447 const tagName = el.tagName.toLowerCase();
10448 if (!allowedElements.includes(tagName)) {
10449 warn(`Unrecognized element <${tagName}>`);
10450 }
10451 });
10452 };
10453
10454 /**
10455 * @param {HTMLElement} el
10456 * @param {string[]} allowedAttributes
10457 */
10458 const showWarningsForAttributes = (el, allowedAttributes) => {
10459 Array.from(el.attributes).forEach(attribute => {
10460 if (allowedAttributes.indexOf(attribute.name) === -1) {
10461 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.'}`]);
10462 }
10463 });
10464 };
10465
10466 const SHOW_CLASS_TIMEOUT = 10;
10467
10468 /**
10469 * Open popup, add necessary classes and styles, fix scrollbar
10470 *
10471 * @param {SweetAlertOptions} params
10472 */
10473 const openPopup = params => {
10474 var _globalState$eventEmi, _globalState$eventEmi2;
10475 const container = getContainer();
10476 const popup = getPopup();
10477 if (!container || !popup) {
10478 return;
10479 }
10480 if (typeof params.willOpen === 'function') {
10481 params.willOpen(popup);
10482 }
10483 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10484 const bodyStyles = window.getComputedStyle(document.body);
10485 const initialBodyOverflow = bodyStyles.overflowY;
10486 addClasses(container, popup, params);
10487
10488 // scrolling is 'hidden' until animation is done, after that 'auto'
10489 setTimeout(() => {
10490 setScrollingVisibility(container, popup);
10491 }, SHOW_CLASS_TIMEOUT);
10492 if (isModal()) {
10493 // Using ternary instead of ?? operator for Webpack 4 compatibility
10494 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10495 setAriaHidden();
10496 }
10497 if (!isToast() && !globalState.previousActiveElement) {
10498 globalState.previousActiveElement = document.activeElement;
10499 }
10500 if (typeof params.didOpen === 'function') {
10501 const didOpen = params.didOpen;
10502 setTimeout(() => didOpen(popup));
10503 }
10504 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10505 };
10506
10507 /**
10508 * @param {Event} event
10509 */
10510 const swalOpenAnimationFinished = event => {
10511 const popup = getPopup();
10512 if (!popup || event.target !== popup) {
10513 return;
10514 }
10515 const container = getContainer();
10516 if (!container) {
10517 return;
10518 }
10519 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10520 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10521 container.style.overflowY = 'auto';
10522
10523 // no-transition is added in init() in case one swal is opened right after another
10524 removeClass(container, swalClasses['no-transition']);
10525 };
10526
10527 /**
10528 * @param {HTMLElement} container
10529 * @param {HTMLElement} popup
10530 */
10531 const setScrollingVisibility = (container, popup) => {
10532 if (hasCssAnimation(popup)) {
10533 container.style.overflowY = 'hidden';
10534 popup.addEventListener('animationend', swalOpenAnimationFinished);
10535 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10536 } else {
10537 container.style.overflowY = 'auto';
10538 }
10539 };
10540
10541 /**
10542 * @param {HTMLElement} container
10543 * @param {boolean} scrollbarPadding
10544 * @param {string} initialBodyOverflow
10545 */
10546 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10547 iOSfix();
10548 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10549 replaceScrollbarWithPadding(initialBodyOverflow);
10550 }
10551
10552 // sweetalert2/issues/1247
10553 setTimeout(() => {
10554 container.scrollTop = 0;
10555 });
10556 };
10557
10558 /**
10559 * @param {HTMLElement} container
10560 * @param {HTMLElement} popup
10561 * @param {SweetAlertOptions} params
10562 */
10563 const addClasses = (container, popup, params) => {
10564 var _params$showClass;
10565 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10566 addClass(container, params.showClass.backdrop);
10567 }
10568 if (params.animation) {
10569 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10570 popup.style.setProperty('opacity', '0', 'important');
10571 show(popup, 'grid');
10572 setTimeout(() => {
10573 var _params$showClass2;
10574 // Animate popup right after showing it
10575 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10576 addClass(popup, params.showClass.popup);
10577 }
10578 // and remove the opacity workaround
10579 popup.style.removeProperty('opacity');
10580 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10581 } else {
10582 show(popup, 'grid');
10583 }
10584 addClass([document.documentElement, document.body], swalClasses.shown);
10585 if (params.heightAuto && params.backdrop && !params.toast) {
10586 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10587 }
10588 };
10589
10590 var defaultInputValidators = {
10591 /**
10592 * @param {string} string
10593 * @param {string} [validationMessage]
10594 * @returns {Promise<string | void>}
10595 */
10596 email: (string, validationMessage) => {
10597 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10598 },
10599 /**
10600 * @param {string} string
10601 * @param {string} [validationMessage]
10602 * @returns {Promise<string | void>}
10603 */
10604 url: (string, validationMessage) => {
10605 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10606 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');
10607 }
10608 };
10609
10610 /**
10611 * @param {SweetAlertOptions} params
10612 */
10613 function setDefaultInputValidators(params) {
10614 // Use default `inputValidator` for supported input types if not provided
10615 if (params.inputValidator) {
10616 return;
10617 }
10618 if (params.input === 'email') {
10619 params.inputValidator = defaultInputValidators['email'];
10620 }
10621 if (params.input === 'url') {
10622 params.inputValidator = defaultInputValidators['url'];
10623 }
10624 }
10625
10626 /**
10627 * @param {SweetAlertOptions} params
10628 */
10629 function validateCustomTargetElement(params) {
10630 // Determine if the custom target element is valid
10631 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10632 warn('Target parameter is not valid, defaulting to "body"');
10633 params.target = 'body';
10634 }
10635 }
10636
10637 /**
10638 * Set type, text and actions on popup
10639 *
10640 * @param {SweetAlertOptions} params
10641 */
10642 function setParameters(params) {
10643 setDefaultInputValidators(params);
10644
10645 // showLoaderOnConfirm && preConfirm
10646 if (params.showLoaderOnConfirm && !params.preConfirm) {
10647 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');
10648 }
10649 validateCustomTargetElement(params);
10650
10651 // Replace newlines with <br> in title
10652 if (typeof params.title === 'string') {
10653 params.title = params.title.split('\n').join('<br />');
10654 }
10655 init(params);
10656 }
10657
10658 /** @type {SweetAlert} */
10659 let currentInstance;
10660 var _promise = /*#__PURE__*/new WeakMap();
10661 class SweetAlert {
10662 /**
10663 * @param {...(SweetAlertOptions | string)} args
10664 * @this {SweetAlert}
10665 */
10666 constructor(...args) {
10667 /**
10668 * @type {Promise<SweetAlertResult>}
10669 */
10670 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
10671 isConfirmed: false,
10672 isDenied: false,
10673 isDismissed: true
10674 }));
10675 // Prevent run in Node env
10676 if (typeof window === 'undefined') {
10677 return;
10678 }
10679 currentInstance = this;
10680
10681 // @ts-ignore
10682 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10683
10684 /** @type {Readonly<SweetAlertOptions>} */
10685 this.params = outerParams;
10686
10687 /** @type {boolean} */
10688 this.isAwaitingPromise = false;
10689 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10690 }
10691
10692 /**
10693 * @param {any} userParams
10694 * @param {any} mixinParams
10695 */
10696 _main(userParams, mixinParams = {}) {
10697 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10698 if (globalState.currentInstance) {
10699 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10700 const {
10701 isAwaitingPromise
10702 } = globalState.currentInstance;
10703 globalState.currentInstance._destroy();
10704 if (!isAwaitingPromise) {
10705 swalPromiseResolve({
10706 isDismissed: true
10707 });
10708 }
10709 if (isModal()) {
10710 unsetAriaHidden();
10711 }
10712 }
10713 globalState.currentInstance = currentInstance;
10714 const innerParams = prepareParams(userParams, mixinParams);
10715 setParameters(innerParams);
10716 Object.freeze(innerParams);
10717
10718 // clear the previous timer
10719 if (globalState.timeout) {
10720 globalState.timeout.stop();
10721 delete globalState.timeout;
10722 }
10723
10724 // clear the restore focus timeout
10725 clearTimeout(globalState.restoreFocusTimeout);
10726 const domCache = populateDomCache(currentInstance);
10727 render(currentInstance, innerParams);
10728 privateProps.innerParams.set(currentInstance, innerParams);
10729 return swalPromise(currentInstance, domCache, innerParams);
10730 }
10731
10732 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10733 /**
10734 * @param {any} onFulfilled
10735 */
10736 then(onFulfilled) {
10737 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10738 }
10739
10740 /**
10741 * @param {any} onFinally
10742 */
10743 finally(onFinally) {
10744 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10745 }
10746 }
10747
10748 /**
10749 * @param {SweetAlert} instance
10750 * @param {DomCache} domCache
10751 * @param {SweetAlertOptions} innerParams
10752 * @returns {Promise<SweetAlertResult>}
10753 */
10754 const swalPromise = (instance, domCache, innerParams) => {
10755 return new Promise((resolve, reject) => {
10756 // functions to handle all closings/dismissals
10757 /**
10758 * @param {DismissReason} dismiss
10759 */
10760 const dismissWith = dismiss => {
10761 instance.close({
10762 isDismissed: true,
10763 dismiss,
10764 isConfirmed: false,
10765 isDenied: false
10766 });
10767 };
10768 privateMethods.swalPromiseResolve.set(instance, resolve);
10769 privateMethods.swalPromiseReject.set(instance, reject);
10770 domCache.confirmButton.onclick = () => {
10771 handleConfirmButtonClick(instance);
10772 };
10773 domCache.denyButton.onclick = () => {
10774 handleDenyButtonClick(instance);
10775 };
10776 domCache.cancelButton.onclick = () => {
10777 handleCancelButtonClick(instance, dismissWith);
10778 };
10779 domCache.closeButton.onclick = () => {
10780 dismissWith(DismissReason.close);
10781 };
10782 handlePopupClick(innerParams, domCache, dismissWith);
10783 addKeydownHandler(globalState, innerParams, dismissWith);
10784 handleInputOptionsAndValue(instance, innerParams);
10785 openPopup(innerParams);
10786 setupTimer(globalState, innerParams, dismissWith);
10787 initFocus(domCache, innerParams);
10788
10789 // Scroll container to top on open (#1247, #1946)
10790 setTimeout(() => {
10791 domCache.container.scrollTop = 0;
10792 });
10793 });
10794 };
10795
10796 /**
10797 * @param {SweetAlertOptions} userParams
10798 * @param {SweetAlertOptions} mixinParams
10799 * @returns {SweetAlertOptions}
10800 */
10801 const prepareParams = (userParams, mixinParams) => {
10802 const templateParams = getTemplateParams(userParams);
10803 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10804 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10805 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10806 if (params.animation === false) {
10807 params.showClass = {
10808 backdrop: 'swal2-noanimation'
10809 };
10810 params.hideClass = {};
10811 }
10812 return params;
10813 };
10814
10815 /**
10816 * @param {SweetAlert} instance
10817 * @returns {DomCache}
10818 */
10819 const populateDomCache = instance => {
10820 const domCache = /** @type {DomCache} */{
10821 popup: (/** @type {HTMLElement} */getPopup()),
10822 container: (/** @type {HTMLElement} */getContainer()),
10823 actions: (/** @type {HTMLElement} */getActions()),
10824 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10825 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10826 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10827 loader: (/** @type {HTMLElement} */getLoader()),
10828 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10829 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10830 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10831 };
10832 privateProps.domCache.set(instance, domCache);
10833 return domCache;
10834 };
10835
10836 /**
10837 * @param {GlobalState} globalState
10838 * @param {SweetAlertOptions} innerParams
10839 * @param {(dismiss: DismissReason) => void} dismissWith
10840 */
10841 const setupTimer = (globalState, innerParams, dismissWith) => {
10842 const timerProgressBar = getTimerProgressBar();
10843 hide(timerProgressBar);
10844 if (innerParams.timer) {
10845 globalState.timeout = new Timer(() => {
10846 dismissWith('timer');
10847 delete globalState.timeout;
10848 }, innerParams.timer);
10849 if (innerParams.timerProgressBar && timerProgressBar) {
10850 show(timerProgressBar);
10851 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10852 setTimeout(() => {
10853 if (globalState.timeout && globalState.timeout.running) {
10854 // timer can be already stopped or unset at this point
10855 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10856 }
10857 });
10858 }
10859 }
10860 };
10861
10862 /**
10863 * Initialize focus in the popup:
10864 *
10865 * 1. If `toast` is `true`, don't steal focus from the document.
10866 * 2. Else if there is an [autofocus] element, focus it.
10867 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10868 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10869 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10870 * 6. Else focus the first focusable element in a popup (if any).
10871 *
10872 * @param {DomCache} domCache
10873 * @param {SweetAlertOptions} innerParams
10874 */
10875 const initFocus = (domCache, innerParams) => {
10876 if (innerParams.toast) {
10877 return;
10878 }
10879 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10880 if (!callIfFunction(innerParams.allowEnterKey)) {
10881 warnAboutDeprecation('allowEnterKey');
10882 blurActiveElement();
10883 return;
10884 }
10885 if (focusAutofocus(domCache)) {
10886 return;
10887 }
10888 if (focusButton(domCache, innerParams)) {
10889 return;
10890 }
10891 setFocus(-1, 1);
10892 };
10893
10894 /**
10895 * @param {DomCache} domCache
10896 * @returns {boolean}
10897 */
10898 const focusAutofocus = domCache => {
10899 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10900 for (const autofocusElement of autofocusElements) {
10901 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10902 autofocusElement.focus();
10903 return true;
10904 }
10905 }
10906 return false;
10907 };
10908
10909 /**
10910 * @param {DomCache} domCache
10911 * @param {SweetAlertOptions} innerParams
10912 * @returns {boolean}
10913 */
10914 const focusButton = (domCache, innerParams) => {
10915 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10916 domCache.denyButton.focus();
10917 return true;
10918 }
10919 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10920 domCache.cancelButton.focus();
10921 return true;
10922 }
10923 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10924 domCache.confirmButton.focus();
10925 return true;
10926 }
10927 return false;
10928 };
10929 const blurActiveElement = () => {
10930 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
10931 document.activeElement.blur();
10932 }
10933 };
10934
10935 // Assign instance methods from src/instanceMethods/*.js to prototype
10936 SweetAlert.prototype.disableButtons = disableButtons;
10937 SweetAlert.prototype.enableButtons = enableButtons;
10938 SweetAlert.prototype.getInput = getInput;
10939 SweetAlert.prototype.disableInput = disableInput;
10940 SweetAlert.prototype.enableInput = enableInput;
10941 SweetAlert.prototype.hideLoading = hideLoading;
10942 SweetAlert.prototype.disableLoading = hideLoading;
10943 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10944 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10945 SweetAlert.prototype.close = close;
10946 SweetAlert.prototype.closePopup = close;
10947 SweetAlert.prototype.closeModal = close;
10948 SweetAlert.prototype.closeToast = close;
10949 SweetAlert.prototype.rejectPromise = rejectPromise;
10950 SweetAlert.prototype.update = update;
10951 SweetAlert.prototype._destroy = _destroy;
10952
10953 // Assign static methods from src/staticMethods/*.js to constructor
10954 Object.assign(SweetAlert, staticMethods);
10955
10956 // Proxy to instance methods to constructor, for now, for backwards compatibility
10957 Object.keys(instanceMethods).forEach(key => {
10958 /**
10959 * @param {...(SweetAlertOptions | string | undefined)} args
10960 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10961 */
10962 // @ts-ignore: Dynamic property assignment for backwards compatibility
10963 SweetAlert[key] = function (...args) {
10964 // @ts-ignore
10965 if (currentInstance && currentInstance[key]) {
10966 // @ts-ignore
10967 return currentInstance[key](...args);
10968 }
10969 return undefined;
10970 };
10971 });
10972 SweetAlert.DismissReason = DismissReason;
10973 SweetAlert.version = '11.26.17';
10974
10975 const Swal = SweetAlert;
10976 // @ts-ignore
10977 Swal.default = Swal;
10978
10979 return Swal;
10980
10981 }));
10982 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10983 "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-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px 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:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;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)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform: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}}");
10984
10985 /***/ },
10986
10987 /***/ "./node_modules/toastify-js/src/toastify.js"
10988 /*!**************************************************!*\
10989 !*** ./node_modules/toastify-js/src/toastify.js ***!
10990 \**************************************************/
10991 (module) {
10992
10993 /*!
10994 * Toastify js 1.12.0
10995 * https://github.com/apvarun/toastify-js
10996 * @license MIT licensed
10997 *
10998 * Copyright (C) 2018 Varun A P
10999 */
11000 (function(root, factory) {
11001 if ( true && module.exports) {
11002 module.exports = factory();
11003 } else {
11004 root.Toastify = factory();
11005 }
11006 })(this, function(global) {
11007 // Object initialization
11008 var Toastify = function(options) {
11009 // Returning a new init object
11010 return new Toastify.lib.init(options);
11011 },
11012 // Library version
11013 version = "1.12.0";
11014
11015 // Set the default global options
11016 Toastify.defaults = {
11017 oldestFirst: true,
11018 text: "Toastify is awesome!",
11019 node: undefined,
11020 duration: 3000,
11021 selector: undefined,
11022 callback: function () {
11023 },
11024 destination: undefined,
11025 newWindow: false,
11026 close: false,
11027 gravity: "toastify-top",
11028 positionLeft: false,
11029 position: '',
11030 backgroundColor: '',
11031 avatar: "",
11032 className: "",
11033 stopOnFocus: true,
11034 onClick: function () {
11035 },
11036 offset: {x: 0, y: 0},
11037 escapeMarkup: true,
11038 ariaLive: 'polite',
11039 style: {background: ''}
11040 };
11041
11042 // Defining the prototype of the object
11043 Toastify.lib = Toastify.prototype = {
11044 toastify: version,
11045
11046 constructor: Toastify,
11047
11048 // Initializing the object with required parameters
11049 init: function(options) {
11050 // Verifying and validating the input object
11051 if (!options) {
11052 options = {};
11053 }
11054
11055 // Creating the options object
11056 this.options = {};
11057
11058 this.toastElement = null;
11059
11060 // Validating the options
11061 this.options.text = options.text || Toastify.defaults.text; // Display message
11062 this.options.node = options.node || Toastify.defaults.node; // Display content as node
11063 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
11064 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
11065 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
11066 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
11067 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
11068 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
11069 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
11070 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
11071 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
11072 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
11073 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
11074 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
11075 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
11076 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
11077 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
11078 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
11079 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
11080 this.options.style = options.style || Toastify.defaults.style;
11081 if(options.backgroundColor) {
11082 this.options.style.background = options.backgroundColor;
11083 }
11084
11085 // Returning the current object for chaining functions
11086 return this;
11087 },
11088
11089 // Building the DOM element
11090 buildToast: function() {
11091 // Validating if the options are defined
11092 if (!this.options) {
11093 throw "Toastify is not initialized";
11094 }
11095
11096 // Creating the DOM object
11097 var divElement = document.createElement("div");
11098 divElement.className = "toastify on " + this.options.className;
11099
11100 // Positioning toast to left or right or center
11101 if (!!this.options.position) {
11102 divElement.className += " toastify-" + this.options.position;
11103 } else {
11104 // To be depreciated in further versions
11105 if (this.options.positionLeft === true) {
11106 divElement.className += " toastify-left";
11107 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
11108 } else {
11109 // Default position
11110 divElement.className += " toastify-right";
11111 }
11112 }
11113
11114 // Assigning gravity of element
11115 divElement.className += " " + this.options.gravity;
11116
11117 if (this.options.backgroundColor) {
11118 // This is being deprecated in favor of using the style HTML DOM property
11119 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
11120 }
11121
11122 // Loop through our style object and apply styles to divElement
11123 for (var property in this.options.style) {
11124 divElement.style[property] = this.options.style[property];
11125 }
11126
11127 // Announce the toast to screen readers
11128 if (this.options.ariaLive) {
11129 divElement.setAttribute('aria-live', this.options.ariaLive)
11130 }
11131
11132 // Adding the toast message/node
11133 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
11134 // If we have a valid node, we insert it
11135 divElement.appendChild(this.options.node)
11136 } else {
11137 if (this.options.escapeMarkup) {
11138 divElement.innerText = this.options.text;
11139 } else {
11140 divElement.innerHTML = this.options.text;
11141 }
11142
11143 if (this.options.avatar !== "") {
11144 var avatarElement = document.createElement("img");
11145 avatarElement.src = this.options.avatar;
11146
11147 avatarElement.className = "toastify-avatar";
11148
11149 if (this.options.position == "left" || this.options.positionLeft === true) {
11150 // Adding close icon on the left of content
11151 divElement.appendChild(avatarElement);
11152 } else {
11153 // Adding close icon on the right of content
11154 divElement.insertAdjacentElement("afterbegin", avatarElement);
11155 }
11156 }
11157 }
11158
11159 // Adding a close icon to the toast
11160 if (this.options.close === true) {
11161 // Create a span for close element
11162 var closeElement = document.createElement("button");
11163 closeElement.type = "button";
11164 closeElement.setAttribute("aria-label", "Close");
11165 closeElement.className = "toast-close";
11166 closeElement.innerHTML = "&#10006;";
11167
11168 // Triggering the removal of toast from DOM on close click
11169 closeElement.addEventListener(
11170 "click",
11171 function(event) {
11172 event.stopPropagation();
11173 this.removeElement(this.toastElement);
11174 window.clearTimeout(this.toastElement.timeOutValue);
11175 }.bind(this)
11176 );
11177
11178 //Calculating screen width
11179 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11180
11181 // Adding the close icon to the toast element
11182 // Display on the right if screen width is less than or equal to 360px
11183 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11184 // Adding close icon on the left of content
11185 divElement.insertAdjacentElement("afterbegin", closeElement);
11186 } else {
11187 // Adding close icon on the right of content
11188 divElement.appendChild(closeElement);
11189 }
11190 }
11191
11192 // Clear timeout while toast is focused
11193 if (this.options.stopOnFocus && this.options.duration > 0) {
11194 var self = this;
11195 // stop countdown
11196 divElement.addEventListener(
11197 "mouseover",
11198 function(event) {
11199 window.clearTimeout(divElement.timeOutValue);
11200 }
11201 )
11202 // add back the timeout
11203 divElement.addEventListener(
11204 "mouseleave",
11205 function() {
11206 divElement.timeOutValue = window.setTimeout(
11207 function() {
11208 // Remove the toast from DOM
11209 self.removeElement(divElement);
11210 },
11211 self.options.duration
11212 )
11213 }
11214 )
11215 }
11216
11217 // Adding an on-click destination path
11218 if (typeof this.options.destination !== "undefined") {
11219 divElement.addEventListener(
11220 "click",
11221 function(event) {
11222 event.stopPropagation();
11223 if (this.options.newWindow === true) {
11224 window.open(this.options.destination, "_blank");
11225 } else {
11226 window.location = this.options.destination;
11227 }
11228 }.bind(this)
11229 );
11230 }
11231
11232 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11233 divElement.addEventListener(
11234 "click",
11235 function(event) {
11236 event.stopPropagation();
11237 this.options.onClick();
11238 }.bind(this)
11239 );
11240 }
11241
11242 // Adding offset
11243 if(typeof this.options.offset === "object") {
11244
11245 var x = getAxisOffsetAValue("x", this.options);
11246 var y = getAxisOffsetAValue("y", this.options);
11247
11248 var xOffset = this.options.position == "left" ? x : "-" + x;
11249 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11250
11251 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11252
11253 }
11254
11255 // Returning the generated element
11256 return divElement;
11257 },
11258
11259 // Displaying the toast
11260 showToast: function() {
11261 // Creating the DOM object for the toast
11262 this.toastElement = this.buildToast();
11263
11264 // Getting the root element to with the toast needs to be added
11265 var rootElement;
11266 if (typeof this.options.selector === "string") {
11267 rootElement = document.getElementById(this.options.selector);
11268 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11269 rootElement = this.options.selector;
11270 } else {
11271 rootElement = document.body;
11272 }
11273
11274 // Validating if root element is present in DOM
11275 if (!rootElement) {
11276 throw "Root element is not defined";
11277 }
11278
11279 // Adding the DOM element
11280 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11281 rootElement.insertBefore(this.toastElement, elementToInsert);
11282
11283 // Repositioning the toasts in case multiple toasts are present
11284 Toastify.reposition();
11285
11286 if (this.options.duration > 0) {
11287 this.toastElement.timeOutValue = window.setTimeout(
11288 function() {
11289 // Remove the toast from DOM
11290 this.removeElement(this.toastElement);
11291 }.bind(this),
11292 this.options.duration
11293 ); // Binding `this` for function invocation
11294 }
11295
11296 // Supporting function chaining
11297 return this;
11298 },
11299
11300 hideToast: function() {
11301 if (this.toastElement.timeOutValue) {
11302 clearTimeout(this.toastElement.timeOutValue);
11303 }
11304 this.removeElement(this.toastElement);
11305 },
11306
11307 // Removing the element from the DOM
11308 removeElement: function(toastElement) {
11309 // Hiding the element
11310 // toastElement.classList.remove("on");
11311 toastElement.className = toastElement.className.replace(" on", "");
11312
11313 // Removing the element from DOM after transition end
11314 window.setTimeout(
11315 function() {
11316 // remove options node if any
11317 if (this.options.node && this.options.node.parentNode) {
11318 this.options.node.parentNode.removeChild(this.options.node);
11319 }
11320
11321 // Remove the element from the DOM, only when the parent node was not removed before.
11322 if (toastElement.parentNode) {
11323 toastElement.parentNode.removeChild(toastElement);
11324 }
11325
11326 // Calling the callback function
11327 this.options.callback.call(toastElement);
11328
11329 // Repositioning the toasts again
11330 Toastify.reposition();
11331 }.bind(this),
11332 400
11333 ); // Binding `this` for function invocation
11334 },
11335 };
11336
11337 // Positioning the toasts on the DOM
11338 Toastify.reposition = function() {
11339
11340 // Top margins with gravity
11341 var topLeftOffsetSize = {
11342 top: 15,
11343 bottom: 15,
11344 };
11345 var topRightOffsetSize = {
11346 top: 15,
11347 bottom: 15,
11348 };
11349 var offsetSize = {
11350 top: 15,
11351 bottom: 15,
11352 };
11353
11354 // Get all toast messages on the DOM
11355 var allToasts = document.getElementsByClassName("toastify");
11356
11357 var classUsed;
11358
11359 // Modifying the position of each toast element
11360 for (var i = 0; i < allToasts.length; i++) {
11361 // Getting the applied gravity
11362 if (containsClass(allToasts[i], "toastify-top") === true) {
11363 classUsed = "toastify-top";
11364 } else {
11365 classUsed = "toastify-bottom";
11366 }
11367
11368 var height = allToasts[i].offsetHeight;
11369 classUsed = classUsed.substr(9, classUsed.length-1)
11370 // Spacing between toasts
11371 var offset = 15;
11372
11373 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11374
11375 // Show toast in center if screen with less than or equal to 360px
11376 if (width <= 360) {
11377 // Setting the position
11378 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11379
11380 offsetSize[classUsed] += height + offset;
11381 } else {
11382 if (containsClass(allToasts[i], "toastify-left") === true) {
11383 // Setting the position
11384 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11385
11386 topLeftOffsetSize[classUsed] += height + offset;
11387 } else {
11388 // Setting the position
11389 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11390
11391 topRightOffsetSize[classUsed] += height + offset;
11392 }
11393 }
11394 }
11395
11396 // Supporting function chaining
11397 return this;
11398 };
11399
11400 // Helper function to get offset.
11401 function getAxisOffsetAValue(axis, options) {
11402
11403 if(options.offset[axis]) {
11404 if(isNaN(options.offset[axis])) {
11405 return options.offset[axis];
11406 }
11407 else {
11408 return options.offset[axis] + 'px';
11409 }
11410 }
11411
11412 return '0px';
11413
11414 }
11415
11416 function containsClass(elem, yourClass) {
11417 if (!elem || typeof yourClass !== "string") {
11418 return false;
11419 } else if (
11420 elem.className &&
11421 elem.className
11422 .trim()
11423 .split(/\s+/gi)
11424 .indexOf(yourClass) > -1
11425 ) {
11426 return true;
11427 } else {
11428 return false;
11429 }
11430 }
11431
11432 // Setting up the prototype for the init object
11433 Toastify.lib.init.prototype = Toastify.lib;
11434
11435 // Returning the Toastify function to be assigned to the window object/module
11436 return Toastify;
11437 });
11438
11439
11440 /***/ },
11441
11442 /***/ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"
11443 /*!**************************************************************************************************************************************************************************************************************************************************************!*\
11444 !*** data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC ***!
11445 \**************************************************************************************************************************************************************************************************************************************************************/
11446 (module) {
11447
11448 "use strict";
11449 module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC";
11450
11451 /***/ }
11452
11453 /******/ });
11454 /************************************************************************/
11455 /******/ // The module cache
11456 /******/ var __webpack_module_cache__ = {};
11457 /******/
11458 /******/ // The require function
11459 /******/ function __webpack_require__(moduleId) {
11460 /******/ // Check if module is in cache
11461 /******/ var cachedModule = __webpack_module_cache__[moduleId];
11462 /******/ if (cachedModule !== undefined) {
11463 /******/ return cachedModule.exports;
11464 /******/ }
11465 /******/ // Create a new module (and put it into the cache)
11466 /******/ var module = __webpack_module_cache__[moduleId] = {
11467 /******/ id: moduleId,
11468 /******/ // no module.loaded needed
11469 /******/ exports: {}
11470 /******/ };
11471 /******/
11472 /******/ // Execute the module function
11473 /******/ if (!(moduleId in __webpack_modules__)) {
11474 /******/ delete __webpack_module_cache__[moduleId];
11475 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
11476 /******/ e.code = 'MODULE_NOT_FOUND';
11477 /******/ throw e;
11478 /******/ }
11479 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11480 /******/
11481 /******/ // Return the exports of the module
11482 /******/ return module.exports;
11483 /******/ }
11484 /******/
11485 /******/ // expose the modules object (__webpack_modules__)
11486 /******/ __webpack_require__.m = __webpack_modules__;
11487 /******/
11488 /************************************************************************/
11489 /******/ /* webpack/runtime/compat get default export */
11490 /******/ (() => {
11491 /******/ // getDefaultExport function for compatibility with non-harmony modules
11492 /******/ __webpack_require__.n = (module) => {
11493 /******/ var getter = module && module.__esModule ?
11494 /******/ () => (module['default']) :
11495 /******/ () => (module);
11496 /******/ __webpack_require__.d(getter, { a: getter });
11497 /******/ return getter;
11498 /******/ };
11499 /******/ })();
11500 /******/
11501 /******/ /* webpack/runtime/define property getters */
11502 /******/ (() => {
11503 /******/ // define getter functions for harmony exports
11504 /******/ __webpack_require__.d = (exports, definition) => {
11505 /******/ for(var key in definition) {
11506 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11507 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11508 /******/ }
11509 /******/ }
11510 /******/ };
11511 /******/ })();
11512 /******/
11513 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11514 /******/ (() => {
11515 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11516 /******/ })();
11517 /******/
11518 /******/ /* webpack/runtime/make namespace object */
11519 /******/ (() => {
11520 /******/ // define __esModule on exports
11521 /******/ __webpack_require__.r = (exports) => {
11522 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
11523 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11524 /******/ }
11525 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11526 /******/ };
11527 /******/ })();
11528 /******/
11529 /******/ /* webpack/runtime/jsonp chunk loading */
11530 /******/ (() => {
11531 /******/ __webpack_require__.b = (typeof document !== 'undefined' && document.baseURI) || self.location.href;
11532 /******/
11533 /******/ // object to store loaded and loading chunks
11534 /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
11535 /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
11536 /******/ var installedChunks = {
11537 /******/ "./assets/js/dist/frontend/profile": 0
11538 /******/ };
11539 /******/
11540 /******/ // no chunk on demand loading
11541 /******/
11542 /******/ // no prefetching
11543 /******/
11544 /******/ // no preloaded
11545 /******/
11546 /******/ // no HMR
11547 /******/
11548 /******/ // no HMR manifest
11549 /******/
11550 /******/ // no on chunks loaded
11551 /******/
11552 /******/ // no jsonp function
11553 /******/ })();
11554 /******/
11555 /******/ /* webpack/runtime/nonce */
11556 /******/ (() => {
11557 /******/ __webpack_require__.nc = undefined;
11558 /******/ })();
11559 /******/
11560 /************************************************************************/
11561 var __webpack_exports__ = {};
11562 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11563 (() => {
11564 "use strict";
11565 /*!*******************************************!*\
11566 !*** ./assets/src/js/frontend/profile.js ***!
11567 \*******************************************/
11568 __webpack_require__.r(__webpack_exports__);
11569 /* harmony import */ var _profile_course_tab__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./profile/course-tab */ "./assets/src/js/frontend/profile/course-tab.js");
11570 /* harmony import */ var _profile_statistic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./profile/statistic */ "./assets/src/js/frontend/profile/statistic.js");
11571 /* harmony import */ var _profile_order_recover__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./profile/order-recover */ "./assets/src/js/frontend/profile/order-recover.js");
11572 /* harmony import */ var _profile_cover_image__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./profile/cover-image */ "./assets/src/js/frontend/profile/cover-image.js");
11573 /* harmony import */ var _profile_avatar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./profile/avatar */ "./assets/src/js/frontend/profile/avatar.js");
11574 /* harmony import */ var _profile_quiz__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./profile/quiz */ "./assets/src/js/frontend/profile/quiz.js");
11575 /* harmony import */ var _profile_order_refund__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./profile/order-refund */ "./assets/src/js/frontend/profile/order-refund.js");
11576 /* 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");
11577
11578
11579
11580
11581
11582
11583
11584
11585 (0,_profile_cover_image__WEBPACK_IMPORTED_MODULE_3__["default"])();
11586 (0,_profile_quiz__WEBPACK_IMPORTED_MODULE_5__["default"])();
11587 (0,_profile_statistic__WEBPACK_IMPORTED_MODULE_1__["default"])();
11588 (0,_profile_order_recover__WEBPACK_IMPORTED_MODULE_2__["default"])();
11589 (0,_profile_order_refund__WEBPACK_IMPORTED_MODULE_6__["default"])();
11590 new _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__.ViewStudentsModal();
11591 document.addEventListener('DOMContentLoaded', function (event) {
11592 (0,_profile_course_tab__WEBPACK_IMPORTED_MODULE_0__["default"])();
11593 });
11594 if (document.getElementById('learnpress-avatar-upload')) {
11595 (0,_profile_avatar__WEBPACK_IMPORTED_MODULE_4__["default"])();
11596 }
11597 })();
11598
11599 /******/ })()
11600 ;
11601 //# sourceMappingURL=profile.js.map