UNPKG

355 kBJavaScriptView Raw
1/**
2 * Swiper Custom Element 10.0.4
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * https://swiperjs.com
5 *
6 * Copyright 2014-2023 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: July 8, 2023
11 */
12
13(function () {
14 'use strict';
15
16 /**
17 * SSR Window 4.0.2
18 * Better handling for window object in SSR environment
19 * https://github.com/nolimits4web/ssr-window
20 *
21 * Copyright 2021, Vladimir Kharlampidi
22 *
23 * Licensed under MIT
24 *
25 * Released on: December 13, 2021
26 */
27 /* eslint-disable no-param-reassign */
28 function isObject$2(obj) {
29 return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
30 }
31 function extend$2(target, src) {
32 if (target === void 0) {
33 target = {};
34 }
35 if (src === void 0) {
36 src = {};
37 }
38 Object.keys(src).forEach(key => {
39 if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject$2(src[key]) && isObject$2(target[key]) && Object.keys(src[key]).length > 0) {
40 extend$2(target[key], src[key]);
41 }
42 });
43 }
44 const ssrDocument = {
45 body: {},
46 addEventListener() {},
47 removeEventListener() {},
48 activeElement: {
49 blur() {},
50 nodeName: ''
51 },
52 querySelector() {
53 return null;
54 },
55 querySelectorAll() {
56 return [];
57 },
58 getElementById() {
59 return null;
60 },
61 createEvent() {
62 return {
63 initEvent() {}
64 };
65 },
66 createElement() {
67 return {
68 children: [],
69 childNodes: [],
70 style: {},
71 setAttribute() {},
72 getElementsByTagName() {
73 return [];
74 }
75 };
76 },
77 createElementNS() {
78 return {};
79 },
80 importNode() {
81 return null;
82 },
83 location: {
84 hash: '',
85 host: '',
86 hostname: '',
87 href: '',
88 origin: '',
89 pathname: '',
90 protocol: '',
91 search: ''
92 }
93 };
94 function getDocument() {
95 const doc = typeof document !== 'undefined' ? document : {};
96 extend$2(doc, ssrDocument);
97 return doc;
98 }
99 const ssrWindow = {
100 document: ssrDocument,
101 navigator: {
102 userAgent: ''
103 },
104 location: {
105 hash: '',
106 host: '',
107 hostname: '',
108 href: '',
109 origin: '',
110 pathname: '',
111 protocol: '',
112 search: ''
113 },
114 history: {
115 replaceState() {},
116 pushState() {},
117 go() {},
118 back() {}
119 },
120 CustomEvent: function CustomEvent() {
121 return this;
122 },
123 addEventListener() {},
124 removeEventListener() {},
125 getComputedStyle() {
126 return {
127 getPropertyValue() {
128 return '';
129 }
130 };
131 },
132 Image() {},
133 Date() {},
134 screen: {},
135 setTimeout() {},
136 clearTimeout() {},
137 matchMedia() {
138 return {};
139 },
140 requestAnimationFrame(callback) {
141 if (typeof setTimeout === 'undefined') {
142 callback();
143 return null;
144 }
145 return setTimeout(callback, 0);
146 },
147 cancelAnimationFrame(id) {
148 if (typeof setTimeout === 'undefined') {
149 return;
150 }
151 clearTimeout(id);
152 }
153 };
154 function getWindow() {
155 const win = typeof window !== 'undefined' ? window : {};
156 extend$2(win, ssrWindow);
157 return win;
158 }
159
160 function deleteProps(obj) {
161 const object = obj;
162 Object.keys(object).forEach(key => {
163 try {
164 object[key] = null;
165 } catch (e) {
166 // no getter for object
167 }
168 try {
169 delete object[key];
170 } catch (e) {
171 // something got wrong
172 }
173 });
174 }
175 function nextTick(callback, delay) {
176 if (delay === void 0) {
177 delay = 0;
178 }
179 return setTimeout(callback, delay);
180 }
181 function now() {
182 return Date.now();
183 }
184 function getComputedStyle$1(el) {
185 const window = getWindow();
186 let style;
187 if (window.getComputedStyle) {
188 style = window.getComputedStyle(el, null);
189 }
190 if (!style && el.currentStyle) {
191 style = el.currentStyle;
192 }
193 if (!style) {
194 style = el.style;
195 }
196 return style;
197 }
198 function getTranslate(el, axis) {
199 if (axis === void 0) {
200 axis = 'x';
201 }
202 const window = getWindow();
203 let matrix;
204 let curTransform;
205 let transformMatrix;
206 const curStyle = getComputedStyle$1(el);
207 if (window.WebKitCSSMatrix) {
208 curTransform = curStyle.transform || curStyle.webkitTransform;
209 if (curTransform.split(',').length > 6) {
210 curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
211 }
212 // Some old versions of Webkit choke when 'none' is passed; pass
213 // empty string instead in this case
214 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
215 } else {
216 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
217 matrix = transformMatrix.toString().split(',');
218 }
219 if (axis === 'x') {
220 // Latest Chrome and webkits Fix
221 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
222 // Crazy IE10 Matrix
223 else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
224 // Normal Browsers
225 else curTransform = parseFloat(matrix[4]);
226 }
227 if (axis === 'y') {
228 // Latest Chrome and webkits Fix
229 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
230 // Crazy IE10 Matrix
231 else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
232 // Normal Browsers
233 else curTransform = parseFloat(matrix[5]);
234 }
235 return curTransform || 0;
236 }
237 function isObject$1(o) {
238 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
239 }
240 function isNode(node) {
241 // eslint-disable-next-line
242 if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
243 return node instanceof HTMLElement;
244 }
245 return node && (node.nodeType === 1 || node.nodeType === 11);
246 }
247 function extend$1() {
248 const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
249 const noExtend = ['__proto__', 'constructor', 'prototype'];
250 for (let i = 1; i < arguments.length; i += 1) {
251 const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
252 if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
253 const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
254 for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
255 const nextKey = keysArray[nextIndex];
256 const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
257 if (desc !== undefined && desc.enumerable) {
258 if (isObject$1(to[nextKey]) && isObject$1(nextSource[nextKey])) {
259 if (nextSource[nextKey].__swiper__) {
260 to[nextKey] = nextSource[nextKey];
261 } else {
262 extend$1(to[nextKey], nextSource[nextKey]);
263 }
264 } else if (!isObject$1(to[nextKey]) && isObject$1(nextSource[nextKey])) {
265 to[nextKey] = {};
266 if (nextSource[nextKey].__swiper__) {
267 to[nextKey] = nextSource[nextKey];
268 } else {
269 extend$1(to[nextKey], nextSource[nextKey]);
270 }
271 } else {
272 to[nextKey] = nextSource[nextKey];
273 }
274 }
275 }
276 }
277 }
278 return to;
279 }
280 function setCSSProperty(el, varName, varValue) {
281 el.style.setProperty(varName, varValue);
282 }
283 function animateCSSModeScroll(_ref) {
284 let {
285 swiper,
286 targetPosition,
287 side
288 } = _ref;
289 const window = getWindow();
290 const startPosition = -swiper.translate;
291 let startTime = null;
292 let time;
293 const duration = swiper.params.speed;
294 swiper.wrapperEl.style.scrollSnapType = 'none';
295 window.cancelAnimationFrame(swiper.cssModeFrameID);
296 const dir = targetPosition > startPosition ? 'next' : 'prev';
297 const isOutOfBound = (current, target) => {
298 return dir === 'next' && current >= target || dir === 'prev' && current <= target;
299 };
300 const animate = () => {
301 time = new Date().getTime();
302 if (startTime === null) {
303 startTime = time;
304 }
305 const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
306 const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
307 let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
308 if (isOutOfBound(currentPosition, targetPosition)) {
309 currentPosition = targetPosition;
310 }
311 swiper.wrapperEl.scrollTo({
312 [side]: currentPosition
313 });
314 if (isOutOfBound(currentPosition, targetPosition)) {
315 swiper.wrapperEl.style.overflow = 'hidden';
316 swiper.wrapperEl.style.scrollSnapType = '';
317 setTimeout(() => {
318 swiper.wrapperEl.style.overflow = '';
319 swiper.wrapperEl.scrollTo({
320 [side]: currentPosition
321 });
322 });
323 window.cancelAnimationFrame(swiper.cssModeFrameID);
324 return;
325 }
326 swiper.cssModeFrameID = window.requestAnimationFrame(animate);
327 };
328 animate();
329 }
330 function getSlideTransformEl(slideEl) {
331 return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl;
332 }
333 function elementChildren(element, selector) {
334 if (selector === void 0) {
335 selector = '';
336 }
337 return [...element.children].filter(el => el.matches(selector));
338 }
339 function createElement(tag, classes) {
340 if (classes === void 0) {
341 classes = [];
342 }
343 const el = document.createElement(tag);
344 el.classList.add(...(Array.isArray(classes) ? classes : [classes]));
345 return el;
346 }
347 function elementOffset(el) {
348 const window = getWindow();
349 const document = getDocument();
350 const box = el.getBoundingClientRect();
351 const body = document.body;
352 const clientTop = el.clientTop || body.clientTop || 0;
353 const clientLeft = el.clientLeft || body.clientLeft || 0;
354 const scrollTop = el === window ? window.scrollY : el.scrollTop;
355 const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
356 return {
357 top: box.top + scrollTop - clientTop,
358 left: box.left + scrollLeft - clientLeft
359 };
360 }
361 function elementPrevAll(el, selector) {
362 const prevEls = [];
363 while (el.previousElementSibling) {
364 const prev = el.previousElementSibling; // eslint-disable-line
365 if (selector) {
366 if (prev.matches(selector)) prevEls.push(prev);
367 } else prevEls.push(prev);
368 el = prev;
369 }
370 return prevEls;
371 }
372 function elementNextAll(el, selector) {
373 const nextEls = [];
374 while (el.nextElementSibling) {
375 const next = el.nextElementSibling; // eslint-disable-line
376 if (selector) {
377 if (next.matches(selector)) nextEls.push(next);
378 } else nextEls.push(next);
379 el = next;
380 }
381 return nextEls;
382 }
383 function elementStyle(el, prop) {
384 const window = getWindow();
385 return window.getComputedStyle(el, null).getPropertyValue(prop);
386 }
387 function elementIndex(el) {
388 let child = el;
389 let i;
390 if (child) {
391 i = 0;
392 // eslint-disable-next-line
393 while ((child = child.previousSibling) !== null) {
394 if (child.nodeType === 1) i += 1;
395 }
396 return i;
397 }
398 return undefined;
399 }
400 function elementParents(el, selector) {
401 const parents = []; // eslint-disable-line
402 let parent = el.parentElement; // eslint-disable-line
403 while (parent) {
404 if (selector) {
405 if (parent.matches(selector)) parents.push(parent);
406 } else {
407 parents.push(parent);
408 }
409 parent = parent.parentElement;
410 }
411 return parents;
412 }
413 function elementTransitionEnd(el, callback) {
414 function fireCallBack(e) {
415 if (e.target !== el) return;
416 callback.call(el, e);
417 el.removeEventListener('transitionend', fireCallBack);
418 }
419 if (callback) {
420 el.addEventListener('transitionend', fireCallBack);
421 }
422 }
423 function elementOuterSize(el, size, includeMargins) {
424 const window = getWindow();
425 if (includeMargins) {
426 return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
427 }
428 return el.offsetWidth;
429 }
430
431 let support;
432 function calcSupport() {
433 const window = getWindow();
434 const document = getDocument();
435 return {
436 smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
437 touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
438 };
439 }
440 function getSupport() {
441 if (!support) {
442 support = calcSupport();
443 }
444 return support;
445 }
446
447 let deviceCached;
448 function calcDevice(_temp) {
449 let {
450 userAgent
451 } = _temp === void 0 ? {} : _temp;
452 const support = getSupport();
453 const window = getWindow();
454 const platform = window.navigator.platform;
455 const ua = userAgent || window.navigator.userAgent;
456 const device = {
457 ios: false,
458 android: false
459 };
460 const screenWidth = window.screen.width;
461 const screenHeight = window.screen.height;
462 const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
463 let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
464 const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
465 const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
466 const windows = platform === 'Win32';
467 let macos = platform === 'MacIntel';
468
469 // iPadOs 13 fix
470 const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
471 if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
472 ipad = ua.match(/(Version)\/([\d.]+)/);
473 if (!ipad) ipad = [0, 1, '13_0_0'];
474 macos = false;
475 }
476
477 // Android
478 if (android && !windows) {
479 device.os = 'android';
480 device.android = true;
481 }
482 if (ipad || iphone || ipod) {
483 device.os = 'ios';
484 device.ios = true;
485 }
486
487 // Export object
488 return device;
489 }
490 function getDevice(overrides) {
491 if (overrides === void 0) {
492 overrides = {};
493 }
494 if (!deviceCached) {
495 deviceCached = calcDevice(overrides);
496 }
497 return deviceCached;
498 }
499
500 let browser;
501 function calcBrowser() {
502 const window = getWindow();
503 let needPerspectiveFix = false;
504 function isSafari() {
505 const ua = window.navigator.userAgent.toLowerCase();
506 return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
507 }
508 if (isSafari()) {
509 const ua = String(window.navigator.userAgent);
510 if (ua.includes('Version/')) {
511 const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
512 needPerspectiveFix = major < 16 || major === 16 && minor < 2;
513 }
514 }
515 return {
516 isSafari: needPerspectiveFix || isSafari(),
517 needPerspectiveFix,
518 isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent)
519 };
520 }
521 function getBrowser() {
522 if (!browser) {
523 browser = calcBrowser();
524 }
525 return browser;
526 }
527
528 function Resize(_ref) {
529 let {
530 swiper,
531 on,
532 emit
533 } = _ref;
534 const window = getWindow();
535 let observer = null;
536 let animationFrame = null;
537 const resizeHandler = () => {
538 if (!swiper || swiper.destroyed || !swiper.initialized) return;
539 emit('beforeResize');
540 emit('resize');
541 };
542 const createObserver = () => {
543 if (!swiper || swiper.destroyed || !swiper.initialized) return;
544 observer = new ResizeObserver(entries => {
545 animationFrame = window.requestAnimationFrame(() => {
546 const {
547 width,
548 height
549 } = swiper;
550 let newWidth = width;
551 let newHeight = height;
552 entries.forEach(_ref2 => {
553 let {
554 contentBoxSize,
555 contentRect,
556 target
557 } = _ref2;
558 if (target && target !== swiper.el) return;
559 newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
560 newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
561 });
562 if (newWidth !== width || newHeight !== height) {
563 resizeHandler();
564 }
565 });
566 });
567 observer.observe(swiper.el);
568 };
569 const removeObserver = () => {
570 if (animationFrame) {
571 window.cancelAnimationFrame(animationFrame);
572 }
573 if (observer && observer.unobserve && swiper.el) {
574 observer.unobserve(swiper.el);
575 observer = null;
576 }
577 };
578 const orientationChangeHandler = () => {
579 if (!swiper || swiper.destroyed || !swiper.initialized) return;
580 emit('orientationchange');
581 };
582 on('init', () => {
583 if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
584 createObserver();
585 return;
586 }
587 window.addEventListener('resize', resizeHandler);
588 window.addEventListener('orientationchange', orientationChangeHandler);
589 });
590 on('destroy', () => {
591 removeObserver();
592 window.removeEventListener('resize', resizeHandler);
593 window.removeEventListener('orientationchange', orientationChangeHandler);
594 });
595 }
596
597 function Observer(_ref) {
598 let {
599 swiper,
600 extendParams,
601 on,
602 emit
603 } = _ref;
604 const observers = [];
605 const window = getWindow();
606 const attach = function (target, options) {
607 if (options === void 0) {
608 options = {};
609 }
610 const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
611 const observer = new ObserverFunc(mutations => {
612 // The observerUpdate event should only be triggered
613 // once despite the number of mutations. Additional
614 // triggers are redundant and are very costly
615 if (swiper.__preventObserver__) return;
616 if (mutations.length === 1) {
617 emit('observerUpdate', mutations[0]);
618 return;
619 }
620 const observerUpdate = function observerUpdate() {
621 emit('observerUpdate', mutations[0]);
622 };
623 if (window.requestAnimationFrame) {
624 window.requestAnimationFrame(observerUpdate);
625 } else {
626 window.setTimeout(observerUpdate, 0);
627 }
628 });
629 observer.observe(target, {
630 attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
631 childList: typeof options.childList === 'undefined' ? true : options.childList,
632 characterData: typeof options.characterData === 'undefined' ? true : options.characterData
633 });
634 observers.push(observer);
635 };
636 const init = () => {
637 if (!swiper.params.observer) return;
638 if (swiper.params.observeParents) {
639 const containerParents = elementParents(swiper.el);
640 for (let i = 0; i < containerParents.length; i += 1) {
641 attach(containerParents[i]);
642 }
643 }
644 // Observe container
645 attach(swiper.el, {
646 childList: swiper.params.observeSlideChildren
647 });
648
649 // Observe wrapper
650 attach(swiper.wrapperEl, {
651 attributes: false
652 });
653 };
654 const destroy = () => {
655 observers.forEach(observer => {
656 observer.disconnect();
657 });
658 observers.splice(0, observers.length);
659 };
660 extendParams({
661 observer: false,
662 observeParents: false,
663 observeSlideChildren: false
664 });
665 on('init', init);
666 on('destroy', destroy);
667 }
668
669 /* eslint-disable no-underscore-dangle */
670
671 var eventsEmitter = {
672 on(events, handler, priority) {
673 const self = this;
674 if (!self.eventsListeners || self.destroyed) return self;
675 if (typeof handler !== 'function') return self;
676 const method = priority ? 'unshift' : 'push';
677 events.split(' ').forEach(event => {
678 if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
679 self.eventsListeners[event][method](handler);
680 });
681 return self;
682 },
683 once(events, handler, priority) {
684 const self = this;
685 if (!self.eventsListeners || self.destroyed) return self;
686 if (typeof handler !== 'function') return self;
687 function onceHandler() {
688 self.off(events, onceHandler);
689 if (onceHandler.__emitterProxy) {
690 delete onceHandler.__emitterProxy;
691 }
692 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
693 args[_key] = arguments[_key];
694 }
695 handler.apply(self, args);
696 }
697 onceHandler.__emitterProxy = handler;
698 return self.on(events, onceHandler, priority);
699 },
700 onAny(handler, priority) {
701 const self = this;
702 if (!self.eventsListeners || self.destroyed) return self;
703 if (typeof handler !== 'function') return self;
704 const method = priority ? 'unshift' : 'push';
705 if (self.eventsAnyListeners.indexOf(handler) < 0) {
706 self.eventsAnyListeners[method](handler);
707 }
708 return self;
709 },
710 offAny(handler) {
711 const self = this;
712 if (!self.eventsListeners || self.destroyed) return self;
713 if (!self.eventsAnyListeners) return self;
714 const index = self.eventsAnyListeners.indexOf(handler);
715 if (index >= 0) {
716 self.eventsAnyListeners.splice(index, 1);
717 }
718 return self;
719 },
720 off(events, handler) {
721 const self = this;
722 if (!self.eventsListeners || self.destroyed) return self;
723 if (!self.eventsListeners) return self;
724 events.split(' ').forEach(event => {
725 if (typeof handler === 'undefined') {
726 self.eventsListeners[event] = [];
727 } else if (self.eventsListeners[event]) {
728 self.eventsListeners[event].forEach((eventHandler, index) => {
729 if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
730 self.eventsListeners[event].splice(index, 1);
731 }
732 });
733 }
734 });
735 return self;
736 },
737 emit() {
738 const self = this;
739 if (!self.eventsListeners || self.destroyed) return self;
740 if (!self.eventsListeners) return self;
741 let events;
742 let data;
743 let context;
744 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
745 args[_key2] = arguments[_key2];
746 }
747 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
748 events = args[0];
749 data = args.slice(1, args.length);
750 context = self;
751 } else {
752 events = args[0].events;
753 data = args[0].data;
754 context = args[0].context || self;
755 }
756 data.unshift(context);
757 const eventsArray = Array.isArray(events) ? events : events.split(' ');
758 eventsArray.forEach(event => {
759 if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
760 self.eventsAnyListeners.forEach(eventHandler => {
761 eventHandler.apply(context, [event, ...data]);
762 });
763 }
764 if (self.eventsListeners && self.eventsListeners[event]) {
765 self.eventsListeners[event].forEach(eventHandler => {
766 eventHandler.apply(context, data);
767 });
768 }
769 });
770 return self;
771 }
772 };
773
774 function updateSize() {
775 const swiper = this;
776 let width;
777 let height;
778 const el = swiper.el;
779 if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
780 width = swiper.params.width;
781 } else {
782 width = el.clientWidth;
783 }
784 if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
785 height = swiper.params.height;
786 } else {
787 height = el.clientHeight;
788 }
789 if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
790 return;
791 }
792
793 // Subtract paddings
794 width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
795 height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
796 if (Number.isNaN(width)) width = 0;
797 if (Number.isNaN(height)) height = 0;
798 Object.assign(swiper, {
799 width,
800 height,
801 size: swiper.isHorizontal() ? width : height
802 });
803 }
804
805 function updateSlides() {
806 const swiper = this;
807 function getDirectionLabel(property) {
808 if (swiper.isHorizontal()) {
809 return property;
810 }
811 // prettier-ignore
812 return {
813 'width': 'height',
814 'margin-top': 'margin-left',
815 'margin-bottom ': 'margin-right',
816 'margin-left': 'margin-top',
817 'margin-right': 'margin-bottom',
818 'padding-left': 'padding-top',
819 'padding-right': 'padding-bottom',
820 'marginRight': 'marginBottom'
821 }[property];
822 }
823 function getDirectionPropertyValue(node, label) {
824 return parseFloat(node.getPropertyValue(getDirectionLabel(label)) || 0);
825 }
826 const params = swiper.params;
827 const {
828 wrapperEl,
829 slidesEl,
830 size: swiperSize,
831 rtlTranslate: rtl,
832 wrongRTL
833 } = swiper;
834 const isVirtual = swiper.virtual && params.virtual.enabled;
835 const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
836 const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
837 const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
838 let snapGrid = [];
839 const slidesGrid = [];
840 const slidesSizesGrid = [];
841 let offsetBefore = params.slidesOffsetBefore;
842 if (typeof offsetBefore === 'function') {
843 offsetBefore = params.slidesOffsetBefore.call(swiper);
844 }
845 let offsetAfter = params.slidesOffsetAfter;
846 if (typeof offsetAfter === 'function') {
847 offsetAfter = params.slidesOffsetAfter.call(swiper);
848 }
849 const previousSnapGridLength = swiper.snapGrid.length;
850 const previousSlidesGridLength = swiper.slidesGrid.length;
851 let spaceBetween = params.spaceBetween;
852 let slidePosition = -offsetBefore;
853 let prevSlideSize = 0;
854 let index = 0;
855 if (typeof swiperSize === 'undefined') {
856 return;
857 }
858 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
859 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
860 } else if (typeof spaceBetween === 'string') {
861 spaceBetween = parseFloat(spaceBetween);
862 }
863 swiper.virtualSize = -spaceBetween;
864
865 // reset margins
866 slides.forEach(slideEl => {
867 if (rtl) {
868 slideEl.style.marginLeft = '';
869 } else {
870 slideEl.style.marginRight = '';
871 }
872 slideEl.style.marginBottom = '';
873 slideEl.style.marginTop = '';
874 });
875
876 // reset cssMode offsets
877 if (params.centeredSlides && params.cssMode) {
878 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
879 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
880 }
881 const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
882 if (gridEnabled) {
883 swiper.grid.initSlides(slidesLength);
884 }
885
886 // Calc slides
887 let slideSize;
888 const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
889 return typeof params.breakpoints[key].slidesPerView !== 'undefined';
890 }).length > 0;
891 for (let i = 0; i < slidesLength; i += 1) {
892 slideSize = 0;
893 let slide;
894 if (slides[i]) slide = slides[i];
895 if (gridEnabled) {
896 swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);
897 }
898 if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
899
900 if (params.slidesPerView === 'auto') {
901 if (shouldResetSlideSize) {
902 slides[i].style[getDirectionLabel('width')] = ``;
903 }
904 const slideStyles = getComputedStyle(slide);
905 const currentTransform = slide.style.transform;
906 const currentWebKitTransform = slide.style.webkitTransform;
907 if (currentTransform) {
908 slide.style.transform = 'none';
909 }
910 if (currentWebKitTransform) {
911 slide.style.webkitTransform = 'none';
912 }
913 if (params.roundLengths) {
914 slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
915 } else {
916 // eslint-disable-next-line
917 const width = getDirectionPropertyValue(slideStyles, 'width');
918 const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
919 const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
920 const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
921 const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
922 const boxSizing = slideStyles.getPropertyValue('box-sizing');
923 if (boxSizing && boxSizing === 'border-box') {
924 slideSize = width + marginLeft + marginRight;
925 } else {
926 const {
927 clientWidth,
928 offsetWidth
929 } = slide;
930 slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
931 }
932 }
933 if (currentTransform) {
934 slide.style.transform = currentTransform;
935 }
936 if (currentWebKitTransform) {
937 slide.style.webkitTransform = currentWebKitTransform;
938 }
939 if (params.roundLengths) slideSize = Math.floor(slideSize);
940 } else {
941 slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
942 if (params.roundLengths) slideSize = Math.floor(slideSize);
943 if (slides[i]) {
944 slides[i].style[getDirectionLabel('width')] = `${slideSize}px`;
945 }
946 }
947 if (slides[i]) {
948 slides[i].swiperSlideSize = slideSize;
949 }
950 slidesSizesGrid.push(slideSize);
951 if (params.centeredSlides) {
952 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
953 if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
954 if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
955 if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
956 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
957 if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
958 slidesGrid.push(slidePosition);
959 } else {
960 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
961 if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
962 slidesGrid.push(slidePosition);
963 slidePosition = slidePosition + slideSize + spaceBetween;
964 }
965 swiper.virtualSize += slideSize + spaceBetween;
966 prevSlideSize = slideSize;
967 index += 1;
968 }
969 swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
970 if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
971 wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
972 }
973 if (params.setWrapperSize) {
974 wrapperEl.style[getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
975 }
976 if (gridEnabled) {
977 swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel);
978 }
979
980 // Remove last grid elements depending on width
981 if (!params.centeredSlides) {
982 const newSlidesGrid = [];
983 for (let i = 0; i < snapGrid.length; i += 1) {
984 let slidesGridItem = snapGrid[i];
985 if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
986 if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
987 newSlidesGrid.push(slidesGridItem);
988 }
989 }
990 snapGrid = newSlidesGrid;
991 if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
992 snapGrid.push(swiper.virtualSize - swiperSize);
993 }
994 }
995 if (isVirtual && params.loop) {
996 const size = slidesSizesGrid[0] + spaceBetween;
997 if (params.slidesPerGroup > 1) {
998 const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
999 const groupSize = size * params.slidesPerGroup;
1000 for (let i = 0; i < groups; i += 1) {
1001 snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
1002 }
1003 }
1004 for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
1005 if (params.slidesPerGroup === 1) {
1006 snapGrid.push(snapGrid[snapGrid.length - 1] + size);
1007 }
1008 slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
1009 swiper.virtualSize += size;
1010 }
1011 }
1012 if (snapGrid.length === 0) snapGrid = [0];
1013 if (spaceBetween !== 0) {
1014 const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');
1015 slides.filter((_, slideIndex) => {
1016 if (!params.cssMode || params.loop) return true;
1017 if (slideIndex === slides.length - 1) {
1018 return false;
1019 }
1020 return true;
1021 }).forEach(slideEl => {
1022 slideEl.style[key] = `${spaceBetween}px`;
1023 });
1024 }
1025 if (params.centeredSlides && params.centeredSlidesBounds) {
1026 let allSlidesSize = 0;
1027 slidesSizesGrid.forEach(slideSizeValue => {
1028 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1029 });
1030 allSlidesSize -= spaceBetween;
1031 const maxSnap = allSlidesSize - swiperSize;
1032 snapGrid = snapGrid.map(snap => {
1033 if (snap <= 0) return -offsetBefore;
1034 if (snap > maxSnap) return maxSnap + offsetAfter;
1035 return snap;
1036 });
1037 }
1038 if (params.centerInsufficientSlides) {
1039 let allSlidesSize = 0;
1040 slidesSizesGrid.forEach(slideSizeValue => {
1041 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1042 });
1043 allSlidesSize -= spaceBetween;
1044 if (allSlidesSize < swiperSize) {
1045 const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
1046 snapGrid.forEach((snap, snapIndex) => {
1047 snapGrid[snapIndex] = snap - allSlidesOffset;
1048 });
1049 slidesGrid.forEach((snap, snapIndex) => {
1050 slidesGrid[snapIndex] = snap + allSlidesOffset;
1051 });
1052 }
1053 }
1054 Object.assign(swiper, {
1055 slides,
1056 snapGrid,
1057 slidesGrid,
1058 slidesSizesGrid
1059 });
1060 if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
1061 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
1062 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
1063 const addToSnapGrid = -swiper.snapGrid[0];
1064 const addToSlidesGrid = -swiper.slidesGrid[0];
1065 swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
1066 swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
1067 }
1068 if (slidesLength !== previousSlidesLength) {
1069 swiper.emit('slidesLengthChange');
1070 }
1071 if (snapGrid.length !== previousSnapGridLength) {
1072 if (swiper.params.watchOverflow) swiper.checkOverflow();
1073 swiper.emit('snapGridLengthChange');
1074 }
1075 if (slidesGrid.length !== previousSlidesGridLength) {
1076 swiper.emit('slidesGridLengthChange');
1077 }
1078 if (params.watchSlidesProgress) {
1079 swiper.updateSlidesOffset();
1080 }
1081 if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
1082 const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
1083 const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
1084 if (slidesLength <= params.maxBackfaceHiddenSlides) {
1085 if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
1086 } else if (hasClassBackfaceClassAdded) {
1087 swiper.el.classList.remove(backFaceHiddenClass);
1088 }
1089 }
1090 }
1091
1092 function updateAutoHeight(speed) {
1093 const swiper = this;
1094 const activeSlides = [];
1095 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1096 let newHeight = 0;
1097 let i;
1098 if (typeof speed === 'number') {
1099 swiper.setTransition(speed);
1100 } else if (speed === true) {
1101 swiper.setTransition(swiper.params.speed);
1102 }
1103 const getSlideByIndex = index => {
1104 if (isVirtual) {
1105 return swiper.slides[swiper.getSlideIndexByData(index)];
1106 }
1107 return swiper.slides[index];
1108 };
1109 // Find slides currently in view
1110 if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1111 if (swiper.params.centeredSlides) {
1112 (swiper.visibleSlides || []).forEach(slide => {
1113 activeSlides.push(slide);
1114 });
1115 } else {
1116 for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1117 const index = swiper.activeIndex + i;
1118 if (index > swiper.slides.length && !isVirtual) break;
1119 activeSlides.push(getSlideByIndex(index));
1120 }
1121 }
1122 } else {
1123 activeSlides.push(getSlideByIndex(swiper.activeIndex));
1124 }
1125
1126 // Find new height from highest slide in view
1127 for (i = 0; i < activeSlides.length; i += 1) {
1128 if (typeof activeSlides[i] !== 'undefined') {
1129 const height = activeSlides[i].offsetHeight;
1130 newHeight = height > newHeight ? height : newHeight;
1131 }
1132 }
1133
1134 // Update Height
1135 if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
1136 }
1137
1138 function updateSlidesOffset() {
1139 const swiper = this;
1140 const slides = swiper.slides;
1141 // eslint-disable-next-line
1142 const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
1143 for (let i = 0; i < slides.length; i += 1) {
1144 slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
1145 }
1146 }
1147
1148 function updateSlidesProgress(translate) {
1149 if (translate === void 0) {
1150 translate = this && this.translate || 0;
1151 }
1152 const swiper = this;
1153 const params = swiper.params;
1154 const {
1155 slides,
1156 rtlTranslate: rtl,
1157 snapGrid
1158 } = swiper;
1159 if (slides.length === 0) return;
1160 if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
1161 let offsetCenter = -translate;
1162 if (rtl) offsetCenter = translate;
1163
1164 // Visible Slides
1165 slides.forEach(slideEl => {
1166 slideEl.classList.remove(params.slideVisibleClass);
1167 });
1168 swiper.visibleSlidesIndexes = [];
1169 swiper.visibleSlides = [];
1170 let spaceBetween = params.spaceBetween;
1171 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
1172 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
1173 } else if (typeof spaceBetween === 'string') {
1174 spaceBetween = parseFloat(spaceBetween);
1175 }
1176 for (let i = 0; i < slides.length; i += 1) {
1177 const slide = slides[i];
1178 let slideOffset = slide.swiperSlideOffset;
1179 if (params.cssMode && params.centeredSlides) {
1180 slideOffset -= slides[0].swiperSlideOffset;
1181 }
1182 const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1183 const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1184 const slideBefore = -(offsetCenter - slideOffset);
1185 const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
1186 const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
1187 if (isVisible) {
1188 swiper.visibleSlides.push(slide);
1189 swiper.visibleSlidesIndexes.push(i);
1190 slides[i].classList.add(params.slideVisibleClass);
1191 }
1192 slide.progress = rtl ? -slideProgress : slideProgress;
1193 slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
1194 }
1195 }
1196
1197 function updateProgress(translate) {
1198 const swiper = this;
1199 if (typeof translate === 'undefined') {
1200 const multiplier = swiper.rtlTranslate ? -1 : 1;
1201 // eslint-disable-next-line
1202 translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
1203 }
1204 const params = swiper.params;
1205 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1206 let {
1207 progress,
1208 isBeginning,
1209 isEnd,
1210 progressLoop
1211 } = swiper;
1212 const wasBeginning = isBeginning;
1213 const wasEnd = isEnd;
1214 if (translatesDiff === 0) {
1215 progress = 0;
1216 isBeginning = true;
1217 isEnd = true;
1218 } else {
1219 progress = (translate - swiper.minTranslate()) / translatesDiff;
1220 const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
1221 const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
1222 isBeginning = isBeginningRounded || progress <= 0;
1223 isEnd = isEndRounded || progress >= 1;
1224 if (isBeginningRounded) progress = 0;
1225 if (isEndRounded) progress = 1;
1226 }
1227 if (params.loop) {
1228 const firstSlideIndex = swiper.getSlideIndexByData(0);
1229 const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
1230 const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
1231 const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
1232 const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
1233 const translateAbs = Math.abs(translate);
1234 if (translateAbs >= firstSlideTranslate) {
1235 progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
1236 } else {
1237 progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
1238 }
1239 if (progressLoop > 1) progressLoop -= 1;
1240 }
1241 Object.assign(swiper, {
1242 progress,
1243 progressLoop,
1244 isBeginning,
1245 isEnd
1246 });
1247 if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
1248 if (isBeginning && !wasBeginning) {
1249 swiper.emit('reachBeginning toEdge');
1250 }
1251 if (isEnd && !wasEnd) {
1252 swiper.emit('reachEnd toEdge');
1253 }
1254 if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
1255 swiper.emit('fromEdge');
1256 }
1257 swiper.emit('progress', progress);
1258 }
1259
1260 function updateSlidesClasses() {
1261 const swiper = this;
1262 const {
1263 slides,
1264 params,
1265 slidesEl,
1266 activeIndex
1267 } = swiper;
1268 const isVirtual = swiper.virtual && params.virtual.enabled;
1269 const getFilteredSlide = selector => {
1270 return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
1271 };
1272 slides.forEach(slideEl => {
1273 slideEl.classList.remove(params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
1274 });
1275 let activeSlide;
1276 if (isVirtual) {
1277 if (params.loop) {
1278 let slideIndex = activeIndex - swiper.virtual.slidesBefore;
1279 if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
1280 if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
1281 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
1282 } else {
1283 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
1284 }
1285 } else {
1286 activeSlide = slides[activeIndex];
1287 }
1288 if (activeSlide) {
1289 // Active classes
1290 activeSlide.classList.add(params.slideActiveClass);
1291
1292 // Next Slide
1293 let nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1294 if (params.loop && !nextSlide) {
1295 nextSlide = slides[0];
1296 }
1297 if (nextSlide) {
1298 nextSlide.classList.add(params.slideNextClass);
1299 }
1300 // Prev Slide
1301 let prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1302 if (params.loop && !prevSlide === 0) {
1303 prevSlide = slides[slides.length - 1];
1304 }
1305 if (prevSlide) {
1306 prevSlide.classList.add(params.slidePrevClass);
1307 }
1308 }
1309 swiper.emitSlidesClasses();
1310 }
1311
1312 const processLazyPreloader = (swiper, imageEl) => {
1313 if (!swiper || swiper.destroyed || !swiper.params) return;
1314 const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
1315 const slideEl = imageEl.closest(slideSelector());
1316 if (slideEl) {
1317 const lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1318 if (lazyEl) lazyEl.remove();
1319 }
1320 };
1321 const unlazy = (swiper, index) => {
1322 if (!swiper.slides[index]) return;
1323 const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
1324 if (imageEl) imageEl.removeAttribute('loading');
1325 };
1326 const preload = swiper => {
1327 if (!swiper || swiper.destroyed || !swiper.params) return;
1328 let amount = swiper.params.lazyPreloadPrevNext;
1329 const len = swiper.slides.length;
1330 if (!len || !amount || amount < 0) return;
1331 amount = Math.min(amount, len);
1332 const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
1333 const activeIndex = swiper.activeIndex;
1334 if (swiper.params.grid && swiper.params.grid.rows > 1) {
1335 const activeColumn = activeIndex;
1336 const preloadColumns = [activeColumn - amount];
1337 preloadColumns.push(...Array.from({
1338 length: amount
1339 }).map((_, i) => {
1340 return activeColumn + slidesPerView + i;
1341 }));
1342 swiper.slides.forEach((slideEl, i) => {
1343 if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
1344 });
1345 return;
1346 }
1347 const slideIndexLastInView = activeIndex + slidesPerView - 1;
1348 if (swiper.params.rewind || swiper.params.loop) {
1349 for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
1350 const realIndex = (i % len + len) % len;
1351 if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
1352 }
1353 } else {
1354 for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
1355 if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
1356 unlazy(swiper, i);
1357 }
1358 }
1359 }
1360 };
1361
1362 function getActiveIndexByTranslate(swiper) {
1363 const {
1364 slidesGrid,
1365 params
1366 } = swiper;
1367 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1368 let activeIndex;
1369 for (let i = 0; i < slidesGrid.length; i += 1) {
1370 if (typeof slidesGrid[i + 1] !== 'undefined') {
1371 if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
1372 activeIndex = i;
1373 } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
1374 activeIndex = i + 1;
1375 }
1376 } else if (translate >= slidesGrid[i]) {
1377 activeIndex = i;
1378 }
1379 }
1380 // Normalize slideIndex
1381 if (params.normalizeSlideIndex) {
1382 if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1383 }
1384 return activeIndex;
1385 }
1386 function updateActiveIndex(newActiveIndex) {
1387 const swiper = this;
1388 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1389 const {
1390 snapGrid,
1391 params,
1392 activeIndex: previousIndex,
1393 realIndex: previousRealIndex,
1394 snapIndex: previousSnapIndex
1395 } = swiper;
1396 let activeIndex = newActiveIndex;
1397 let snapIndex;
1398 const getVirtualRealIndex = aIndex => {
1399 let realIndex = aIndex - swiper.virtual.slidesBefore;
1400 if (realIndex < 0) {
1401 realIndex = swiper.virtual.slides.length + realIndex;
1402 }
1403 if (realIndex >= swiper.virtual.slides.length) {
1404 realIndex -= swiper.virtual.slides.length;
1405 }
1406 return realIndex;
1407 };
1408 if (typeof activeIndex === 'undefined') {
1409 activeIndex = getActiveIndexByTranslate(swiper);
1410 }
1411 if (snapGrid.indexOf(translate) >= 0) {
1412 snapIndex = snapGrid.indexOf(translate);
1413 } else {
1414 const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
1415 snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
1416 }
1417 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1418 if (activeIndex === previousIndex) {
1419 if (snapIndex !== previousSnapIndex) {
1420 swiper.snapIndex = snapIndex;
1421 swiper.emit('snapIndexChange');
1422 }
1423 if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1424 swiper.realIndex = getVirtualRealIndex(activeIndex);
1425 }
1426 return;
1427 }
1428 // Get real index
1429 let realIndex;
1430 if (swiper.virtual && params.virtual.enabled && params.loop) {
1431 realIndex = getVirtualRealIndex(activeIndex);
1432 } else if (swiper.slides[activeIndex]) {
1433 realIndex = parseInt(swiper.slides[activeIndex].getAttribute('data-swiper-slide-index') || activeIndex, 10);
1434 } else {
1435 realIndex = activeIndex;
1436 }
1437 Object.assign(swiper, {
1438 previousSnapIndex,
1439 snapIndex,
1440 previousRealIndex,
1441 realIndex,
1442 previousIndex,
1443 activeIndex
1444 });
1445 if (swiper.initialized) {
1446 preload(swiper);
1447 }
1448 swiper.emit('activeIndexChange');
1449 swiper.emit('snapIndexChange');
1450 if (previousRealIndex !== realIndex) {
1451 swiper.emit('realIndexChange');
1452 }
1453 if (swiper.initialized || swiper.params.runCallbacksOnInit) {
1454 swiper.emit('slideChange');
1455 }
1456 }
1457
1458 function updateClickedSlide(e) {
1459 const swiper = this;
1460 const params = swiper.params;
1461 const slide = e.closest(`.${params.slideClass}, swiper-slide`);
1462 let slideFound = false;
1463 let slideIndex;
1464 if (slide) {
1465 for (let i = 0; i < swiper.slides.length; i += 1) {
1466 if (swiper.slides[i] === slide) {
1467 slideFound = true;
1468 slideIndex = i;
1469 break;
1470 }
1471 }
1472 }
1473 if (slide && slideFound) {
1474 swiper.clickedSlide = slide;
1475 if (swiper.virtual && swiper.params.virtual.enabled) {
1476 swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1477 } else {
1478 swiper.clickedIndex = slideIndex;
1479 }
1480 } else {
1481 swiper.clickedSlide = undefined;
1482 swiper.clickedIndex = undefined;
1483 return;
1484 }
1485 if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
1486 swiper.slideToClickedSlide();
1487 }
1488 }
1489
1490 var update = {
1491 updateSize,
1492 updateSlides,
1493 updateAutoHeight,
1494 updateSlidesOffset,
1495 updateSlidesProgress,
1496 updateProgress,
1497 updateSlidesClasses,
1498 updateActiveIndex,
1499 updateClickedSlide
1500 };
1501
1502 function getSwiperTranslate(axis) {
1503 if (axis === void 0) {
1504 axis = this.isHorizontal() ? 'x' : 'y';
1505 }
1506 const swiper = this;
1507 const {
1508 params,
1509 rtlTranslate: rtl,
1510 translate,
1511 wrapperEl
1512 } = swiper;
1513 if (params.virtualTranslate) {
1514 return rtl ? -translate : translate;
1515 }
1516 if (params.cssMode) {
1517 return translate;
1518 }
1519 let currentTranslate = getTranslate(wrapperEl, axis);
1520 currentTranslate += swiper.cssOverflowAdjustment();
1521 if (rtl) currentTranslate = -currentTranslate;
1522 return currentTranslate || 0;
1523 }
1524
1525 function setTranslate(translate, byController) {
1526 const swiper = this;
1527 const {
1528 rtlTranslate: rtl,
1529 params,
1530 wrapperEl,
1531 progress
1532 } = swiper;
1533 let x = 0;
1534 let y = 0;
1535 const z = 0;
1536 if (swiper.isHorizontal()) {
1537 x = rtl ? -translate : translate;
1538 } else {
1539 y = translate;
1540 }
1541 if (params.roundLengths) {
1542 x = Math.floor(x);
1543 y = Math.floor(y);
1544 }
1545 swiper.previousTranslate = swiper.translate;
1546 swiper.translate = swiper.isHorizontal() ? x : y;
1547 if (params.cssMode) {
1548 wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1549 } else if (!params.virtualTranslate) {
1550 if (swiper.isHorizontal()) {
1551 x -= swiper.cssOverflowAdjustment();
1552 } else {
1553 y -= swiper.cssOverflowAdjustment();
1554 }
1555 wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
1556 }
1557
1558 // Check if we need to update progress
1559 let newProgress;
1560 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1561 if (translatesDiff === 0) {
1562 newProgress = 0;
1563 } else {
1564 newProgress = (translate - swiper.minTranslate()) / translatesDiff;
1565 }
1566 if (newProgress !== progress) {
1567 swiper.updateProgress(translate);
1568 }
1569 swiper.emit('setTranslate', swiper.translate, byController);
1570 }
1571
1572 function minTranslate() {
1573 return -this.snapGrid[0];
1574 }
1575
1576 function maxTranslate() {
1577 return -this.snapGrid[this.snapGrid.length - 1];
1578 }
1579
1580 function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
1581 if (translate === void 0) {
1582 translate = 0;
1583 }
1584 if (speed === void 0) {
1585 speed = this.params.speed;
1586 }
1587 if (runCallbacks === void 0) {
1588 runCallbacks = true;
1589 }
1590 if (translateBounds === void 0) {
1591 translateBounds = true;
1592 }
1593 const swiper = this;
1594 const {
1595 params,
1596 wrapperEl
1597 } = swiper;
1598 if (swiper.animating && params.preventInteractionOnTransition) {
1599 return false;
1600 }
1601 const minTranslate = swiper.minTranslate();
1602 const maxTranslate = swiper.maxTranslate();
1603 let newTranslate;
1604 if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
1605
1606 // Update progress
1607 swiper.updateProgress(newTranslate);
1608 if (params.cssMode) {
1609 const isH = swiper.isHorizontal();
1610 if (speed === 0) {
1611 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1612 } else {
1613 if (!swiper.support.smoothScroll) {
1614 animateCSSModeScroll({
1615 swiper,
1616 targetPosition: -newTranslate,
1617 side: isH ? 'left' : 'top'
1618 });
1619 return true;
1620 }
1621 wrapperEl.scrollTo({
1622 [isH ? 'left' : 'top']: -newTranslate,
1623 behavior: 'smooth'
1624 });
1625 }
1626 return true;
1627 }
1628 if (speed === 0) {
1629 swiper.setTransition(0);
1630 swiper.setTranslate(newTranslate);
1631 if (runCallbacks) {
1632 swiper.emit('beforeTransitionStart', speed, internal);
1633 swiper.emit('transitionEnd');
1634 }
1635 } else {
1636 swiper.setTransition(speed);
1637 swiper.setTranslate(newTranslate);
1638 if (runCallbacks) {
1639 swiper.emit('beforeTransitionStart', speed, internal);
1640 swiper.emit('transitionStart');
1641 }
1642 if (!swiper.animating) {
1643 swiper.animating = true;
1644 if (!swiper.onTranslateToWrapperTransitionEnd) {
1645 swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
1646 if (!swiper || swiper.destroyed) return;
1647 if (e.target !== this) return;
1648 swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1649 swiper.onTranslateToWrapperTransitionEnd = null;
1650 delete swiper.onTranslateToWrapperTransitionEnd;
1651 if (runCallbacks) {
1652 swiper.emit('transitionEnd');
1653 }
1654 };
1655 }
1656 swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1657 }
1658 }
1659 return true;
1660 }
1661
1662 var translate = {
1663 getTranslate: getSwiperTranslate,
1664 setTranslate,
1665 minTranslate,
1666 maxTranslate,
1667 translateTo
1668 };
1669
1670 function setTransition(duration, byController) {
1671 const swiper = this;
1672 if (!swiper.params.cssMode) {
1673 swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
1674 }
1675 swiper.emit('setTransition', duration, byController);
1676 }
1677
1678 function transitionEmit(_ref) {
1679 let {
1680 swiper,
1681 runCallbacks,
1682 direction,
1683 step
1684 } = _ref;
1685 const {
1686 activeIndex,
1687 previousIndex
1688 } = swiper;
1689 let dir = direction;
1690 if (!dir) {
1691 if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
1692 }
1693 swiper.emit(`transition${step}`);
1694 if (runCallbacks && activeIndex !== previousIndex) {
1695 if (dir === 'reset') {
1696 swiper.emit(`slideResetTransition${step}`);
1697 return;
1698 }
1699 swiper.emit(`slideChangeTransition${step}`);
1700 if (dir === 'next') {
1701 swiper.emit(`slideNextTransition${step}`);
1702 } else {
1703 swiper.emit(`slidePrevTransition${step}`);
1704 }
1705 }
1706 }
1707
1708 function transitionStart(runCallbacks, direction) {
1709 if (runCallbacks === void 0) {
1710 runCallbacks = true;
1711 }
1712 const swiper = this;
1713 const {
1714 params
1715 } = swiper;
1716 if (params.cssMode) return;
1717 if (params.autoHeight) {
1718 swiper.updateAutoHeight();
1719 }
1720 transitionEmit({
1721 swiper,
1722 runCallbacks,
1723 direction,
1724 step: 'Start'
1725 });
1726 }
1727
1728 function transitionEnd(runCallbacks, direction) {
1729 if (runCallbacks === void 0) {
1730 runCallbacks = true;
1731 }
1732 const swiper = this;
1733 const {
1734 params
1735 } = swiper;
1736 swiper.animating = false;
1737 if (params.cssMode) return;
1738 swiper.setTransition(0);
1739 transitionEmit({
1740 swiper,
1741 runCallbacks,
1742 direction,
1743 step: 'End'
1744 });
1745 }
1746
1747 var transition = {
1748 setTransition,
1749 transitionStart,
1750 transitionEnd
1751 };
1752
1753 function slideTo(index, speed, runCallbacks, internal, initial) {
1754 if (index === void 0) {
1755 index = 0;
1756 }
1757 if (speed === void 0) {
1758 speed = this.params.speed;
1759 }
1760 if (runCallbacks === void 0) {
1761 runCallbacks = true;
1762 }
1763 if (typeof index === 'string') {
1764 index = parseInt(index, 10);
1765 }
1766 const swiper = this;
1767 let slideIndex = index;
1768 if (slideIndex < 0) slideIndex = 0;
1769 const {
1770 params,
1771 snapGrid,
1772 slidesGrid,
1773 previousIndex,
1774 activeIndex,
1775 rtlTranslate: rtl,
1776 wrapperEl,
1777 enabled
1778 } = swiper;
1779 if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
1780 return false;
1781 }
1782 const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
1783 let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1784 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1785 const translate = -snapGrid[snapIndex];
1786 // Normalize slideIndex
1787 if (params.normalizeSlideIndex) {
1788 for (let i = 0; i < slidesGrid.length; i += 1) {
1789 const normalizedTranslate = -Math.floor(translate * 100);
1790 const normalizedGrid = Math.floor(slidesGrid[i] * 100);
1791 const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
1792 if (typeof slidesGrid[i + 1] !== 'undefined') {
1793 if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
1794 slideIndex = i;
1795 } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
1796 slideIndex = i + 1;
1797 }
1798 } else if (normalizedTranslate >= normalizedGrid) {
1799 slideIndex = i;
1800 }
1801 }
1802 }
1803 // Directions locks
1804 if (swiper.initialized && slideIndex !== activeIndex) {
1805 if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
1806 return false;
1807 }
1808 if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1809 if ((activeIndex || 0) !== slideIndex) {
1810 return false;
1811 }
1812 }
1813 }
1814 if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1815 swiper.emit('beforeSlideChangeStart');
1816 }
1817
1818 // Update progress
1819 swiper.updateProgress(translate);
1820 let direction;
1821 if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
1822
1823 // Update Index
1824 if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
1825 swiper.updateActiveIndex(slideIndex);
1826 // Update Height
1827 if (params.autoHeight) {
1828 swiper.updateAutoHeight();
1829 }
1830 swiper.updateSlidesClasses();
1831 if (params.effect !== 'slide') {
1832 swiper.setTranslate(translate);
1833 }
1834 if (direction !== 'reset') {
1835 swiper.transitionStart(runCallbacks, direction);
1836 swiper.transitionEnd(runCallbacks, direction);
1837 }
1838 return false;
1839 }
1840 if (params.cssMode) {
1841 const isH = swiper.isHorizontal();
1842 const t = rtl ? translate : -translate;
1843 if (speed === 0) {
1844 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1845 if (isVirtual) {
1846 swiper.wrapperEl.style.scrollSnapType = 'none';
1847 swiper._immediateVirtual = true;
1848 }
1849 if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1850 swiper._cssModeVirtualInitialSet = true;
1851 requestAnimationFrame(() => {
1852 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1853 });
1854 } else {
1855 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1856 }
1857 if (isVirtual) {
1858 requestAnimationFrame(() => {
1859 swiper.wrapperEl.style.scrollSnapType = '';
1860 swiper._immediateVirtual = false;
1861 });
1862 }
1863 } else {
1864 if (!swiper.support.smoothScroll) {
1865 animateCSSModeScroll({
1866 swiper,
1867 targetPosition: t,
1868 side: isH ? 'left' : 'top'
1869 });
1870 return true;
1871 }
1872 wrapperEl.scrollTo({
1873 [isH ? 'left' : 'top']: t,
1874 behavior: 'smooth'
1875 });
1876 }
1877 return true;
1878 }
1879 swiper.setTransition(speed);
1880 swiper.setTranslate(translate);
1881 swiper.updateActiveIndex(slideIndex);
1882 swiper.updateSlidesClasses();
1883 swiper.emit('beforeTransitionStart', speed, internal);
1884 swiper.transitionStart(runCallbacks, direction);
1885 if (speed === 0) {
1886 swiper.transitionEnd(runCallbacks, direction);
1887 } else if (!swiper.animating) {
1888 swiper.animating = true;
1889 if (!swiper.onSlideToWrapperTransitionEnd) {
1890 swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
1891 if (!swiper || swiper.destroyed) return;
1892 if (e.target !== this) return;
1893 swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1894 swiper.onSlideToWrapperTransitionEnd = null;
1895 delete swiper.onSlideToWrapperTransitionEnd;
1896 swiper.transitionEnd(runCallbacks, direction);
1897 };
1898 }
1899 swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1900 }
1901 return true;
1902 }
1903
1904 function slideToLoop(index, speed, runCallbacks, internal) {
1905 if (index === void 0) {
1906 index = 0;
1907 }
1908 if (speed === void 0) {
1909 speed = this.params.speed;
1910 }
1911 if (runCallbacks === void 0) {
1912 runCallbacks = true;
1913 }
1914 if (typeof index === 'string') {
1915 const indexAsNumber = parseInt(index, 10);
1916 index = indexAsNumber;
1917 }
1918 const swiper = this;
1919 let newIndex = index;
1920 if (swiper.params.loop) {
1921 if (swiper.virtual && swiper.params.virtual.enabled) {
1922 // eslint-disable-next-line
1923 newIndex = newIndex + swiper.virtual.slidesBefore;
1924 } else {
1925 newIndex = swiper.getSlideIndexByData(newIndex);
1926 }
1927 }
1928 return swiper.slideTo(newIndex, speed, runCallbacks, internal);
1929 }
1930
1931 /* eslint no-unused-vars: "off" */
1932 function slideNext(speed, runCallbacks, internal) {
1933 if (speed === void 0) {
1934 speed = this.params.speed;
1935 }
1936 if (runCallbacks === void 0) {
1937 runCallbacks = true;
1938 }
1939 const swiper = this;
1940 const {
1941 enabled,
1942 params,
1943 animating
1944 } = swiper;
1945 if (!enabled) return swiper;
1946 let perGroup = params.slidesPerGroup;
1947 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
1948 perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
1949 }
1950 const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
1951 const isVirtual = swiper.virtual && params.virtual.enabled;
1952 if (params.loop) {
1953 if (animating && !isVirtual && params.loopPreventsSliding) return false;
1954 swiper.loopFix({
1955 direction: 'next'
1956 });
1957 // eslint-disable-next-line
1958 swiper._clientLeft = swiper.wrapperEl.clientLeft;
1959 }
1960 if (params.rewind && swiper.isEnd) {
1961 return swiper.slideTo(0, speed, runCallbacks, internal);
1962 }
1963 return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
1964 }
1965
1966 /* eslint no-unused-vars: "off" */
1967 function slidePrev(speed, runCallbacks, internal) {
1968 if (speed === void 0) {
1969 speed = this.params.speed;
1970 }
1971 if (runCallbacks === void 0) {
1972 runCallbacks = true;
1973 }
1974 const swiper = this;
1975 const {
1976 params,
1977 snapGrid,
1978 slidesGrid,
1979 rtlTranslate,
1980 enabled,
1981 animating
1982 } = swiper;
1983 if (!enabled) return swiper;
1984 const isVirtual = swiper.virtual && params.virtual.enabled;
1985 if (params.loop) {
1986 if (animating && !isVirtual && params.loopPreventsSliding) return false;
1987 swiper.loopFix({
1988 direction: 'prev'
1989 });
1990 // eslint-disable-next-line
1991 swiper._clientLeft = swiper.wrapperEl.clientLeft;
1992 }
1993 const translate = rtlTranslate ? swiper.translate : -swiper.translate;
1994 function normalize(val) {
1995 if (val < 0) return -Math.floor(Math.abs(val));
1996 return Math.floor(val);
1997 }
1998 const normalizedTranslate = normalize(translate);
1999 const normalizedSnapGrid = snapGrid.map(val => normalize(val));
2000 let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2001 if (typeof prevSnap === 'undefined' && params.cssMode) {
2002 let prevSnapIndex;
2003 snapGrid.forEach((snap, snapIndex) => {
2004 if (normalizedTranslate >= snap) {
2005 // prevSnap = snap;
2006 prevSnapIndex = snapIndex;
2007 }
2008 });
2009 if (typeof prevSnapIndex !== 'undefined') {
2010 prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2011 }
2012 }
2013 let prevIndex = 0;
2014 if (typeof prevSnap !== 'undefined') {
2015 prevIndex = slidesGrid.indexOf(prevSnap);
2016 if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
2017 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2018 prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
2019 prevIndex = Math.max(prevIndex, 0);
2020 }
2021 }
2022 if (params.rewind && swiper.isBeginning) {
2023 const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2024 return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
2025 }
2026 return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2027 }
2028
2029 /* eslint no-unused-vars: "off" */
2030 function slideReset(speed, runCallbacks, internal) {
2031 if (speed === void 0) {
2032 speed = this.params.speed;
2033 }
2034 if (runCallbacks === void 0) {
2035 runCallbacks = true;
2036 }
2037 const swiper = this;
2038 return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
2039 }
2040
2041 /* eslint no-unused-vars: "off" */
2042 function slideToClosest(speed, runCallbacks, internal, threshold) {
2043 if (speed === void 0) {
2044 speed = this.params.speed;
2045 }
2046 if (runCallbacks === void 0) {
2047 runCallbacks = true;
2048 }
2049 if (threshold === void 0) {
2050 threshold = 0.5;
2051 }
2052 const swiper = this;
2053 let index = swiper.activeIndex;
2054 const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
2055 const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
2056 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
2057 if (translate >= swiper.snapGrid[snapIndex]) {
2058 // The current translate is on or after the current snap index, so the choice
2059 // is between the current index and the one after it.
2060 const currentSnap = swiper.snapGrid[snapIndex];
2061 const nextSnap = swiper.snapGrid[snapIndex + 1];
2062 if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
2063 index += swiper.params.slidesPerGroup;
2064 }
2065 } else {
2066 // The current translate is before the current snap index, so the choice
2067 // is between the current index and the one before it.
2068 const prevSnap = swiper.snapGrid[snapIndex - 1];
2069 const currentSnap = swiper.snapGrid[snapIndex];
2070 if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
2071 index -= swiper.params.slidesPerGroup;
2072 }
2073 }
2074 index = Math.max(index, 0);
2075 index = Math.min(index, swiper.slidesGrid.length - 1);
2076 return swiper.slideTo(index, speed, runCallbacks, internal);
2077 }
2078
2079 function slideToClickedSlide() {
2080 const swiper = this;
2081 const {
2082 params,
2083 slidesEl
2084 } = swiper;
2085 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2086 let slideToIndex = swiper.clickedIndex;
2087 let realIndex;
2088 const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
2089 if (params.loop) {
2090 if (swiper.animating) return;
2091 realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
2092 if (params.centeredSlides) {
2093 if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {
2094 swiper.loopFix();
2095 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2096 nextTick(() => {
2097 swiper.slideTo(slideToIndex);
2098 });
2099 } else {
2100 swiper.slideTo(slideToIndex);
2101 }
2102 } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2103 swiper.loopFix();
2104 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2105 nextTick(() => {
2106 swiper.slideTo(slideToIndex);
2107 });
2108 } else {
2109 swiper.slideTo(slideToIndex);
2110 }
2111 } else {
2112 swiper.slideTo(slideToIndex);
2113 }
2114 }
2115
2116 var slide = {
2117 slideTo,
2118 slideToLoop,
2119 slideNext,
2120 slidePrev,
2121 slideReset,
2122 slideToClosest,
2123 slideToClickedSlide
2124 };
2125
2126 function loopCreate(slideRealIndex) {
2127 const swiper = this;
2128 const {
2129 params,
2130 slidesEl
2131 } = swiper;
2132 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2133 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
2134 slides.forEach((el, index) => {
2135 el.setAttribute('data-swiper-slide-index', index);
2136 });
2137 swiper.loopFix({
2138 slideRealIndex,
2139 direction: params.centeredSlides ? undefined : 'next'
2140 });
2141 }
2142
2143 function loopFix(_temp) {
2144 let {
2145 slideRealIndex,
2146 slideTo = true,
2147 direction,
2148 setTranslate,
2149 activeSlideIndex,
2150 byController,
2151 byMousewheel
2152 } = _temp === void 0 ? {} : _temp;
2153 const swiper = this;
2154 if (!swiper.params.loop) return;
2155 swiper.emit('beforeLoopFix');
2156 const {
2157 slides,
2158 allowSlidePrev,
2159 allowSlideNext,
2160 slidesEl,
2161 params
2162 } = swiper;
2163 swiper.allowSlidePrev = true;
2164 swiper.allowSlideNext = true;
2165 if (swiper.virtual && params.virtual.enabled) {
2166 if (slideTo) {
2167 if (!params.centeredSlides && swiper.snapIndex === 0) {
2168 swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2169 } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2170 swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2171 } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2172 swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2173 }
2174 }
2175 swiper.allowSlidePrev = allowSlidePrev;
2176 swiper.allowSlideNext = allowSlideNext;
2177 swiper.emit('loopFix');
2178 return;
2179 }
2180 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
2181 let loopedSlides = params.loopedSlides || slidesPerView;
2182 if (loopedSlides % params.slidesPerGroup !== 0) {
2183 loopedSlides += params.slidesPerGroup - loopedSlides % params.slidesPerGroup;
2184 }
2185 swiper.loopedSlides = loopedSlides;
2186 const prependSlidesIndexes = [];
2187 const appendSlidesIndexes = [];
2188 let activeIndex = swiper.activeIndex;
2189 if (typeof activeSlideIndex === 'undefined') {
2190 activeSlideIndex = swiper.getSlideIndex(swiper.slides.filter(el => el.classList.contains(params.slideActiveClass))[0]);
2191 } else {
2192 activeIndex = activeSlideIndex;
2193 }
2194 const isNext = direction === 'next' || !direction;
2195 const isPrev = direction === 'prev' || !direction;
2196 let slidesPrepended = 0;
2197 let slidesAppended = 0;
2198 // prepend last slides before start
2199 if (activeSlideIndex < loopedSlides) {
2200 slidesPrepended = Math.max(loopedSlides - activeSlideIndex, params.slidesPerGroup);
2201 for (let i = 0; i < loopedSlides - activeSlideIndex; i += 1) {
2202 const index = i - Math.floor(i / slides.length) * slides.length;
2203 prependSlidesIndexes.push(slides.length - index - 1);
2204 }
2205 } else if (activeSlideIndex /* + slidesPerView */ > swiper.slides.length - loopedSlides * 2) {
2206 slidesAppended = Math.max(activeSlideIndex - (swiper.slides.length - loopedSlides * 2), params.slidesPerGroup);
2207 for (let i = 0; i < slidesAppended; i += 1) {
2208 const index = i - Math.floor(i / slides.length) * slides.length;
2209 appendSlidesIndexes.push(index);
2210 }
2211 }
2212 if (isPrev) {
2213 prependSlidesIndexes.forEach(index => {
2214 swiper.slides[index].swiperLoopMoveDOM = true;
2215 slidesEl.prepend(swiper.slides[index]);
2216 swiper.slides[index].swiperLoopMoveDOM = false;
2217 });
2218 }
2219 if (isNext) {
2220 appendSlidesIndexes.forEach(index => {
2221 swiper.slides[index].swiperLoopMoveDOM = true;
2222 slidesEl.append(swiper.slides[index]);
2223 swiper.slides[index].swiperLoopMoveDOM = false;
2224 });
2225 }
2226 swiper.recalcSlides();
2227 if (params.slidesPerView === 'auto') {
2228 swiper.updateSlides();
2229 }
2230 if (params.watchSlidesProgress) {
2231 swiper.updateSlidesOffset();
2232 }
2233 if (slideTo) {
2234 if (prependSlidesIndexes.length > 0 && isPrev) {
2235 if (typeof slideRealIndex === 'undefined') {
2236 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2237 const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
2238 const diff = newSlideTranslate - currentSlideTranslate;
2239 if (byMousewheel) {
2240 swiper.setTranslate(swiper.translate - diff);
2241 } else {
2242 swiper.slideTo(activeIndex + slidesPrepended, 0, false, true);
2243 if (setTranslate) {
2244 swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
2245 }
2246 }
2247 } else {
2248 if (setTranslate) {
2249 swiper.slideToLoop(slideRealIndex, 0, false, true);
2250 }
2251 }
2252 } else if (appendSlidesIndexes.length > 0 && isNext) {
2253 if (typeof slideRealIndex === 'undefined') {
2254 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2255 const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
2256 const diff = newSlideTranslate - currentSlideTranslate;
2257 if (byMousewheel) {
2258 swiper.setTranslate(swiper.translate - diff);
2259 } else {
2260 swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
2261 if (setTranslate) {
2262 swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
2263 }
2264 }
2265 } else {
2266 swiper.slideToLoop(slideRealIndex, 0, false, true);
2267 }
2268 }
2269 }
2270 swiper.allowSlidePrev = allowSlidePrev;
2271 swiper.allowSlideNext = allowSlideNext;
2272 if (swiper.controller && swiper.controller.control && !byController) {
2273 const loopParams = {
2274 slideRealIndex,
2275 slideTo: false,
2276 direction,
2277 setTranslate,
2278 activeSlideIndex,
2279 byController: true
2280 };
2281 if (Array.isArray(swiper.controller.control)) {
2282 swiper.controller.control.forEach(c => {
2283 if (!c.destroyed && c.params.loop) c.loopFix(loopParams);
2284 });
2285 } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2286 swiper.controller.control.loopFix(loopParams);
2287 }
2288 }
2289 swiper.emit('loopFix');
2290 }
2291
2292 function loopDestroy() {
2293 const swiper = this;
2294 const {
2295 params,
2296 slidesEl
2297 } = swiper;
2298 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2299 swiper.recalcSlides();
2300 const newSlidesOrder = [];
2301 swiper.slides.forEach(slideEl => {
2302 const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
2303 newSlidesOrder[index] = slideEl;
2304 });
2305 swiper.slides.forEach(slideEl => {
2306 slideEl.removeAttribute('data-swiper-slide-index');
2307 });
2308 newSlidesOrder.forEach(slideEl => {
2309 slidesEl.append(slideEl);
2310 });
2311 swiper.recalcSlides();
2312 swiper.slideTo(swiper.realIndex, 0);
2313 }
2314
2315 var loop = {
2316 loopCreate,
2317 loopFix,
2318 loopDestroy
2319 };
2320
2321 function setGrabCursor(moving) {
2322 const swiper = this;
2323 if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
2324 const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
2325 if (swiper.isElement) {
2326 swiper.__preventObserver__ = true;
2327 }
2328 el.style.cursor = 'move';
2329 el.style.cursor = moving ? 'grabbing' : 'grab';
2330 if (swiper.isElement) {
2331 requestAnimationFrame(() => {
2332 swiper.__preventObserver__ = false;
2333 });
2334 }
2335 }
2336
2337 function unsetGrabCursor() {
2338 const swiper = this;
2339 if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
2340 return;
2341 }
2342 if (swiper.isElement) {
2343 swiper.__preventObserver__ = true;
2344 }
2345 swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
2346 if (swiper.isElement) {
2347 requestAnimationFrame(() => {
2348 swiper.__preventObserver__ = false;
2349 });
2350 }
2351 }
2352
2353 var grabCursor = {
2354 setGrabCursor,
2355 unsetGrabCursor
2356 };
2357
2358 // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2359 function closestElement(selector, base) {
2360 if (base === void 0) {
2361 base = this;
2362 }
2363 function __closestFrom(el) {
2364 if (!el || el === getDocument() || el === getWindow()) return null;
2365 if (el.assignedSlot) el = el.assignedSlot;
2366 const found = el.closest(selector);
2367 if (!found && !el.getRootNode) {
2368 return null;
2369 }
2370 return found || __closestFrom(el.getRootNode().host);
2371 }
2372 return __closestFrom(base);
2373 }
2374 function onTouchStart(event) {
2375 const swiper = this;
2376 const document = getDocument();
2377 const window = getWindow();
2378 const data = swiper.touchEventsData;
2379 data.evCache.push(event);
2380 const {
2381 params,
2382 touches,
2383 enabled
2384 } = swiper;
2385 if (!enabled) return;
2386 if (!params.simulateTouch && event.pointerType === 'mouse') return;
2387 if (swiper.animating && params.preventInteractionOnTransition) {
2388 return;
2389 }
2390 if (!swiper.animating && params.cssMode && params.loop) {
2391 swiper.loopFix();
2392 }
2393 let e = event;
2394 if (e.originalEvent) e = e.originalEvent;
2395 let targetEl = e.target;
2396 if (params.touchEventsTarget === 'wrapper') {
2397 if (!swiper.wrapperEl.contains(targetEl)) return;
2398 }
2399 if ('which' in e && e.which === 3) return;
2400 if ('button' in e && e.button > 0) return;
2401 if (data.isTouched && data.isMoved) return;
2402
2403 // change target el for shadow root component
2404 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
2405 // eslint-disable-next-line
2406 const eventPath = event.composedPath ? event.composedPath() : event.path;
2407 if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
2408 targetEl = eventPath[0];
2409 }
2410 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
2411 const isTargetShadow = !!(e.target && e.target.shadowRoot);
2412
2413 // use closestElement for shadow root element to get the actual closest for nested shadow root element
2414 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
2415 swiper.allowClick = true;
2416 return;
2417 }
2418 if (params.swipeHandler) {
2419 if (!targetEl.closest(params.swipeHandler)) return;
2420 }
2421 touches.currentX = e.pageX;
2422 touches.currentY = e.pageY;
2423 const startX = touches.currentX;
2424 const startY = touches.currentY;
2425
2426 // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
2427
2428 const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
2429 const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
2430 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
2431 if (edgeSwipeDetection === 'prevent') {
2432 event.preventDefault();
2433 } else {
2434 return;
2435 }
2436 }
2437 Object.assign(data, {
2438 isTouched: true,
2439 isMoved: false,
2440 allowTouchCallbacks: true,
2441 isScrolling: undefined,
2442 startMoving: undefined
2443 });
2444 touches.startX = startX;
2445 touches.startY = startY;
2446 data.touchStartTime = now();
2447 swiper.allowClick = true;
2448 swiper.updateSize();
2449 swiper.swipeDirection = undefined;
2450 if (params.threshold > 0) data.allowThresholdMove = false;
2451 let preventDefault = true;
2452 if (targetEl.matches(data.focusableElements)) {
2453 preventDefault = false;
2454 if (targetEl.nodeName === 'SELECT') {
2455 data.isTouched = false;
2456 }
2457 }
2458 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl) {
2459 document.activeElement.blur();
2460 }
2461 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
2462 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
2463 e.preventDefault();
2464 }
2465 if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
2466 swiper.freeMode.onTouchStart();
2467 }
2468 swiper.emit('touchStart', e);
2469 }
2470
2471 function onTouchMove(event) {
2472 const document = getDocument();
2473 const swiper = this;
2474 const data = swiper.touchEventsData;
2475 const {
2476 params,
2477 touches,
2478 rtlTranslate: rtl,
2479 enabled
2480 } = swiper;
2481 if (!enabled) return;
2482 if (!params.simulateTouch && event.pointerType === 'mouse') return;
2483 let e = event;
2484 if (e.originalEvent) e = e.originalEvent;
2485 if (!data.isTouched) {
2486 if (data.startMoving && data.isScrolling) {
2487 swiper.emit('touchMoveOpposite', e);
2488 }
2489 return;
2490 }
2491 const pointerIndex = data.evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
2492 if (pointerIndex >= 0) data.evCache[pointerIndex] = e;
2493 const targetTouch = data.evCache.length > 1 ? data.evCache[0] : e;
2494 const pageX = targetTouch.pageX;
2495 const pageY = targetTouch.pageY;
2496 if (e.preventedByNestedSwiper) {
2497 touches.startX = pageX;
2498 touches.startY = pageY;
2499 return;
2500 }
2501 if (!swiper.allowTouchMove) {
2502 if (!e.target.matches(data.focusableElements)) {
2503 swiper.allowClick = false;
2504 }
2505 if (data.isTouched) {
2506 Object.assign(touches, {
2507 startX: pageX,
2508 startY: pageY,
2509 prevX: swiper.touches.currentX,
2510 prevY: swiper.touches.currentY,
2511 currentX: pageX,
2512 currentY: pageY
2513 });
2514 data.touchStartTime = now();
2515 }
2516 return;
2517 }
2518 if (params.touchReleaseOnEdges && !params.loop) {
2519 if (swiper.isVertical()) {
2520 // Vertical
2521 if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
2522 data.isTouched = false;
2523 data.isMoved = false;
2524 return;
2525 }
2526 } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {
2527 return;
2528 }
2529 }
2530 if (document.activeElement) {
2531 if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
2532 data.isMoved = true;
2533 swiper.allowClick = false;
2534 return;
2535 }
2536 }
2537 if (data.allowTouchCallbacks) {
2538 swiper.emit('touchMove', e);
2539 }
2540 if (e.targetTouches && e.targetTouches.length > 1) return;
2541 touches.currentX = pageX;
2542 touches.currentY = pageY;
2543 const diffX = touches.currentX - touches.startX;
2544 const diffY = touches.currentY - touches.startY;
2545 if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
2546 if (typeof data.isScrolling === 'undefined') {
2547 let touchAngle;
2548 if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
2549 data.isScrolling = false;
2550 } else {
2551 // eslint-disable-next-line
2552 if (diffX * diffX + diffY * diffY >= 25) {
2553 touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
2554 data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
2555 }
2556 }
2557 }
2558 if (data.isScrolling) {
2559 swiper.emit('touchMoveOpposite', e);
2560 }
2561 if (typeof data.startMoving === 'undefined') {
2562 if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
2563 data.startMoving = true;
2564 }
2565 }
2566 if (data.isScrolling || swiper.zoom && swiper.params.zoom && swiper.params.zoom.enabled && data.evCache.length > 1) {
2567 data.isTouched = false;
2568 return;
2569 }
2570 if (!data.startMoving) {
2571 return;
2572 }
2573 swiper.allowClick = false;
2574 if (!params.cssMode && e.cancelable) {
2575 e.preventDefault();
2576 }
2577 if (params.touchMoveStopPropagation && !params.nested) {
2578 e.stopPropagation();
2579 }
2580 let diff = swiper.isHorizontal() ? diffX : diffY;
2581 let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
2582 if (params.oneWayMovement) {
2583 diff = Math.abs(diff) * (rtl ? 1 : -1);
2584 touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
2585 }
2586 touches.diff = diff;
2587 diff *= params.touchRatio;
2588 if (rtl) {
2589 diff = -diff;
2590 touchesDiff = -touchesDiff;
2591 }
2592 const prevTouchesDirection = swiper.touchesDirection;
2593 swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
2594 swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
2595 const isLoop = swiper.params.loop && !params.cssMode;
2596 if (!data.isMoved) {
2597 if (isLoop) {
2598 swiper.loopFix({
2599 direction: swiper.swipeDirection
2600 });
2601 }
2602 data.startTranslate = swiper.getTranslate();
2603 swiper.setTransition(0);
2604 if (swiper.animating) {
2605 const evt = new window.CustomEvent('transitionend', {
2606 bubbles: true,
2607 cancelable: true
2608 });
2609 swiper.wrapperEl.dispatchEvent(evt);
2610 }
2611 data.allowMomentumBounce = false;
2612 // Grab Cursor
2613 if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2614 swiper.setGrabCursor(true);
2615 }
2616 swiper.emit('sliderFirstMove', e);
2617 }
2618 let loopFixed;
2619 if (data.isMoved && prevTouchesDirection !== swiper.touchesDirection && isLoop && Math.abs(diff) >= 1) {
2620 // need another loop fix
2621 swiper.loopFix({
2622 direction: swiper.swipeDirection,
2623 setTranslate: true
2624 });
2625 loopFixed = true;
2626 }
2627 swiper.emit('sliderMove', e);
2628 data.isMoved = true;
2629 data.currentTranslate = diff + data.startTranslate;
2630 let disableParentSwiper = true;
2631 let resistanceRatio = params.resistanceRatio;
2632 if (params.touchReleaseOnEdges) {
2633 resistanceRatio = 0;
2634 }
2635 if (diff > 0) {
2636 if (isLoop && !loopFixed && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.size / 2 : swiper.minTranslate())) {
2637 swiper.loopFix({
2638 direction: 'prev',
2639 setTranslate: true,
2640 activeSlideIndex: 0
2641 });
2642 }
2643 if (data.currentTranslate > swiper.minTranslate()) {
2644 disableParentSwiper = false;
2645 if (params.resistance) {
2646 data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
2647 }
2648 }
2649 } else if (diff < 0) {
2650 if (isLoop && !loopFixed && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.size / 2 : swiper.maxTranslate())) {
2651 swiper.loopFix({
2652 direction: 'next',
2653 setTranslate: true,
2654 activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
2655 });
2656 }
2657 if (data.currentTranslate < swiper.maxTranslate()) {
2658 disableParentSwiper = false;
2659 if (params.resistance) {
2660 data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
2661 }
2662 }
2663 }
2664 if (disableParentSwiper) {
2665 e.preventedByNestedSwiper = true;
2666 }
2667
2668 // Directions locks
2669 if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
2670 data.currentTranslate = data.startTranslate;
2671 }
2672 if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
2673 data.currentTranslate = data.startTranslate;
2674 }
2675 if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
2676 data.currentTranslate = data.startTranslate;
2677 }
2678
2679 // Threshold
2680 if (params.threshold > 0) {
2681 if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2682 if (!data.allowThresholdMove) {
2683 data.allowThresholdMove = true;
2684 touches.startX = touches.currentX;
2685 touches.startY = touches.currentY;
2686 data.currentTranslate = data.startTranslate;
2687 touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
2688 return;
2689 }
2690 } else {
2691 data.currentTranslate = data.startTranslate;
2692 return;
2693 }
2694 }
2695 if (!params.followFinger || params.cssMode) return;
2696
2697 // Update active index in free mode
2698 if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
2699 swiper.updateActiveIndex();
2700 swiper.updateSlidesClasses();
2701 }
2702 if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
2703 swiper.freeMode.onTouchMove();
2704 }
2705 // Update progress
2706 swiper.updateProgress(data.currentTranslate);
2707 // Update translate
2708 swiper.setTranslate(data.currentTranslate);
2709 }
2710
2711 function onTouchEnd(event) {
2712 const swiper = this;
2713 const data = swiper.touchEventsData;
2714 const pointerIndex = data.evCache.findIndex(cachedEv => cachedEv.pointerId === event.pointerId);
2715 if (pointerIndex >= 0) {
2716 data.evCache.splice(pointerIndex, 1);
2717 }
2718 if (['pointercancel', 'pointerout', 'pointerleave'].includes(event.type)) {
2719 const proceed = event.type === 'pointercancel' && (swiper.browser.isSafari || swiper.browser.isWebView);
2720 if (!proceed) {
2721 return;
2722 }
2723 }
2724 const {
2725 params,
2726 touches,
2727 rtlTranslate: rtl,
2728 slidesGrid,
2729 enabled
2730 } = swiper;
2731 if (!enabled) return;
2732 if (!params.simulateTouch && event.pointerType === 'mouse') return;
2733 let e = event;
2734 if (e.originalEvent) e = e.originalEvent;
2735 if (data.allowTouchCallbacks) {
2736 swiper.emit('touchEnd', e);
2737 }
2738 data.allowTouchCallbacks = false;
2739 if (!data.isTouched) {
2740 if (data.isMoved && params.grabCursor) {
2741 swiper.setGrabCursor(false);
2742 }
2743 data.isMoved = false;
2744 data.startMoving = false;
2745 return;
2746 }
2747 // Return Grab Cursor
2748 if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2749 swiper.setGrabCursor(false);
2750 }
2751
2752 // Time diff
2753 const touchEndTime = now();
2754 const timeDiff = touchEndTime - data.touchStartTime;
2755
2756 // Tap, doubleTap, Click
2757 if (swiper.allowClick) {
2758 const pathTree = e.path || e.composedPath && e.composedPath();
2759 swiper.updateClickedSlide(pathTree && pathTree[0] || e.target);
2760 swiper.emit('tap click', e);
2761 if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
2762 swiper.emit('doubleTap doubleClick', e);
2763 }
2764 }
2765 data.lastClickTime = now();
2766 nextTick(() => {
2767 if (!swiper.destroyed) swiper.allowClick = true;
2768 });
2769 if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {
2770 data.isTouched = false;
2771 data.isMoved = false;
2772 data.startMoving = false;
2773 return;
2774 }
2775 data.isTouched = false;
2776 data.isMoved = false;
2777 data.startMoving = false;
2778 let currentPos;
2779 if (params.followFinger) {
2780 currentPos = rtl ? swiper.translate : -swiper.translate;
2781 } else {
2782 currentPos = -data.currentTranslate;
2783 }
2784 if (params.cssMode) {
2785 return;
2786 }
2787 if (params.freeMode && params.freeMode.enabled) {
2788 swiper.freeMode.onTouchEnd({
2789 currentPos
2790 });
2791 return;
2792 }
2793
2794 // Find current slide
2795 let stopIndex = 0;
2796 let groupSize = swiper.slidesSizesGrid[0];
2797 for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
2798 const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
2799 if (typeof slidesGrid[i + increment] !== 'undefined') {
2800 if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
2801 stopIndex = i;
2802 groupSize = slidesGrid[i + increment] - slidesGrid[i];
2803 }
2804 } else if (currentPos >= slidesGrid[i]) {
2805 stopIndex = i;
2806 groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
2807 }
2808 }
2809 let rewindFirstIndex = null;
2810 let rewindLastIndex = null;
2811 if (params.rewind) {
2812 if (swiper.isBeginning) {
2813 rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2814 } else if (swiper.isEnd) {
2815 rewindFirstIndex = 0;
2816 }
2817 }
2818 // Find current slide size
2819 const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
2820 const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
2821 if (timeDiff > params.longSwipesMs) {
2822 // Long touches
2823 if (!params.longSwipes) {
2824 swiper.slideTo(swiper.activeIndex);
2825 return;
2826 }
2827 if (swiper.swipeDirection === 'next') {
2828 if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
2829 }
2830 if (swiper.swipeDirection === 'prev') {
2831 if (ratio > 1 - params.longSwipesRatio) {
2832 swiper.slideTo(stopIndex + increment);
2833 } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
2834 swiper.slideTo(rewindLastIndex);
2835 } else {
2836 swiper.slideTo(stopIndex);
2837 }
2838 }
2839 } else {
2840 // Short swipes
2841 if (!params.shortSwipes) {
2842 swiper.slideTo(swiper.activeIndex);
2843 return;
2844 }
2845 const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
2846 if (!isNavButtonTarget) {
2847 if (swiper.swipeDirection === 'next') {
2848 swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
2849 }
2850 if (swiper.swipeDirection === 'prev') {
2851 swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
2852 }
2853 } else if (e.target === swiper.navigation.nextEl) {
2854 swiper.slideTo(stopIndex + increment);
2855 } else {
2856 swiper.slideTo(stopIndex);
2857 }
2858 }
2859 }
2860
2861 function onResize() {
2862 const swiper = this;
2863 const {
2864 params,
2865 el
2866 } = swiper;
2867 if (el && el.offsetWidth === 0) return;
2868
2869 // Breakpoints
2870 if (params.breakpoints) {
2871 swiper.setBreakpoint();
2872 }
2873
2874 // Save locks
2875 const {
2876 allowSlideNext,
2877 allowSlidePrev,
2878 snapGrid
2879 } = swiper;
2880 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
2881
2882 // Disable locks on resize
2883 swiper.allowSlideNext = true;
2884 swiper.allowSlidePrev = true;
2885 swiper.updateSize();
2886 swiper.updateSlides();
2887 swiper.updateSlidesClasses();
2888 const isVirtualLoop = isVirtual && params.loop;
2889 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
2890 swiper.slideTo(swiper.slides.length - 1, 0, false, true);
2891 } else {
2892 if (swiper.params.loop && !isVirtual) {
2893 swiper.slideToLoop(swiper.realIndex, 0, false, true);
2894 } else {
2895 swiper.slideTo(swiper.activeIndex, 0, false, true);
2896 }
2897 }
2898 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
2899 clearTimeout(swiper.autoplay.resizeTimeout);
2900 swiper.autoplay.resizeTimeout = setTimeout(() => {
2901 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
2902 swiper.autoplay.resume();
2903 }
2904 }, 500);
2905 }
2906 // Return locks after resize
2907 swiper.allowSlidePrev = allowSlidePrev;
2908 swiper.allowSlideNext = allowSlideNext;
2909 if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
2910 swiper.checkOverflow();
2911 }
2912 }
2913
2914 function onClick(e) {
2915 const swiper = this;
2916 if (!swiper.enabled) return;
2917 if (!swiper.allowClick) {
2918 if (swiper.params.preventClicks) e.preventDefault();
2919 if (swiper.params.preventClicksPropagation && swiper.animating) {
2920 e.stopPropagation();
2921 e.stopImmediatePropagation();
2922 }
2923 }
2924 }
2925
2926 function onScroll() {
2927 const swiper = this;
2928 const {
2929 wrapperEl,
2930 rtlTranslate,
2931 enabled
2932 } = swiper;
2933 if (!enabled) return;
2934 swiper.previousTranslate = swiper.translate;
2935 if (swiper.isHorizontal()) {
2936 swiper.translate = -wrapperEl.scrollLeft;
2937 } else {
2938 swiper.translate = -wrapperEl.scrollTop;
2939 }
2940 // eslint-disable-next-line
2941 if (swiper.translate === 0) swiper.translate = 0;
2942 swiper.updateActiveIndex();
2943 swiper.updateSlidesClasses();
2944 let newProgress;
2945 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
2946 if (translatesDiff === 0) {
2947 newProgress = 0;
2948 } else {
2949 newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
2950 }
2951 if (newProgress !== swiper.progress) {
2952 swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
2953 }
2954 swiper.emit('setTranslate', swiper.translate, false);
2955 }
2956
2957 function onLoad(e) {
2958 const swiper = this;
2959 processLazyPreloader(swiper, e.target);
2960 if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
2961 return;
2962 }
2963 swiper.update();
2964 }
2965
2966 let dummyEventAttached = false;
2967 function dummyEventListener() {}
2968 const events = (swiper, method) => {
2969 const document = getDocument();
2970 const {
2971 params,
2972 el,
2973 wrapperEl,
2974 device
2975 } = swiper;
2976 const capture = !!params.nested;
2977 const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
2978 const swiperMethod = method;
2979
2980 // Touch Events
2981 el[domMethod]('pointerdown', swiper.onTouchStart, {
2982 passive: false
2983 });
2984 document[domMethod]('pointermove', swiper.onTouchMove, {
2985 passive: false,
2986 capture
2987 });
2988 document[domMethod]('pointerup', swiper.onTouchEnd, {
2989 passive: true
2990 });
2991 document[domMethod]('pointercancel', swiper.onTouchEnd, {
2992 passive: true
2993 });
2994 document[domMethod]('pointerout', swiper.onTouchEnd, {
2995 passive: true
2996 });
2997 document[domMethod]('pointerleave', swiper.onTouchEnd, {
2998 passive: true
2999 });
3000
3001 // Prevent Links Clicks
3002 if (params.preventClicks || params.preventClicksPropagation) {
3003 el[domMethod]('click', swiper.onClick, true);
3004 }
3005 if (params.cssMode) {
3006 wrapperEl[domMethod]('scroll', swiper.onScroll);
3007 }
3008
3009 // Resize handler
3010 if (params.updateOnWindowResize) {
3011 swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
3012 } else {
3013 swiper[swiperMethod]('observerUpdate', onResize, true);
3014 }
3015
3016 // Images loader
3017 el[domMethod]('load', swiper.onLoad, {
3018 capture: true
3019 });
3020 };
3021 function attachEvents() {
3022 const swiper = this;
3023 const document = getDocument();
3024 const {
3025 params
3026 } = swiper;
3027 swiper.onTouchStart = onTouchStart.bind(swiper);
3028 swiper.onTouchMove = onTouchMove.bind(swiper);
3029 swiper.onTouchEnd = onTouchEnd.bind(swiper);
3030 if (params.cssMode) {
3031 swiper.onScroll = onScroll.bind(swiper);
3032 }
3033 swiper.onClick = onClick.bind(swiper);
3034 swiper.onLoad = onLoad.bind(swiper);
3035 if (!dummyEventAttached) {
3036 document.addEventListener('touchstart', dummyEventListener);
3037 dummyEventAttached = true;
3038 }
3039 events(swiper, 'on');
3040 }
3041 function detachEvents() {
3042 const swiper = this;
3043 events(swiper, 'off');
3044 }
3045 var events$1 = {
3046 attachEvents,
3047 detachEvents
3048 };
3049
3050 const isGridEnabled = (swiper, params) => {
3051 return swiper.grid && params.grid && params.grid.rows > 1;
3052 };
3053 function setBreakpoint() {
3054 const swiper = this;
3055 const {
3056 realIndex,
3057 initialized,
3058 params,
3059 el
3060 } = swiper;
3061 const breakpoints = params.breakpoints;
3062 if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
3063
3064 // Get breakpoint for window width and update parameters
3065 const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
3066 if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3067 const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3068 const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3069 const wasMultiRow = isGridEnabled(swiper, params);
3070 const isMultiRow = isGridEnabled(swiper, breakpointParams);
3071 const wasEnabled = params.enabled;
3072 if (wasMultiRow && !isMultiRow) {
3073 el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3074 swiper.emitContainerClasses();
3075 } else if (!wasMultiRow && isMultiRow) {
3076 el.classList.add(`${params.containerModifierClass}grid`);
3077 if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
3078 el.classList.add(`${params.containerModifierClass}grid-column`);
3079 }
3080 swiper.emitContainerClasses();
3081 }
3082
3083 // Toggle navigation, pagination, scrollbar
3084 ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
3085 if (typeof breakpointParams[prop] === 'undefined') return;
3086 const wasModuleEnabled = params[prop] && params[prop].enabled;
3087 const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3088 if (wasModuleEnabled && !isModuleEnabled) {
3089 swiper[prop].disable();
3090 }
3091 if (!wasModuleEnabled && isModuleEnabled) {
3092 swiper[prop].enable();
3093 }
3094 });
3095 const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3096 const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
3097 if (directionChanged && initialized) {
3098 swiper.changeDirection();
3099 }
3100 extend$1(swiper.params, breakpointParams);
3101 const isEnabled = swiper.params.enabled;
3102 Object.assign(swiper, {
3103 allowTouchMove: swiper.params.allowTouchMove,
3104 allowSlideNext: swiper.params.allowSlideNext,
3105 allowSlidePrev: swiper.params.allowSlidePrev
3106 });
3107 if (wasEnabled && !isEnabled) {
3108 swiper.disable();
3109 } else if (!wasEnabled && isEnabled) {
3110 swiper.enable();
3111 }
3112 swiper.currentBreakpoint = breakpoint;
3113 swiper.emit('_beforeBreakpoint', breakpointParams);
3114 if (needsReLoop && initialized) {
3115 swiper.loopDestroy();
3116 swiper.loopCreate(realIndex);
3117 swiper.updateSlides();
3118 }
3119 swiper.emit('breakpoint', breakpointParams);
3120 }
3121
3122 function getBreakpoint(breakpoints, base, containerEl) {
3123 if (base === void 0) {
3124 base = 'window';
3125 }
3126 if (!breakpoints || base === 'container' && !containerEl) return undefined;
3127 let breakpoint = false;
3128 const window = getWindow();
3129 const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
3130 const points = Object.keys(breakpoints).map(point => {
3131 if (typeof point === 'string' && point.indexOf('@') === 0) {
3132 const minRatio = parseFloat(point.substr(1));
3133 const value = currentHeight * minRatio;
3134 return {
3135 value,
3136 point
3137 };
3138 }
3139 return {
3140 value: point,
3141 point
3142 };
3143 });
3144 points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
3145 for (let i = 0; i < points.length; i += 1) {
3146 const {
3147 point,
3148 value
3149 } = points[i];
3150 if (base === 'window') {
3151 if (window.matchMedia(`(min-width: ${value}px)`).matches) {
3152 breakpoint = point;
3153 }
3154 } else if (value <= containerEl.clientWidth) {
3155 breakpoint = point;
3156 }
3157 }
3158 return breakpoint || 'max';
3159 }
3160
3161 var breakpoints = {
3162 setBreakpoint,
3163 getBreakpoint
3164 };
3165
3166 function prepareClasses(entries, prefix) {
3167 const resultClasses = [];
3168 entries.forEach(item => {
3169 if (typeof item === 'object') {
3170 Object.keys(item).forEach(classNames => {
3171 if (item[classNames]) {
3172 resultClasses.push(prefix + classNames);
3173 }
3174 });
3175 } else if (typeof item === 'string') {
3176 resultClasses.push(prefix + item);
3177 }
3178 });
3179 return resultClasses;
3180 }
3181 function addClasses() {
3182 const swiper = this;
3183 const {
3184 classNames,
3185 params,
3186 rtl,
3187 el,
3188 device
3189 } = swiper;
3190 // prettier-ignore
3191 const suffixes = prepareClasses(['initialized', params.direction, {
3192 'free-mode': swiper.params.freeMode && params.freeMode.enabled
3193 }, {
3194 'autoheight': params.autoHeight
3195 }, {
3196 'rtl': rtl
3197 }, {
3198 'grid': params.grid && params.grid.rows > 1
3199 }, {
3200 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3201 }, {
3202 'android': device.android
3203 }, {
3204 'ios': device.ios
3205 }, {
3206 'css-mode': params.cssMode
3207 }, {
3208 'centered': params.cssMode && params.centeredSlides
3209 }, {
3210 'watch-progress': params.watchSlidesProgress
3211 }], params.containerModifierClass);
3212 classNames.push(...suffixes);
3213 el.classList.add(...classNames);
3214 swiper.emitContainerClasses();
3215 }
3216
3217 function removeClasses() {
3218 const swiper = this;
3219 const {
3220 el,
3221 classNames
3222 } = swiper;
3223 el.classList.remove(...classNames);
3224 swiper.emitContainerClasses();
3225 }
3226
3227 var classes = {
3228 addClasses,
3229 removeClasses
3230 };
3231
3232 function checkOverflow() {
3233 const swiper = this;
3234 const {
3235 isLocked: wasLocked,
3236 params
3237 } = swiper;
3238 const {
3239 slidesOffsetBefore
3240 } = params;
3241 if (slidesOffsetBefore) {
3242 const lastSlideIndex = swiper.slides.length - 1;
3243 const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
3244 swiper.isLocked = swiper.size > lastSlideRightEdge;
3245 } else {
3246 swiper.isLocked = swiper.snapGrid.length === 1;
3247 }
3248 if (params.allowSlideNext === true) {
3249 swiper.allowSlideNext = !swiper.isLocked;
3250 }
3251 if (params.allowSlidePrev === true) {
3252 swiper.allowSlidePrev = !swiper.isLocked;
3253 }
3254 if (wasLocked && wasLocked !== swiper.isLocked) {
3255 swiper.isEnd = false;
3256 }
3257 if (wasLocked !== swiper.isLocked) {
3258 swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
3259 }
3260 }
3261 var checkOverflow$1 = {
3262 checkOverflow
3263 };
3264
3265 var defaults = {
3266 init: true,
3267 direction: 'horizontal',
3268 oneWayMovement: false,
3269 touchEventsTarget: 'wrapper',
3270 initialSlide: 0,
3271 speed: 300,
3272 cssMode: false,
3273 updateOnWindowResize: true,
3274 resizeObserver: true,
3275 nested: false,
3276 createElements: false,
3277 enabled: true,
3278 focusableElements: 'input, select, option, textarea, button, video, label',
3279 // Overrides
3280 width: null,
3281 height: null,
3282 //
3283 preventInteractionOnTransition: false,
3284 // ssr
3285 userAgent: null,
3286 url: null,
3287 // To support iOS's swipe-to-go-back gesture (when being used in-app).
3288 edgeSwipeDetection: false,
3289 edgeSwipeThreshold: 20,
3290 // Autoheight
3291 autoHeight: false,
3292 // Set wrapper width
3293 setWrapperSize: false,
3294 // Virtual Translate
3295 virtualTranslate: false,
3296 // Effects
3297 effect: 'slide',
3298 // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3299
3300 // Breakpoints
3301 breakpoints: undefined,
3302 breakpointsBase: 'window',
3303 // Slides grid
3304 spaceBetween: 0,
3305 slidesPerView: 1,
3306 slidesPerGroup: 1,
3307 slidesPerGroupSkip: 0,
3308 slidesPerGroupAuto: false,
3309 centeredSlides: false,
3310 centeredSlidesBounds: false,
3311 slidesOffsetBefore: 0,
3312 // in px
3313 slidesOffsetAfter: 0,
3314 // in px
3315 normalizeSlideIndex: true,
3316 centerInsufficientSlides: false,
3317 // Disable swiper and hide navigation when container not overflow
3318 watchOverflow: true,
3319 // Round length
3320 roundLengths: false,
3321 // Touches
3322 touchRatio: 1,
3323 touchAngle: 45,
3324 simulateTouch: true,
3325 shortSwipes: true,
3326 longSwipes: true,
3327 longSwipesRatio: 0.5,
3328 longSwipesMs: 300,
3329 followFinger: true,
3330 allowTouchMove: true,
3331 threshold: 5,
3332 touchMoveStopPropagation: false,
3333 touchStartPreventDefault: true,
3334 touchStartForcePreventDefault: false,
3335 touchReleaseOnEdges: false,
3336 // Unique Navigation Elements
3337 uniqueNavElements: true,
3338 // Resistance
3339 resistance: true,
3340 resistanceRatio: 0.85,
3341 // Progress
3342 watchSlidesProgress: false,
3343 // Cursor
3344 grabCursor: false,
3345 // Clicks
3346 preventClicks: true,
3347 preventClicksPropagation: true,
3348 slideToClickedSlide: false,
3349 // loop
3350 loop: false,
3351 loopedSlides: null,
3352 loopPreventsSliding: true,
3353 // rewind
3354 rewind: false,
3355 // Swiping/no swiping
3356 allowSlidePrev: true,
3357 allowSlideNext: true,
3358 swipeHandler: null,
3359 // '.swipe-handler',
3360 noSwiping: true,
3361 noSwipingClass: 'swiper-no-swiping',
3362 noSwipingSelector: null,
3363 // Passive Listeners
3364 passiveListeners: true,
3365 maxBackfaceHiddenSlides: 10,
3366 // NS
3367 containerModifierClass: 'swiper-',
3368 // NEW
3369 slideClass: 'swiper-slide',
3370 slideActiveClass: 'swiper-slide-active',
3371 slideVisibleClass: 'swiper-slide-visible',
3372 slideNextClass: 'swiper-slide-next',
3373 slidePrevClass: 'swiper-slide-prev',
3374 wrapperClass: 'swiper-wrapper',
3375 lazyPreloaderClass: 'swiper-lazy-preloader',
3376 lazyPreloadPrevNext: 0,
3377 // Callbacks
3378 runCallbacksOnInit: true,
3379 // Internals
3380 _emitClasses: false
3381 };
3382
3383 function moduleExtendParams(params, allModulesParams) {
3384 return function extendParams(obj) {
3385 if (obj === void 0) {
3386 obj = {};
3387 }
3388 const moduleParamName = Object.keys(obj)[0];
3389 const moduleParams = obj[moduleParamName];
3390 if (typeof moduleParams !== 'object' || moduleParams === null) {
3391 extend$1(allModulesParams, obj);
3392 return;
3393 }
3394 if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] === true) {
3395 params[moduleParamName] = {
3396 auto: true
3397 };
3398 }
3399 if (!(moduleParamName in params && 'enabled' in moduleParams)) {
3400 extend$1(allModulesParams, obj);
3401 return;
3402 }
3403 if (params[moduleParamName] === true) {
3404 params[moduleParamName] = {
3405 enabled: true
3406 };
3407 }
3408 if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
3409 params[moduleParamName].enabled = true;
3410 }
3411 if (!params[moduleParamName]) params[moduleParamName] = {
3412 enabled: false
3413 };
3414 extend$1(allModulesParams, obj);
3415 };
3416 }
3417
3418 /* eslint no-param-reassign: "off" */
3419 const prototypes = {
3420 eventsEmitter,
3421 update,
3422 translate,
3423 transition,
3424 slide,
3425 loop,
3426 grabCursor,
3427 events: events$1,
3428 breakpoints,
3429 checkOverflow: checkOverflow$1,
3430 classes
3431 };
3432 const extendedDefaults = {};
3433 class Swiper {
3434 constructor() {
3435 let el;
3436 let params;
3437 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3438 args[_key] = arguments[_key];
3439 }
3440 if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
3441 params = args[0];
3442 } else {
3443 [el, params] = args;
3444 }
3445 if (!params) params = {};
3446 params = extend$1({}, params);
3447 if (el && !params.el) params.el = el;
3448 const document = getDocument();
3449 if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
3450 const swipers = [];
3451 document.querySelectorAll(params.el).forEach(containerEl => {
3452 const newParams = extend$1({}, params, {
3453 el: containerEl
3454 });
3455 swipers.push(new Swiper(newParams));
3456 });
3457 // eslint-disable-next-line no-constructor-return
3458 return swipers;
3459 }
3460
3461 // Swiper Instance
3462 const swiper = this;
3463 swiper.__swiper__ = true;
3464 swiper.support = getSupport();
3465 swiper.device = getDevice({
3466 userAgent: params.userAgent
3467 });
3468 swiper.browser = getBrowser();
3469 swiper.eventsListeners = {};
3470 swiper.eventsAnyListeners = [];
3471 swiper.modules = [...swiper.__modules__];
3472 if (params.modules && Array.isArray(params.modules)) {
3473 swiper.modules.push(...params.modules);
3474 }
3475 const allModulesParams = {};
3476 swiper.modules.forEach(mod => {
3477 mod({
3478 params,
3479 swiper,
3480 extendParams: moduleExtendParams(params, allModulesParams),
3481 on: swiper.on.bind(swiper),
3482 once: swiper.once.bind(swiper),
3483 off: swiper.off.bind(swiper),
3484 emit: swiper.emit.bind(swiper)
3485 });
3486 });
3487
3488 // Extend defaults with modules params
3489 const swiperParams = extend$1({}, defaults, allModulesParams);
3490
3491 // Extend defaults with passed params
3492 swiper.params = extend$1({}, swiperParams, extendedDefaults, params);
3493 swiper.originalParams = extend$1({}, swiper.params);
3494 swiper.passedParams = extend$1({}, params);
3495
3496 // add event listeners
3497 if (swiper.params && swiper.params.on) {
3498 Object.keys(swiper.params.on).forEach(eventName => {
3499 swiper.on(eventName, swiper.params.on[eventName]);
3500 });
3501 }
3502 if (swiper.params && swiper.params.onAny) {
3503 swiper.onAny(swiper.params.onAny);
3504 }
3505
3506 // Extend Swiper
3507 Object.assign(swiper, {
3508 enabled: swiper.params.enabled,
3509 el,
3510 // Classes
3511 classNames: [],
3512 // Slides
3513 slides: [],
3514 slidesGrid: [],
3515 snapGrid: [],
3516 slidesSizesGrid: [],
3517 // isDirection
3518 isHorizontal() {
3519 return swiper.params.direction === 'horizontal';
3520 },
3521 isVertical() {
3522 return swiper.params.direction === 'vertical';
3523 },
3524 // Indexes
3525 activeIndex: 0,
3526 realIndex: 0,
3527 //
3528 isBeginning: true,
3529 isEnd: false,
3530 // Props
3531 translate: 0,
3532 previousTranslate: 0,
3533 progress: 0,
3534 velocity: 0,
3535 animating: false,
3536 cssOverflowAdjustment() {
3537 // Returns 0 unless `translate` is > 2**23
3538 // Should be subtracted from css values to prevent overflow
3539 return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
3540 },
3541 // Locks
3542 allowSlideNext: swiper.params.allowSlideNext,
3543 allowSlidePrev: swiper.params.allowSlidePrev,
3544 // Touch Events
3545 touchEventsData: {
3546 isTouched: undefined,
3547 isMoved: undefined,
3548 allowTouchCallbacks: undefined,
3549 touchStartTime: undefined,
3550 isScrolling: undefined,
3551 currentTranslate: undefined,
3552 startTranslate: undefined,
3553 allowThresholdMove: undefined,
3554 // Form elements to match
3555 focusableElements: swiper.params.focusableElements,
3556 // Last click time
3557 lastClickTime: 0,
3558 clickTimeout: undefined,
3559 // Velocities
3560 velocities: [],
3561 allowMomentumBounce: undefined,
3562 startMoving: undefined,
3563 evCache: []
3564 },
3565 // Clicks
3566 allowClick: true,
3567 // Touches
3568 allowTouchMove: swiper.params.allowTouchMove,
3569 touches: {
3570 startX: 0,
3571 startY: 0,
3572 currentX: 0,
3573 currentY: 0,
3574 diff: 0
3575 },
3576 // Images
3577 imagesToLoad: [],
3578 imagesLoaded: 0
3579 });
3580 swiper.emit('_swiper');
3581
3582 // Init
3583 if (swiper.params.init) {
3584 swiper.init();
3585 }
3586
3587 // Return app instance
3588 // eslint-disable-next-line no-constructor-return
3589 return swiper;
3590 }
3591 getSlideIndex(slideEl) {
3592 const {
3593 slidesEl,
3594 params
3595 } = this;
3596 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3597 const firstSlideIndex = elementIndex(slides[0]);
3598 return elementIndex(slideEl) - firstSlideIndex;
3599 }
3600 getSlideIndexByData(index) {
3601 return this.getSlideIndex(this.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)[0]);
3602 }
3603 recalcSlides() {
3604 const swiper = this;
3605 const {
3606 slidesEl,
3607 params
3608 } = swiper;
3609 swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3610 }
3611 enable() {
3612 const swiper = this;
3613 if (swiper.enabled) return;
3614 swiper.enabled = true;
3615 if (swiper.params.grabCursor) {
3616 swiper.setGrabCursor();
3617 }
3618 swiper.emit('enable');
3619 }
3620 disable() {
3621 const swiper = this;
3622 if (!swiper.enabled) return;
3623 swiper.enabled = false;
3624 if (swiper.params.grabCursor) {
3625 swiper.unsetGrabCursor();
3626 }
3627 swiper.emit('disable');
3628 }
3629 setProgress(progress, speed) {
3630 const swiper = this;
3631 progress = Math.min(Math.max(progress, 0), 1);
3632 const min = swiper.minTranslate();
3633 const max = swiper.maxTranslate();
3634 const current = (max - min) * progress + min;
3635 swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
3636 swiper.updateActiveIndex();
3637 swiper.updateSlidesClasses();
3638 }
3639 emitContainerClasses() {
3640 const swiper = this;
3641 if (!swiper.params._emitClasses || !swiper.el) return;
3642 const cls = swiper.el.className.split(' ').filter(className => {
3643 return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
3644 });
3645 swiper.emit('_containerClasses', cls.join(' '));
3646 }
3647 getSlideClasses(slideEl) {
3648 const swiper = this;
3649 if (swiper.destroyed) return '';
3650 return slideEl.className.split(' ').filter(className => {
3651 return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
3652 }).join(' ');
3653 }
3654 emitSlidesClasses() {
3655 const swiper = this;
3656 if (!swiper.params._emitClasses || !swiper.el) return;
3657 const updates = [];
3658 swiper.slides.forEach(slideEl => {
3659 const classNames = swiper.getSlideClasses(slideEl);
3660 updates.push({
3661 slideEl,
3662 classNames
3663 });
3664 swiper.emit('_slideClass', slideEl, classNames);
3665 });
3666 swiper.emit('_slideClasses', updates);
3667 }
3668 slidesPerViewDynamic(view, exact) {
3669 if (view === void 0) {
3670 view = 'current';
3671 }
3672 if (exact === void 0) {
3673 exact = false;
3674 }
3675 const swiper = this;
3676 const {
3677 params,
3678 slides,
3679 slidesGrid,
3680 slidesSizesGrid,
3681 size: swiperSize,
3682 activeIndex
3683 } = swiper;
3684 let spv = 1;
3685 if (params.centeredSlides) {
3686 let slideSize = slides[activeIndex] ? slides[activeIndex].swiperSlideSize : 0;
3687 let breakLoop;
3688 for (let i = activeIndex + 1; i < slides.length; i += 1) {
3689 if (slides[i] && !breakLoop) {
3690 slideSize += slides[i].swiperSlideSize;
3691 spv += 1;
3692 if (slideSize > swiperSize) breakLoop = true;
3693 }
3694 }
3695 for (let i = activeIndex - 1; i >= 0; i -= 1) {
3696 if (slides[i] && !breakLoop) {
3697 slideSize += slides[i].swiperSlideSize;
3698 spv += 1;
3699 if (slideSize > swiperSize) breakLoop = true;
3700 }
3701 }
3702 } else {
3703 // eslint-disable-next-line
3704 if (view === 'current') {
3705 for (let i = activeIndex + 1; i < slides.length; i += 1) {
3706 const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
3707 if (slideInView) {
3708 spv += 1;
3709 }
3710 }
3711 } else {
3712 // previous
3713 for (let i = activeIndex - 1; i >= 0; i -= 1) {
3714 const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
3715 if (slideInView) {
3716 spv += 1;
3717 }
3718 }
3719 }
3720 }
3721 return spv;
3722 }
3723 update() {
3724 const swiper = this;
3725 if (!swiper || swiper.destroyed) return;
3726 const {
3727 snapGrid,
3728 params
3729 } = swiper;
3730 // Breakpoints
3731 if (params.breakpoints) {
3732 swiper.setBreakpoint();
3733 }
3734 [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
3735 if (imageEl.complete) {
3736 processLazyPreloader(swiper, imageEl);
3737 }
3738 });
3739 swiper.updateSize();
3740 swiper.updateSlides();
3741 swiper.updateProgress();
3742 swiper.updateSlidesClasses();
3743 function setTranslate() {
3744 const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
3745 const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
3746 swiper.setTranslate(newTranslate);
3747 swiper.updateActiveIndex();
3748 swiper.updateSlidesClasses();
3749 }
3750 let translated;
3751 if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
3752 setTranslate();
3753 if (params.autoHeight) {
3754 swiper.updateAutoHeight();
3755 }
3756 } else {
3757 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
3758 const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
3759 translated = swiper.slideTo(slides.length - 1, 0, false, true);
3760 } else {
3761 translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
3762 }
3763 if (!translated) {
3764 setTranslate();
3765 }
3766 }
3767 if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
3768 swiper.checkOverflow();
3769 }
3770 swiper.emit('update');
3771 }
3772 changeDirection(newDirection, needUpdate) {
3773 if (needUpdate === void 0) {
3774 needUpdate = true;
3775 }
3776 const swiper = this;
3777 const currentDirection = swiper.params.direction;
3778 if (!newDirection) {
3779 // eslint-disable-next-line
3780 newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
3781 }
3782 if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
3783 return swiper;
3784 }
3785 swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
3786 swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
3787 swiper.emitContainerClasses();
3788 swiper.params.direction = newDirection;
3789 swiper.slides.forEach(slideEl => {
3790 if (newDirection === 'vertical') {
3791 slideEl.style.width = '';
3792 } else {
3793 slideEl.style.height = '';
3794 }
3795 });
3796 swiper.emit('changeDirection');
3797 if (needUpdate) swiper.update();
3798 return swiper;
3799 }
3800 changeLanguageDirection(direction) {
3801 const swiper = this;
3802 if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
3803 swiper.rtl = direction === 'rtl';
3804 swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
3805 if (swiper.rtl) {
3806 swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
3807 swiper.el.dir = 'rtl';
3808 } else {
3809 swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
3810 swiper.el.dir = 'ltr';
3811 }
3812 swiper.update();
3813 }
3814 mount(element) {
3815 const swiper = this;
3816 if (swiper.mounted) return true;
3817
3818 // Find el
3819 let el = element || swiper.params.el;
3820 if (typeof el === 'string') {
3821 el = document.querySelector(el);
3822 }
3823 if (!el) {
3824 return false;
3825 }
3826 el.swiper = swiper;
3827 if (el.parentNode && el.parentNode.host) {
3828 swiper.isElement = true;
3829 }
3830 const getWrapperSelector = () => {
3831 return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
3832 };
3833 const getWrapper = () => {
3834 if (el && el.shadowRoot && el.shadowRoot.querySelector) {
3835 const res = el.shadowRoot.querySelector(getWrapperSelector());
3836 // Children needs to return slot items
3837 return res;
3838 }
3839 return elementChildren(el, getWrapperSelector())[0];
3840 };
3841 // Find Wrapper
3842 let wrapperEl = getWrapper();
3843 if (!wrapperEl && swiper.params.createElements) {
3844 wrapperEl = createElement('div', swiper.params.wrapperClass);
3845 el.append(wrapperEl);
3846 elementChildren(el, `.${swiper.params.slideClass}`).forEach(slideEl => {
3847 wrapperEl.append(slideEl);
3848 });
3849 }
3850 Object.assign(swiper, {
3851 el,
3852 wrapperEl,
3853 slidesEl: swiper.isElement ? el.parentNode.host : wrapperEl,
3854 hostEl: swiper.isElement ? el.parentNode.host : el,
3855 mounted: true,
3856 // RTL
3857 rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
3858 rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
3859 wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
3860 });
3861 return true;
3862 }
3863 init(el) {
3864 const swiper = this;
3865 if (swiper.initialized) return swiper;
3866 const mounted = swiper.mount(el);
3867 if (mounted === false) return swiper;
3868 swiper.emit('beforeInit');
3869
3870 // Set breakpoint
3871 if (swiper.params.breakpoints) {
3872 swiper.setBreakpoint();
3873 }
3874
3875 // Add Classes
3876 swiper.addClasses();
3877
3878 // Update size
3879 swiper.updateSize();
3880
3881 // Update slides
3882 swiper.updateSlides();
3883 if (swiper.params.watchOverflow) {
3884 swiper.checkOverflow();
3885 }
3886
3887 // Set Grab Cursor
3888 if (swiper.params.grabCursor && swiper.enabled) {
3889 swiper.setGrabCursor();
3890 }
3891
3892 // Slide To Initial Slide
3893 if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
3894 swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
3895 } else {
3896 swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
3897 }
3898
3899 // Create loop
3900 if (swiper.params.loop) {
3901 swiper.loopCreate();
3902 }
3903
3904 // Attach events
3905 swiper.attachEvents();
3906 [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
3907 if (imageEl.complete) {
3908 processLazyPreloader(swiper, imageEl);
3909 } else {
3910 imageEl.addEventListener('load', e => {
3911 processLazyPreloader(swiper, e.target);
3912 });
3913 }
3914 });
3915 preload(swiper);
3916
3917 // Init Flag
3918 swiper.initialized = true;
3919 preload(swiper);
3920
3921 // Emit
3922 swiper.emit('init');
3923 swiper.emit('afterInit');
3924 return swiper;
3925 }
3926 destroy(deleteInstance, cleanStyles) {
3927 if (deleteInstance === void 0) {
3928 deleteInstance = true;
3929 }
3930 if (cleanStyles === void 0) {
3931 cleanStyles = true;
3932 }
3933 const swiper = this;
3934 const {
3935 params,
3936 el,
3937 wrapperEl,
3938 slides
3939 } = swiper;
3940 if (typeof swiper.params === 'undefined' || swiper.destroyed) {
3941 return null;
3942 }
3943 swiper.emit('beforeDestroy');
3944
3945 // Init Flag
3946 swiper.initialized = false;
3947
3948 // Detach events
3949 swiper.detachEvents();
3950
3951 // Destroy loop
3952 if (params.loop) {
3953 swiper.loopDestroy();
3954 }
3955
3956 // Cleanup styles
3957 if (cleanStyles) {
3958 swiper.removeClasses();
3959 el.removeAttribute('style');
3960 wrapperEl.removeAttribute('style');
3961 if (slides && slides.length) {
3962 slides.forEach(slideEl => {
3963 slideEl.classList.remove(params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
3964 slideEl.removeAttribute('style');
3965 slideEl.removeAttribute('data-swiper-slide-index');
3966 });
3967 }
3968 }
3969 swiper.emit('destroy');
3970
3971 // Detach emitter events
3972 Object.keys(swiper.eventsListeners).forEach(eventName => {
3973 swiper.off(eventName);
3974 });
3975 if (deleteInstance !== false) {
3976 swiper.el.swiper = null;
3977 deleteProps(swiper);
3978 }
3979 swiper.destroyed = true;
3980 return null;
3981 }
3982 static extendDefaults(newDefaults) {
3983 extend$1(extendedDefaults, newDefaults);
3984 }
3985 static get extendedDefaults() {
3986 return extendedDefaults;
3987 }
3988 static get defaults() {
3989 return defaults;
3990 }
3991 static installModule(mod) {
3992 if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
3993 const modules = Swiper.prototype.__modules__;
3994 if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
3995 modules.push(mod);
3996 }
3997 }
3998 static use(module) {
3999 if (Array.isArray(module)) {
4000 module.forEach(m => Swiper.installModule(m));
4001 return Swiper;
4002 }
4003 Swiper.installModule(module);
4004 return Swiper;
4005 }
4006 }
4007 Object.keys(prototypes).forEach(prototypeGroup => {
4008 Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
4009 Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
4010 });
4011 });
4012 Swiper.use([Resize, Observer]);
4013
4014 function Virtual(_ref) {
4015 let {
4016 swiper,
4017 extendParams,
4018 on,
4019 emit
4020 } = _ref;
4021 extendParams({
4022 virtual: {
4023 enabled: false,
4024 slides: [],
4025 cache: true,
4026 renderSlide: null,
4027 renderExternal: null,
4028 renderExternalUpdate: true,
4029 addSlidesBefore: 0,
4030 addSlidesAfter: 0
4031 }
4032 });
4033 let cssModeTimeout;
4034 const document = getDocument();
4035 swiper.virtual = {
4036 cache: {},
4037 from: undefined,
4038 to: undefined,
4039 slides: [],
4040 offset: 0,
4041 slidesGrid: []
4042 };
4043 const tempDOM = document.createElement('div');
4044 function renderSlide(slide, index) {
4045 const params = swiper.params.virtual;
4046 if (params.cache && swiper.virtual.cache[index]) {
4047 return swiper.virtual.cache[index];
4048 }
4049 // eslint-disable-next-line
4050 let slideEl;
4051 if (params.renderSlide) {
4052 slideEl = params.renderSlide.call(swiper, slide, index);
4053 if (typeof slideEl === 'string') {
4054 tempDOM.innerHTML = slideEl;
4055 slideEl = tempDOM.children[0];
4056 }
4057 } else if (swiper.isElement) {
4058 slideEl = createElement('swiper-slide');
4059 } else {
4060 slideEl = createElement('div', swiper.params.slideClass);
4061 }
4062 slideEl.setAttribute('data-swiper-slide-index', index);
4063 if (!params.renderSlide) {
4064 slideEl.innerHTML = slide;
4065 }
4066 if (params.cache) swiper.virtual.cache[index] = slideEl;
4067 return slideEl;
4068 }
4069 function update(force) {
4070 const {
4071 slidesPerView,
4072 slidesPerGroup,
4073 centeredSlides,
4074 loop: isLoop
4075 } = swiper.params;
4076 const {
4077 addSlidesBefore,
4078 addSlidesAfter
4079 } = swiper.params.virtual;
4080 const {
4081 from: previousFrom,
4082 to: previousTo,
4083 slides,
4084 slidesGrid: previousSlidesGrid,
4085 offset: previousOffset
4086 } = swiper.virtual;
4087 if (!swiper.params.cssMode) {
4088 swiper.updateActiveIndex();
4089 }
4090 const activeIndex = swiper.activeIndex || 0;
4091 let offsetProp;
4092 if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
4093 let slidesAfter;
4094 let slidesBefore;
4095 if (centeredSlides) {
4096 slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
4097 slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
4098 } else {
4099 slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
4100 slidesBefore = (isLoop ? slidesPerView : slidesPerGroup) + addSlidesBefore;
4101 }
4102 let from = activeIndex - slidesBefore;
4103 let to = activeIndex + slidesAfter;
4104 if (!isLoop) {
4105 from = Math.max(from, 0);
4106 to = Math.min(to, slides.length - 1);
4107 }
4108 let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
4109 if (isLoop && activeIndex >= slidesBefore) {
4110 from -= slidesBefore;
4111 if (!centeredSlides) offset += swiper.slidesGrid[0];
4112 } else if (isLoop && activeIndex < slidesBefore) {
4113 from = -slidesBefore;
4114 if (centeredSlides) offset += swiper.slidesGrid[0];
4115 }
4116 Object.assign(swiper.virtual, {
4117 from,
4118 to,
4119 offset,
4120 slidesGrid: swiper.slidesGrid,
4121 slidesBefore,
4122 slidesAfter
4123 });
4124 function onRendered() {
4125 swiper.updateSlides();
4126 swiper.updateProgress();
4127 swiper.updateSlidesClasses();
4128 emit('virtualUpdate');
4129 }
4130 if (previousFrom === from && previousTo === to && !force) {
4131 if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
4132 swiper.slides.forEach(slideEl => {
4133 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4134 });
4135 }
4136 swiper.updateProgress();
4137 emit('virtualUpdate');
4138 return;
4139 }
4140 if (swiper.params.virtual.renderExternal) {
4141 swiper.params.virtual.renderExternal.call(swiper, {
4142 offset,
4143 from,
4144 to,
4145 slides: function getSlides() {
4146 const slidesToRender = [];
4147 for (let i = from; i <= to; i += 1) {
4148 slidesToRender.push(slides[i]);
4149 }
4150 return slidesToRender;
4151 }()
4152 });
4153 if (swiper.params.virtual.renderExternalUpdate) {
4154 onRendered();
4155 } else {
4156 emit('virtualUpdate');
4157 }
4158 return;
4159 }
4160 const prependIndexes = [];
4161 const appendIndexes = [];
4162 const getSlideIndex = index => {
4163 let slideIndex = index;
4164 if (index < 0) {
4165 slideIndex = slides.length + index;
4166 } else if (slideIndex >= slides.length) {
4167 // eslint-disable-next-line
4168 slideIndex = slideIndex - slides.length;
4169 }
4170 return slideIndex;
4171 };
4172 if (force) {
4173 swiper.slidesEl.querySelectorAll(`.${swiper.params.slideClass}, swiper-slide`).forEach(slideEl => {
4174 slideEl.remove();
4175 });
4176 } else {
4177 for (let i = previousFrom; i <= previousTo; i += 1) {
4178 if (i < from || i > to) {
4179 const slideIndex = getSlideIndex(i);
4180 swiper.slidesEl.querySelectorAll(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`).forEach(slideEl => {
4181 slideEl.remove();
4182 });
4183 }
4184 }
4185 }
4186 const loopFrom = isLoop ? -slides.length : 0;
4187 const loopTo = isLoop ? slides.length * 2 : slides.length;
4188 for (let i = loopFrom; i < loopTo; i += 1) {
4189 if (i >= from && i <= to) {
4190 const slideIndex = getSlideIndex(i);
4191 if (typeof previousTo === 'undefined' || force) {
4192 appendIndexes.push(slideIndex);
4193 } else {
4194 if (i > previousTo) appendIndexes.push(slideIndex);
4195 if (i < previousFrom) prependIndexes.push(slideIndex);
4196 }
4197 }
4198 }
4199 appendIndexes.forEach(index => {
4200 swiper.slidesEl.append(renderSlide(slides[index], index));
4201 });
4202 if (isLoop) {
4203 for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
4204 const index = prependIndexes[i];
4205 swiper.slidesEl.prepend(renderSlide(slides[index], index));
4206 }
4207 } else {
4208 prependIndexes.sort((a, b) => b - a);
4209 prependIndexes.forEach(index => {
4210 swiper.slidesEl.prepend(renderSlide(slides[index], index));
4211 });
4212 }
4213 elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(slideEl => {
4214 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4215 });
4216 onRendered();
4217 }
4218 function appendSlide(slides) {
4219 if (typeof slides === 'object' && 'length' in slides) {
4220 for (let i = 0; i < slides.length; i += 1) {
4221 if (slides[i]) swiper.virtual.slides.push(slides[i]);
4222 }
4223 } else {
4224 swiper.virtual.slides.push(slides);
4225 }
4226 update(true);
4227 }
4228 function prependSlide(slides) {
4229 const activeIndex = swiper.activeIndex;
4230 let newActiveIndex = activeIndex + 1;
4231 let numberOfNewSlides = 1;
4232 if (Array.isArray(slides)) {
4233 for (let i = 0; i < slides.length; i += 1) {
4234 if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
4235 }
4236 newActiveIndex = activeIndex + slides.length;
4237 numberOfNewSlides = slides.length;
4238 } else {
4239 swiper.virtual.slides.unshift(slides);
4240 }
4241 if (swiper.params.virtual.cache) {
4242 const cache = swiper.virtual.cache;
4243 const newCache = {};
4244 Object.keys(cache).forEach(cachedIndex => {
4245 const cachedEl = cache[cachedIndex];
4246 const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
4247 if (cachedElIndex) {
4248 cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
4249 }
4250 newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
4251 });
4252 swiper.virtual.cache = newCache;
4253 }
4254 update(true);
4255 swiper.slideTo(newActiveIndex, 0);
4256 }
4257 function removeSlide(slidesIndexes) {
4258 if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
4259 let activeIndex = swiper.activeIndex;
4260 if (Array.isArray(slidesIndexes)) {
4261 for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
4262 swiper.virtual.slides.splice(slidesIndexes[i], 1);
4263 if (swiper.params.virtual.cache) {
4264 delete swiper.virtual.cache[slidesIndexes[i]];
4265 }
4266 if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
4267 activeIndex = Math.max(activeIndex, 0);
4268 }
4269 } else {
4270 swiper.virtual.slides.splice(slidesIndexes, 1);
4271 if (swiper.params.virtual.cache) {
4272 delete swiper.virtual.cache[slidesIndexes];
4273 }
4274 if (slidesIndexes < activeIndex) activeIndex -= 1;
4275 activeIndex = Math.max(activeIndex, 0);
4276 }
4277 update(true);
4278 swiper.slideTo(activeIndex, 0);
4279 }
4280 function removeAllSlides() {
4281 swiper.virtual.slides = [];
4282 if (swiper.params.virtual.cache) {
4283 swiper.virtual.cache = {};
4284 }
4285 update(true);
4286 swiper.slideTo(0, 0);
4287 }
4288 on('beforeInit', () => {
4289 if (!swiper.params.virtual.enabled) return;
4290 let domSlidesAssigned;
4291 if (typeof swiper.passedParams.virtual.slides === 'undefined') {
4292 const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
4293 if (slides && slides.length) {
4294 swiper.virtual.slides = [...slides];
4295 domSlidesAssigned = true;
4296 slides.forEach((slideEl, slideIndex) => {
4297 slideEl.setAttribute('data-swiper-slide-index', slideIndex);
4298 swiper.virtual.cache[slideIndex] = slideEl;
4299 slideEl.remove();
4300 });
4301 }
4302 }
4303 if (!domSlidesAssigned) {
4304 swiper.virtual.slides = swiper.params.virtual.slides;
4305 }
4306 swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
4307 swiper.params.watchSlidesProgress = true;
4308 swiper.originalParams.watchSlidesProgress = true;
4309 if (!swiper.params.initialSlide) {
4310 update();
4311 }
4312 });
4313 on('setTranslate', () => {
4314 if (!swiper.params.virtual.enabled) return;
4315 if (swiper.params.cssMode && !swiper._immediateVirtual) {
4316 clearTimeout(cssModeTimeout);
4317 cssModeTimeout = setTimeout(() => {
4318 update();
4319 }, 100);
4320 } else {
4321 update();
4322 }
4323 });
4324 on('init update resize', () => {
4325 if (!swiper.params.virtual.enabled) return;
4326 if (swiper.params.cssMode) {
4327 setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
4328 }
4329 });
4330 Object.assign(swiper.virtual, {
4331 appendSlide,
4332 prependSlide,
4333 removeSlide,
4334 removeAllSlides,
4335 update
4336 });
4337 }
4338
4339 /* eslint-disable consistent-return */
4340 function Keyboard(_ref) {
4341 let {
4342 swiper,
4343 extendParams,
4344 on,
4345 emit
4346 } = _ref;
4347 const document = getDocument();
4348 const window = getWindow();
4349 swiper.keyboard = {
4350 enabled: false
4351 };
4352 extendParams({
4353 keyboard: {
4354 enabled: false,
4355 onlyInViewport: true,
4356 pageUpDown: true
4357 }
4358 });
4359 function handle(event) {
4360 if (!swiper.enabled) return;
4361 const {
4362 rtlTranslate: rtl
4363 } = swiper;
4364 let e = event;
4365 if (e.originalEvent) e = e.originalEvent; // jquery fix
4366 const kc = e.keyCode || e.charCode;
4367 const pageUpDown = swiper.params.keyboard.pageUpDown;
4368 const isPageUp = pageUpDown && kc === 33;
4369 const isPageDown = pageUpDown && kc === 34;
4370 const isArrowLeft = kc === 37;
4371 const isArrowRight = kc === 39;
4372 const isArrowUp = kc === 38;
4373 const isArrowDown = kc === 40;
4374 // Directions locks
4375 if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
4376 return false;
4377 }
4378 if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
4379 return false;
4380 }
4381 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
4382 return undefined;
4383 }
4384 if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
4385 return undefined;
4386 }
4387 if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
4388 let inView = false;
4389 // Check that swiper should be inside of visible area of window
4390 if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) {
4391 return undefined;
4392 }
4393 const el = swiper.el;
4394 const swiperWidth = el.clientWidth;
4395 const swiperHeight = el.clientHeight;
4396 const windowWidth = window.innerWidth;
4397 const windowHeight = window.innerHeight;
4398 const swiperOffset = elementOffset(el);
4399 if (rtl) swiperOffset.left -= el.scrollLeft;
4400 const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
4401 for (let i = 0; i < swiperCoord.length; i += 1) {
4402 const point = swiperCoord[i];
4403 if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
4404 if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
4405 inView = true;
4406 }
4407 }
4408 if (!inView) return undefined;
4409 }
4410 if (swiper.isHorizontal()) {
4411 if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
4412 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
4413 }
4414 if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
4415 if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
4416 } else {
4417 if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
4418 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
4419 }
4420 if (isPageDown || isArrowDown) swiper.slideNext();
4421 if (isPageUp || isArrowUp) swiper.slidePrev();
4422 }
4423 emit('keyPress', kc);
4424 return undefined;
4425 }
4426 function enable() {
4427 if (swiper.keyboard.enabled) return;
4428 document.addEventListener('keydown', handle);
4429 swiper.keyboard.enabled = true;
4430 }
4431 function disable() {
4432 if (!swiper.keyboard.enabled) return;
4433 document.removeEventListener('keydown', handle);
4434 swiper.keyboard.enabled = false;
4435 }
4436 on('init', () => {
4437 if (swiper.params.keyboard.enabled) {
4438 enable();
4439 }
4440 });
4441 on('destroy', () => {
4442 if (swiper.keyboard.enabled) {
4443 disable();
4444 }
4445 });
4446 Object.assign(swiper.keyboard, {
4447 enable,
4448 disable
4449 });
4450 }
4451
4452 /* eslint-disable consistent-return */
4453 function Mousewheel(_ref) {
4454 let {
4455 swiper,
4456 extendParams,
4457 on,
4458 emit
4459 } = _ref;
4460 const window = getWindow();
4461 extendParams({
4462 mousewheel: {
4463 enabled: false,
4464 releaseOnEdges: false,
4465 invert: false,
4466 forceToAxis: false,
4467 sensitivity: 1,
4468 eventsTarget: 'container',
4469 thresholdDelta: null,
4470 thresholdTime: null,
4471 noMousewheelClass: 'swiper-no-mousewheel'
4472 }
4473 });
4474 swiper.mousewheel = {
4475 enabled: false
4476 };
4477 let timeout;
4478 let lastScrollTime = now();
4479 let lastEventBeforeSnap;
4480 const recentWheelEvents = [];
4481 function normalize(e) {
4482 // Reasonable defaults
4483 const PIXEL_STEP = 10;
4484 const LINE_HEIGHT = 40;
4485 const PAGE_HEIGHT = 800;
4486 let sX = 0;
4487 let sY = 0; // spinX, spinY
4488 let pX = 0;
4489 let pY = 0; // pixelX, pixelY
4490
4491 // Legacy
4492 if ('detail' in e) {
4493 sY = e.detail;
4494 }
4495 if ('wheelDelta' in e) {
4496 sY = -e.wheelDelta / 120;
4497 }
4498 if ('wheelDeltaY' in e) {
4499 sY = -e.wheelDeltaY / 120;
4500 }
4501 if ('wheelDeltaX' in e) {
4502 sX = -e.wheelDeltaX / 120;
4503 }
4504
4505 // side scrolling on FF with DOMMouseScroll
4506 if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
4507 sX = sY;
4508 sY = 0;
4509 }
4510 pX = sX * PIXEL_STEP;
4511 pY = sY * PIXEL_STEP;
4512 if ('deltaY' in e) {
4513 pY = e.deltaY;
4514 }
4515 if ('deltaX' in e) {
4516 pX = e.deltaX;
4517 }
4518 if (e.shiftKey && !pX) {
4519 // if user scrolls with shift he wants horizontal scroll
4520 pX = pY;
4521 pY = 0;
4522 }
4523 if ((pX || pY) && e.deltaMode) {
4524 if (e.deltaMode === 1) {
4525 // delta in LINE units
4526 pX *= LINE_HEIGHT;
4527 pY *= LINE_HEIGHT;
4528 } else {
4529 // delta in PAGE units
4530 pX *= PAGE_HEIGHT;
4531 pY *= PAGE_HEIGHT;
4532 }
4533 }
4534
4535 // Fall-back if spin cannot be determined
4536 if (pX && !sX) {
4537 sX = pX < 1 ? -1 : 1;
4538 }
4539 if (pY && !sY) {
4540 sY = pY < 1 ? -1 : 1;
4541 }
4542 return {
4543 spinX: sX,
4544 spinY: sY,
4545 pixelX: pX,
4546 pixelY: pY
4547 };
4548 }
4549 function handleMouseEnter() {
4550 if (!swiper.enabled) return;
4551 swiper.mouseEntered = true;
4552 }
4553 function handleMouseLeave() {
4554 if (!swiper.enabled) return;
4555 swiper.mouseEntered = false;
4556 }
4557 function animateSlider(newEvent) {
4558 if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
4559 // Prevent if delta of wheel scroll delta is below configured threshold
4560 return false;
4561 }
4562 if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
4563 // Prevent if time between scrolls is below configured threshold
4564 return false;
4565 }
4566
4567 // If the movement is NOT big enough and
4568 // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
4569 // Don't go any further (avoid insignificant scroll movement).
4570 if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
4571 // Return false as a default
4572 return true;
4573 }
4574 // If user is scrolling towards the end:
4575 // If the slider hasn't hit the latest slide or
4576 // if the slider is a loop and
4577 // if the slider isn't moving right now:
4578 // Go to next slide and
4579 // emit a scroll event.
4580 // Else (the user is scrolling towards the beginning) and
4581 // if the slider hasn't hit the first slide or
4582 // if the slider is a loop and
4583 // if the slider isn't moving right now:
4584 // Go to prev slide and
4585 // emit a scroll event.
4586 if (newEvent.direction < 0) {
4587 if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
4588 swiper.slideNext();
4589 emit('scroll', newEvent.raw);
4590 }
4591 } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
4592 swiper.slidePrev();
4593 emit('scroll', newEvent.raw);
4594 }
4595 // If you got here is because an animation has been triggered so store the current time
4596 lastScrollTime = new window.Date().getTime();
4597 // Return false as a default
4598 return false;
4599 }
4600 function releaseScroll(newEvent) {
4601 const params = swiper.params.mousewheel;
4602 if (newEvent.direction < 0) {
4603 if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
4604 // Return true to animate scroll on edges
4605 return true;
4606 }
4607 } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
4608 // Return true to animate scroll on edges
4609 return true;
4610 }
4611 return false;
4612 }
4613 function handle(event) {
4614 let e = event;
4615 let disableParentSwiper = true;
4616 if (!swiper.enabled) return;
4617
4618 // Ignore event if the target or its parents have the swiper-no-mousewheel class
4619 if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
4620 const params = swiper.params.mousewheel;
4621 if (swiper.params.cssMode) {
4622 e.preventDefault();
4623 }
4624 let targetEl = swiper.el;
4625 if (swiper.params.mousewheel.eventsTarget !== 'container') {
4626 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
4627 }
4628 const targetElContainsTarget = targetEl && targetEl.contains(e.target);
4629 if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
4630 if (e.originalEvent) e = e.originalEvent; // jquery fix
4631 let delta = 0;
4632 const rtlFactor = swiper.rtlTranslate ? -1 : 1;
4633 const data = normalize(e);
4634 if (params.forceToAxis) {
4635 if (swiper.isHorizontal()) {
4636 if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;
4637 } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;
4638 } else {
4639 delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
4640 }
4641 if (delta === 0) return true;
4642 if (params.invert) delta = -delta;
4643
4644 // Get the scroll positions
4645 let positions = swiper.getTranslate() + delta * params.sensitivity;
4646 if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
4647 if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
4648
4649 // When loop is true:
4650 // the disableParentSwiper will be true.
4651 // When loop is false:
4652 // if the scroll positions is not on edge,
4653 // then the disableParentSwiper will be true.
4654 // if the scroll on edge positions,
4655 // then the disableParentSwiper will be false.
4656 disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
4657 if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
4658 if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
4659 // Register the new event in a variable which stores the relevant data
4660 const newEvent = {
4661 time: now(),
4662 delta: Math.abs(delta),
4663 direction: Math.sign(delta),
4664 raw: event
4665 };
4666
4667 // Keep the most recent events
4668 if (recentWheelEvents.length >= 2) {
4669 recentWheelEvents.shift(); // only store the last N events
4670 }
4671
4672 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4673 recentWheelEvents.push(newEvent);
4674
4675 // If there is at least one previous recorded event:
4676 // If direction has changed or
4677 // if the scroll is quicker than the previous one:
4678 // Animate the slider.
4679 // Else (this is the first time the wheel is moved):
4680 // Animate the slider.
4681 if (prevEvent) {
4682 if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
4683 animateSlider(newEvent);
4684 }
4685 } else {
4686 animateSlider(newEvent);
4687 }
4688
4689 // If it's time to release the scroll:
4690 // Return now so you don't hit the preventDefault.
4691 if (releaseScroll(newEvent)) {
4692 return true;
4693 }
4694 } else {
4695 // Freemode or scrollContainer:
4696
4697 // If we recently snapped after a momentum scroll, then ignore wheel events
4698 // to give time for the deceleration to finish. Stop ignoring after 500 msecs
4699 // or if it's a new scroll (larger delta or inverse sign as last event before
4700 // an end-of-momentum snap).
4701 const newEvent = {
4702 time: now(),
4703 delta: Math.abs(delta),
4704 direction: Math.sign(delta)
4705 };
4706 const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;
4707 if (!ignoreWheelEvents) {
4708 lastEventBeforeSnap = undefined;
4709 let position = swiper.getTranslate() + delta * params.sensitivity;
4710 const wasBeginning = swiper.isBeginning;
4711 const wasEnd = swiper.isEnd;
4712 if (position >= swiper.minTranslate()) position = swiper.minTranslate();
4713 if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
4714 swiper.setTransition(0);
4715 swiper.setTranslate(position);
4716 swiper.updateProgress();
4717 swiper.updateActiveIndex();
4718 swiper.updateSlidesClasses();
4719 if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
4720 swiper.updateSlidesClasses();
4721 }
4722 if (swiper.params.loop) {
4723 swiper.loopFix({
4724 direction: newEvent.direction < 0 ? 'next' : 'prev',
4725 byMousewheel: true
4726 });
4727 }
4728 if (swiper.params.freeMode.sticky) {
4729 // When wheel scrolling starts with sticky (aka snap) enabled, then detect
4730 // the end of a momentum scroll by storing recent (N=15?) wheel events.
4731 // 1. do all N events have decreasing or same (absolute value) delta?
4732 // 2. did all N events arrive in the last M (M=500?) msecs?
4733 // 3. does the earliest event have an (absolute value) delta that's
4734 // at least P (P=1?) larger than the most recent event's delta?
4735 // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
4736 // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
4737 // Snap immediately and ignore remaining wheel events in this scroll.
4738 // See comment above for "remaining wheel events in this scroll" determination.
4739 // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
4740 clearTimeout(timeout);
4741 timeout = undefined;
4742 if (recentWheelEvents.length >= 15) {
4743 recentWheelEvents.shift(); // only store the last N events
4744 }
4745
4746 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4747 const firstEvent = recentWheelEvents[0];
4748 recentWheelEvents.push(newEvent);
4749 if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
4750 // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
4751 recentWheelEvents.splice(0);
4752 } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {
4753 // We're at the end of the deceleration of a momentum scroll, so there's no need
4754 // to wait for more events. Snap ASAP on the next tick.
4755 // Also, because there's some remaining momentum we'll bias the snap in the
4756 // direction of the ongoing scroll because it's better UX for the scroll to snap
4757 // in the same direction as the scroll instead of reversing to snap. Therefore,
4758 // if it's already scrolled more than 20% in the current direction, keep going.
4759 const snapToThreshold = delta > 0 ? 0.8 : 0.2;
4760 lastEventBeforeSnap = newEvent;
4761 recentWheelEvents.splice(0);
4762 timeout = nextTick(() => {
4763 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4764 }, 0); // no delay; move on next tick
4765 }
4766
4767 if (!timeout) {
4768 // if we get here, then we haven't detected the end of a momentum scroll, so
4769 // we'll consider a scroll "complete" when there haven't been any wheel events
4770 // for 500ms.
4771 timeout = nextTick(() => {
4772 const snapToThreshold = 0.5;
4773 lastEventBeforeSnap = newEvent;
4774 recentWheelEvents.splice(0);
4775 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4776 }, 500);
4777 }
4778 }
4779
4780 // Emit event
4781 if (!ignoreWheelEvents) emit('scroll', e);
4782
4783 // Stop autoplay
4784 if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
4785 // Return page scroll on edge positions
4786 if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
4787 }
4788 }
4789 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
4790 return false;
4791 }
4792 function events(method) {
4793 let targetEl = swiper.el;
4794 if (swiper.params.mousewheel.eventsTarget !== 'container') {
4795 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
4796 }
4797 targetEl[method]('mouseenter', handleMouseEnter);
4798 targetEl[method]('mouseleave', handleMouseLeave);
4799 targetEl[method]('wheel', handle);
4800 }
4801 function enable() {
4802 if (swiper.params.cssMode) {
4803 swiper.wrapperEl.removeEventListener('wheel', handle);
4804 return true;
4805 }
4806 if (swiper.mousewheel.enabled) return false;
4807 events('addEventListener');
4808 swiper.mousewheel.enabled = true;
4809 return true;
4810 }
4811 function disable() {
4812 if (swiper.params.cssMode) {
4813 swiper.wrapperEl.addEventListener(event, handle);
4814 return true;
4815 }
4816 if (!swiper.mousewheel.enabled) return false;
4817 events('removeEventListener');
4818 swiper.mousewheel.enabled = false;
4819 return true;
4820 }
4821 on('init', () => {
4822 if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
4823 disable();
4824 }
4825 if (swiper.params.mousewheel.enabled) enable();
4826 });
4827 on('destroy', () => {
4828 if (swiper.params.cssMode) {
4829 enable();
4830 }
4831 if (swiper.mousewheel.enabled) disable();
4832 });
4833 Object.assign(swiper.mousewheel, {
4834 enable,
4835 disable
4836 });
4837 }
4838
4839 function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
4840 if (swiper.params.createElements) {
4841 Object.keys(checkProps).forEach(key => {
4842 if (!params[key] && params.auto === true) {
4843 let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
4844 if (!element) {
4845 element = createElement('div', checkProps[key]);
4846 element.className = checkProps[key];
4847 swiper.el.append(element);
4848 }
4849 params[key] = element;
4850 originalParams[key] = element;
4851 }
4852 });
4853 }
4854 return params;
4855 }
4856
4857 function Navigation(_ref) {
4858 let {
4859 swiper,
4860 extendParams,
4861 on,
4862 emit
4863 } = _ref;
4864 extendParams({
4865 navigation: {
4866 nextEl: null,
4867 prevEl: null,
4868 hideOnClick: false,
4869 disabledClass: 'swiper-button-disabled',
4870 hiddenClass: 'swiper-button-hidden',
4871 lockClass: 'swiper-button-lock',
4872 navigationDisabledClass: 'swiper-navigation-disabled'
4873 }
4874 });
4875 swiper.navigation = {
4876 nextEl: null,
4877 prevEl: null
4878 };
4879 const makeElementsArray = el => {
4880 if (!Array.isArray(el)) el = [el].filter(e => !!e);
4881 return el;
4882 };
4883 function getEl(el) {
4884 let res;
4885 if (el && typeof el === 'string' && swiper.isElement) {
4886 res = swiper.el.querySelector(el);
4887 if (res) return res;
4888 }
4889 if (el) {
4890 if (typeof el === 'string') res = [...document.querySelectorAll(el)];
4891 if (swiper.params.uniqueNavElements && typeof el === 'string' && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
4892 res = swiper.el.querySelector(el);
4893 }
4894 }
4895 if (el && !res) return el;
4896 // if (Array.isArray(res) && res.length === 1) res = res[0];
4897 return res;
4898 }
4899 function toggleEl(el, disabled) {
4900 const params = swiper.params.navigation;
4901 el = makeElementsArray(el);
4902 el.forEach(subEl => {
4903 if (subEl) {
4904 subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
4905 if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
4906 if (swiper.params.watchOverflow && swiper.enabled) {
4907 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
4908 }
4909 }
4910 });
4911 }
4912 function update() {
4913 // Update Navigation Buttons
4914 const {
4915 nextEl,
4916 prevEl
4917 } = swiper.navigation;
4918 if (swiper.params.loop) {
4919 toggleEl(prevEl, false);
4920 toggleEl(nextEl, false);
4921 return;
4922 }
4923 toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
4924 toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
4925 }
4926 function onPrevClick(e) {
4927 e.preventDefault();
4928 if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
4929 swiper.slidePrev();
4930 emit('navigationPrev');
4931 }
4932 function onNextClick(e) {
4933 e.preventDefault();
4934 if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
4935 swiper.slideNext();
4936 emit('navigationNext');
4937 }
4938 function init() {
4939 const params = swiper.params.navigation;
4940 swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
4941 nextEl: 'swiper-button-next',
4942 prevEl: 'swiper-button-prev'
4943 });
4944 if (!(params.nextEl || params.prevEl)) return;
4945 let nextEl = getEl(params.nextEl);
4946 let prevEl = getEl(params.prevEl);
4947 Object.assign(swiper.navigation, {
4948 nextEl,
4949 prevEl
4950 });
4951 nextEl = makeElementsArray(nextEl);
4952 prevEl = makeElementsArray(prevEl);
4953 const initButton = (el, dir) => {
4954 if (el) {
4955 el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
4956 }
4957 if (!swiper.enabled && el) {
4958 el.classList.add(...params.lockClass.split(' '));
4959 }
4960 };
4961 nextEl.forEach(el => initButton(el, 'next'));
4962 prevEl.forEach(el => initButton(el, 'prev'));
4963 }
4964 function destroy() {
4965 let {
4966 nextEl,
4967 prevEl
4968 } = swiper.navigation;
4969 nextEl = makeElementsArray(nextEl);
4970 prevEl = makeElementsArray(prevEl);
4971 const destroyButton = (el, dir) => {
4972 el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
4973 el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
4974 };
4975 nextEl.forEach(el => destroyButton(el, 'next'));
4976 prevEl.forEach(el => destroyButton(el, 'prev'));
4977 }
4978 on('init', () => {
4979 if (swiper.params.navigation.enabled === false) {
4980 // eslint-disable-next-line
4981 disable();
4982 } else {
4983 init();
4984 update();
4985 }
4986 });
4987 on('toEdge fromEdge lock unlock', () => {
4988 update();
4989 });
4990 on('destroy', () => {
4991 destroy();
4992 });
4993 on('enable disable', () => {
4994 let {
4995 nextEl,
4996 prevEl
4997 } = swiper.navigation;
4998 nextEl = makeElementsArray(nextEl);
4999 prevEl = makeElementsArray(prevEl);
5000 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.navigation.lockClass));
5001 });
5002 on('click', (_s, e) => {
5003 let {
5004 nextEl,
5005 prevEl
5006 } = swiper.navigation;
5007 nextEl = makeElementsArray(nextEl);
5008 prevEl = makeElementsArray(prevEl);
5009 const targetEl = e.target;
5010 if (swiper.params.navigation.hideOnClick && !prevEl.includes(targetEl) && !nextEl.includes(targetEl)) {
5011 if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
5012 let isHidden;
5013 if (nextEl.length) {
5014 isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5015 } else if (prevEl.length) {
5016 isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5017 }
5018 if (isHidden === true) {
5019 emit('navigationShow');
5020 } else {
5021 emit('navigationHide');
5022 }
5023 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
5024 }
5025 });
5026 const enable = () => {
5027 swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
5028 init();
5029 update();
5030 };
5031 const disable = () => {
5032 swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
5033 destroy();
5034 };
5035 Object.assign(swiper.navigation, {
5036 enable,
5037 disable,
5038 update,
5039 init,
5040 destroy
5041 });
5042 }
5043
5044 function classesToSelector(classes) {
5045 if (classes === void 0) {
5046 classes = '';
5047 }
5048 return `.${classes.trim().replace(/([\.:!+\/])/g, '\\$1') // eslint-disable-line
5049 .replace(/ /g, '.')}`;
5050 }
5051
5052 function Pagination(_ref) {
5053 let {
5054 swiper,
5055 extendParams,
5056 on,
5057 emit
5058 } = _ref;
5059 const pfx = 'swiper-pagination';
5060 extendParams({
5061 pagination: {
5062 el: null,
5063 bulletElement: 'span',
5064 clickable: false,
5065 hideOnClick: false,
5066 renderBullet: null,
5067 renderProgressbar: null,
5068 renderFraction: null,
5069 renderCustom: null,
5070 progressbarOpposite: false,
5071 type: 'bullets',
5072 // 'bullets' or 'progressbar' or 'fraction' or 'custom'
5073 dynamicBullets: false,
5074 dynamicMainBullets: 1,
5075 formatFractionCurrent: number => number,
5076 formatFractionTotal: number => number,
5077 bulletClass: `${pfx}-bullet`,
5078 bulletActiveClass: `${pfx}-bullet-active`,
5079 modifierClass: `${pfx}-`,
5080 currentClass: `${pfx}-current`,
5081 totalClass: `${pfx}-total`,
5082 hiddenClass: `${pfx}-hidden`,
5083 progressbarFillClass: `${pfx}-progressbar-fill`,
5084 progressbarOppositeClass: `${pfx}-progressbar-opposite`,
5085 clickableClass: `${pfx}-clickable`,
5086 lockClass: `${pfx}-lock`,
5087 horizontalClass: `${pfx}-horizontal`,
5088 verticalClass: `${pfx}-vertical`,
5089 paginationDisabledClass: `${pfx}-disabled`
5090 }
5091 });
5092 swiper.pagination = {
5093 el: null,
5094 bullets: []
5095 };
5096 let bulletSize;
5097 let dynamicBulletIndex = 0;
5098 const makeElementsArray = el => {
5099 if (!Array.isArray(el)) el = [el].filter(e => !!e);
5100 return el;
5101 };
5102 function isPaginationDisabled() {
5103 return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;
5104 }
5105 function setSideBullets(bulletEl, position) {
5106 const {
5107 bulletActiveClass
5108 } = swiper.params.pagination;
5109 if (!bulletEl) return;
5110 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5111 if (bulletEl) {
5112 bulletEl.classList.add(`${bulletActiveClass}-${position}`);
5113 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5114 if (bulletEl) {
5115 bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
5116 }
5117 }
5118 }
5119 function onBulletClick(e) {
5120 const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));
5121 if (!bulletEl) {
5122 return;
5123 }
5124 e.preventDefault();
5125 const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
5126 if (swiper.params.loop) {
5127 if (swiper.realIndex === index) return;
5128 const newSlideIndex = swiper.getSlideIndexByData(index);
5129 const currentSlideIndex = swiper.getSlideIndexByData(swiper.realIndex);
5130 if (newSlideIndex > swiper.slides.length - swiper.loopedSlides) {
5131 swiper.loopFix({
5132 direction: newSlideIndex > currentSlideIndex ? 'next' : 'prev',
5133 activeSlideIndex: newSlideIndex,
5134 slideTo: false
5135 });
5136 }
5137 swiper.slideToLoop(index);
5138 } else {
5139 swiper.slideTo(index);
5140 }
5141 }
5142 function update() {
5143 // Render || Update Pagination bullets/items
5144 const rtl = swiper.rtl;
5145 const params = swiper.params.pagination;
5146 if (isPaginationDisabled()) return;
5147 let el = swiper.pagination.el;
5148 el = makeElementsArray(el);
5149 // Current/Total
5150 let current;
5151 let previousIndex;
5152 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5153 const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5154 if (swiper.params.loop) {
5155 previousIndex = swiper.previousRealIndex || 0;
5156 current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;
5157 } else if (typeof swiper.snapIndex !== 'undefined') {
5158 current = swiper.snapIndex;
5159 previousIndex = swiper.previousSnapIndex;
5160 } else {
5161 previousIndex = swiper.previousIndex || 0;
5162 current = swiper.activeIndex || 0;
5163 }
5164 // Types
5165 if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
5166 const bullets = swiper.pagination.bullets;
5167 let firstIndex;
5168 let lastIndex;
5169 let midIndex;
5170 if (params.dynamicBullets) {
5171 bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);
5172 el.forEach(subEl => {
5173 subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
5174 });
5175 if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
5176 dynamicBulletIndex += current - (previousIndex || 0);
5177 if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
5178 dynamicBulletIndex = params.dynamicMainBullets - 1;
5179 } else if (dynamicBulletIndex < 0) {
5180 dynamicBulletIndex = 0;
5181 }
5182 }
5183 firstIndex = Math.max(current - dynamicBulletIndex, 0);
5184 lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
5185 midIndex = (lastIndex + firstIndex) / 2;
5186 }
5187 bullets.forEach(bulletEl => {
5188 const classesToRemove = [...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`)].map(s => typeof s === 'string' && s.includes(' ') ? s.split(' ') : s).flat();
5189 bulletEl.classList.remove(...classesToRemove);
5190 });
5191 if (el.length > 1) {
5192 bullets.forEach(bullet => {
5193 const bulletIndex = elementIndex(bullet);
5194 if (bulletIndex === current) {
5195 bullet.classList.add(...params.bulletActiveClass.split(' '));
5196 } else if (swiper.isElement) {
5197 bullet.setAttribute('part', 'bullet');
5198 }
5199 if (params.dynamicBullets) {
5200 if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
5201 bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5202 }
5203 if (bulletIndex === firstIndex) {
5204 setSideBullets(bullet, 'prev');
5205 }
5206 if (bulletIndex === lastIndex) {
5207 setSideBullets(bullet, 'next');
5208 }
5209 }
5210 });
5211 } else {
5212 const bullet = bullets[current];
5213 if (bullet) {
5214 bullet.classList.add(...params.bulletActiveClass.split(' '));
5215 }
5216 if (swiper.isElement) {
5217 bullets.forEach((bulletEl, bulletIndex) => {
5218 bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
5219 });
5220 }
5221 if (params.dynamicBullets) {
5222 const firstDisplayedBullet = bullets[firstIndex];
5223 const lastDisplayedBullet = bullets[lastIndex];
5224 for (let i = firstIndex; i <= lastIndex; i += 1) {
5225 if (bullets[i]) {
5226 bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5227 }
5228 }
5229 setSideBullets(firstDisplayedBullet, 'prev');
5230 setSideBullets(lastDisplayedBullet, 'next');
5231 }
5232 }
5233 if (params.dynamicBullets) {
5234 const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
5235 const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
5236 const offsetProp = rtl ? 'right' : 'left';
5237 bullets.forEach(bullet => {
5238 bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
5239 });
5240 }
5241 }
5242 el.forEach((subEl, subElIndex) => {
5243 if (params.type === 'fraction') {
5244 subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach(fractionEl => {
5245 fractionEl.textContent = params.formatFractionCurrent(current + 1);
5246 });
5247 subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach(totalEl => {
5248 totalEl.textContent = params.formatFractionTotal(total);
5249 });
5250 }
5251 if (params.type === 'progressbar') {
5252 let progressbarDirection;
5253 if (params.progressbarOpposite) {
5254 progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
5255 } else {
5256 progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
5257 }
5258 const scale = (current + 1) / total;
5259 let scaleX = 1;
5260 let scaleY = 1;
5261 if (progressbarDirection === 'horizontal') {
5262 scaleX = scale;
5263 } else {
5264 scaleY = scale;
5265 }
5266 subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach(progressEl => {
5267 progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
5268 progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
5269 });
5270 }
5271 if (params.type === 'custom' && params.renderCustom) {
5272 subEl.innerHTML = params.renderCustom(swiper, current + 1, total);
5273 if (subElIndex === 0) emit('paginationRender', subEl);
5274 } else {
5275 if (subElIndex === 0) emit('paginationRender', subEl);
5276 emit('paginationUpdate', subEl);
5277 }
5278 if (swiper.params.watchOverflow && swiper.enabled) {
5279 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
5280 }
5281 });
5282 }
5283 function render() {
5284 // Render Container
5285 const params = swiper.params.pagination;
5286 if (isPaginationDisabled()) return;
5287 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5288 let el = swiper.pagination.el;
5289 el = makeElementsArray(el);
5290 let paginationHTML = '';
5291 if (params.type === 'bullets') {
5292 let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5293 if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
5294 numberOfBullets = slidesLength;
5295 }
5296 for (let i = 0; i < numberOfBullets; i += 1) {
5297 if (params.renderBullet) {
5298 paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
5299 } else {
5300 // prettier-ignore
5301 paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
5302 }
5303 }
5304 }
5305 if (params.type === 'fraction') {
5306 if (params.renderFraction) {
5307 paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
5308 } else {
5309 paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
5310 }
5311 }
5312 if (params.type === 'progressbar') {
5313 if (params.renderProgressbar) {
5314 paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
5315 } else {
5316 paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
5317 }
5318 }
5319 swiper.pagination.bullets = [];
5320 el.forEach(subEl => {
5321 if (params.type !== 'custom') {
5322 subEl.innerHTML = paginationHTML || '';
5323 }
5324 if (params.type === 'bullets') {
5325 swiper.pagination.bullets.push(...subEl.querySelectorAll(classesToSelector(params.bulletClass)));
5326 }
5327 });
5328 if (params.type !== 'custom') {
5329 emit('paginationRender', el[0]);
5330 }
5331 }
5332 function init() {
5333 swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
5334 el: 'swiper-pagination'
5335 });
5336 const params = swiper.params.pagination;
5337 if (!params.el) return;
5338 let el;
5339 if (typeof params.el === 'string' && swiper.isElement) {
5340 el = swiper.el.querySelector(params.el);
5341 }
5342 if (!el && typeof params.el === 'string') {
5343 el = [...document.querySelectorAll(params.el)];
5344 }
5345 if (!el) {
5346 el = params.el;
5347 }
5348 if (!el || el.length === 0) return;
5349 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
5350 el = [...swiper.el.querySelectorAll(params.el)];
5351 // check if it belongs to another nested Swiper
5352 if (el.length > 1) {
5353 el = el.filter(subEl => {
5354 if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
5355 return true;
5356 })[0];
5357 }
5358 }
5359 if (Array.isArray(el) && el.length === 1) el = el[0];
5360 Object.assign(swiper.pagination, {
5361 el
5362 });
5363 el = makeElementsArray(el);
5364 el.forEach(subEl => {
5365 if (params.type === 'bullets' && params.clickable) {
5366 subEl.classList.add(params.clickableClass);
5367 }
5368 subEl.classList.add(params.modifierClass + params.type);
5369 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5370 if (params.type === 'bullets' && params.dynamicBullets) {
5371 subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
5372 dynamicBulletIndex = 0;
5373 if (params.dynamicMainBullets < 1) {
5374 params.dynamicMainBullets = 1;
5375 }
5376 }
5377 if (params.type === 'progressbar' && params.progressbarOpposite) {
5378 subEl.classList.add(params.progressbarOppositeClass);
5379 }
5380 if (params.clickable) {
5381 subEl.addEventListener('click', onBulletClick);
5382 }
5383 if (!swiper.enabled) {
5384 subEl.classList.add(params.lockClass);
5385 }
5386 });
5387 }
5388 function destroy() {
5389 const params = swiper.params.pagination;
5390 if (isPaginationDisabled()) return;
5391 let el = swiper.pagination.el;
5392 if (el) {
5393 el = makeElementsArray(el);
5394 el.forEach(subEl => {
5395 subEl.classList.remove(params.hiddenClass);
5396 subEl.classList.remove(params.modifierClass + params.type);
5397 subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5398 if (params.clickable) {
5399 subEl.removeEventListener('click', onBulletClick);
5400 }
5401 });
5402 }
5403 if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
5404 }
5405 on('changeDirection', () => {
5406 if (!swiper.pagination || !swiper.pagination.el) return;
5407 const params = swiper.params.pagination;
5408 let {
5409 el
5410 } = swiper.pagination;
5411 el = makeElementsArray(el);
5412 el.forEach(subEl => {
5413 subEl.classList.remove(params.horizontalClass, params.verticalClass);
5414 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5415 });
5416 });
5417 on('init', () => {
5418 if (swiper.params.pagination.enabled === false) {
5419 // eslint-disable-next-line
5420 disable();
5421 } else {
5422 init();
5423 render();
5424 update();
5425 }
5426 });
5427 on('activeIndexChange', () => {
5428 if (typeof swiper.snapIndex === 'undefined') {
5429 update();
5430 }
5431 });
5432 on('snapIndexChange', () => {
5433 update();
5434 });
5435 on('snapGridLengthChange', () => {
5436 render();
5437 update();
5438 });
5439 on('destroy', () => {
5440 destroy();
5441 });
5442 on('enable disable', () => {
5443 let {
5444 el
5445 } = swiper.pagination;
5446 if (el) {
5447 el = makeElementsArray(el);
5448 el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
5449 }
5450 });
5451 on('lock unlock', () => {
5452 update();
5453 });
5454 on('click', (_s, e) => {
5455 const targetEl = e.target;
5456 const el = makeElementsArray(swiper.pagination.el);
5457 if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {
5458 if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
5459 const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
5460 if (isHidden === true) {
5461 emit('paginationShow');
5462 } else {
5463 emit('paginationHide');
5464 }
5465 el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
5466 }
5467 });
5468 const enable = () => {
5469 swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
5470 let {
5471 el
5472 } = swiper.pagination;
5473 if (el) {
5474 el = makeElementsArray(el);
5475 el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
5476 }
5477 init();
5478 render();
5479 update();
5480 };
5481 const disable = () => {
5482 swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
5483 let {
5484 el
5485 } = swiper.pagination;
5486 if (el) {
5487 el = makeElementsArray(el);
5488 el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
5489 }
5490 destroy();
5491 };
5492 Object.assign(swiper.pagination, {
5493 enable,
5494 disable,
5495 render,
5496 update,
5497 init,
5498 destroy
5499 });
5500 }
5501
5502 function Scrollbar(_ref) {
5503 let {
5504 swiper,
5505 extendParams,
5506 on,
5507 emit
5508 } = _ref;
5509 const document = getDocument();
5510 let isTouched = false;
5511 let timeout = null;
5512 let dragTimeout = null;
5513 let dragStartPos;
5514 let dragSize;
5515 let trackSize;
5516 let divider;
5517 extendParams({
5518 scrollbar: {
5519 el: null,
5520 dragSize: 'auto',
5521 hide: false,
5522 draggable: false,
5523 snapOnRelease: true,
5524 lockClass: 'swiper-scrollbar-lock',
5525 dragClass: 'swiper-scrollbar-drag',
5526 scrollbarDisabledClass: 'swiper-scrollbar-disabled',
5527 horizontalClass: `swiper-scrollbar-horizontal`,
5528 verticalClass: `swiper-scrollbar-vertical`
5529 }
5530 });
5531 swiper.scrollbar = {
5532 el: null,
5533 dragEl: null
5534 };
5535 function setTranslate() {
5536 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5537 const {
5538 scrollbar,
5539 rtlTranslate: rtl
5540 } = swiper;
5541 const {
5542 dragEl,
5543 el
5544 } = scrollbar;
5545 const params = swiper.params.scrollbar;
5546 const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
5547 let newSize = dragSize;
5548 let newPos = (trackSize - dragSize) * progress;
5549 if (rtl) {
5550 newPos = -newPos;
5551 if (newPos > 0) {
5552 newSize = dragSize - newPos;
5553 newPos = 0;
5554 } else if (-newPos + dragSize > trackSize) {
5555 newSize = trackSize + newPos;
5556 }
5557 } else if (newPos < 0) {
5558 newSize = dragSize + newPos;
5559 newPos = 0;
5560 } else if (newPos + dragSize > trackSize) {
5561 newSize = trackSize - newPos;
5562 }
5563 if (swiper.isHorizontal()) {
5564 dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
5565 dragEl.style.width = `${newSize}px`;
5566 } else {
5567 dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
5568 dragEl.style.height = `${newSize}px`;
5569 }
5570 if (params.hide) {
5571 clearTimeout(timeout);
5572 el.style.opacity = 1;
5573 timeout = setTimeout(() => {
5574 el.style.opacity = 0;
5575 el.style.transitionDuration = '400ms';
5576 }, 1000);
5577 }
5578 }
5579 function setTransition(duration) {
5580 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5581 swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
5582 }
5583 function updateSize() {
5584 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5585 const {
5586 scrollbar
5587 } = swiper;
5588 const {
5589 dragEl,
5590 el
5591 } = scrollbar;
5592 dragEl.style.width = '';
5593 dragEl.style.height = '';
5594 trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
5595 divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
5596 if (swiper.params.scrollbar.dragSize === 'auto') {
5597 dragSize = trackSize * divider;
5598 } else {
5599 dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
5600 }
5601 if (swiper.isHorizontal()) {
5602 dragEl.style.width = `${dragSize}px`;
5603 } else {
5604 dragEl.style.height = `${dragSize}px`;
5605 }
5606 if (divider >= 1) {
5607 el.style.display = 'none';
5608 } else {
5609 el.style.display = '';
5610 }
5611 if (swiper.params.scrollbar.hide) {
5612 el.style.opacity = 0;
5613 }
5614 if (swiper.params.watchOverflow && swiper.enabled) {
5615 scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
5616 }
5617 }
5618 function getPointerPosition(e) {
5619 return swiper.isHorizontal() ? e.clientX : e.clientY;
5620 }
5621 function setDragPosition(e) {
5622 const {
5623 scrollbar,
5624 rtlTranslate: rtl
5625 } = swiper;
5626 const {
5627 el
5628 } = scrollbar;
5629 let positionRatio;
5630 positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
5631 positionRatio = Math.max(Math.min(positionRatio, 1), 0);
5632 if (rtl) {
5633 positionRatio = 1 - positionRatio;
5634 }
5635 const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
5636 swiper.updateProgress(position);
5637 swiper.setTranslate(position);
5638 swiper.updateActiveIndex();
5639 swiper.updateSlidesClasses();
5640 }
5641 function onDragStart(e) {
5642 const params = swiper.params.scrollbar;
5643 const {
5644 scrollbar,
5645 wrapperEl
5646 } = swiper;
5647 const {
5648 el,
5649 dragEl
5650 } = scrollbar;
5651 isTouched = true;
5652 dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
5653 e.preventDefault();
5654 e.stopPropagation();
5655 wrapperEl.style.transitionDuration = '100ms';
5656 dragEl.style.transitionDuration = '100ms';
5657 setDragPosition(e);
5658 clearTimeout(dragTimeout);
5659 el.style.transitionDuration = '0ms';
5660 if (params.hide) {
5661 el.style.opacity = 1;
5662 }
5663 if (swiper.params.cssMode) {
5664 swiper.wrapperEl.style['scroll-snap-type'] = 'none';
5665 }
5666 emit('scrollbarDragStart', e);
5667 }
5668 function onDragMove(e) {
5669 const {
5670 scrollbar,
5671 wrapperEl
5672 } = swiper;
5673 const {
5674 el,
5675 dragEl
5676 } = scrollbar;
5677 if (!isTouched) return;
5678 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
5679 setDragPosition(e);
5680 wrapperEl.style.transitionDuration = '0ms';
5681 el.style.transitionDuration = '0ms';
5682 dragEl.style.transitionDuration = '0ms';
5683 emit('scrollbarDragMove', e);
5684 }
5685 function onDragEnd(e) {
5686 const params = swiper.params.scrollbar;
5687 const {
5688 scrollbar,
5689 wrapperEl
5690 } = swiper;
5691 const {
5692 el
5693 } = scrollbar;
5694 if (!isTouched) return;
5695 isTouched = false;
5696 if (swiper.params.cssMode) {
5697 swiper.wrapperEl.style['scroll-snap-type'] = '';
5698 wrapperEl.style.transitionDuration = '';
5699 }
5700 if (params.hide) {
5701 clearTimeout(dragTimeout);
5702 dragTimeout = nextTick(() => {
5703 el.style.opacity = 0;
5704 el.style.transitionDuration = '400ms';
5705 }, 1000);
5706 }
5707 emit('scrollbarDragEnd', e);
5708 if (params.snapOnRelease) {
5709 swiper.slideToClosest();
5710 }
5711 }
5712 function events(method) {
5713 const {
5714 scrollbar,
5715 params
5716 } = swiper;
5717 const el = scrollbar.el;
5718 if (!el) return;
5719 const target = el;
5720 const activeListener = params.passiveListeners ? {
5721 passive: false,
5722 capture: false
5723 } : false;
5724 const passiveListener = params.passiveListeners ? {
5725 passive: true,
5726 capture: false
5727 } : false;
5728 if (!target) return;
5729 const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
5730 target[eventMethod]('pointerdown', onDragStart, activeListener);
5731 document[eventMethod]('pointermove', onDragMove, activeListener);
5732 document[eventMethod]('pointerup', onDragEnd, passiveListener);
5733 }
5734 function enableDraggable() {
5735 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5736 events('on');
5737 }
5738 function disableDraggable() {
5739 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5740 events('off');
5741 }
5742 function init() {
5743 const {
5744 scrollbar,
5745 el: swiperEl
5746 } = swiper;
5747 swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {
5748 el: 'swiper-scrollbar'
5749 });
5750 const params = swiper.params.scrollbar;
5751 if (!params.el) return;
5752 let el;
5753 if (typeof params.el === 'string' && swiper.isElement) {
5754 el = swiper.el.querySelector(params.el);
5755 }
5756 if (!el && typeof params.el === 'string') {
5757 el = document.querySelectorAll(params.el);
5758 } else if (!el) {
5759 el = params.el;
5760 }
5761 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) {
5762 el = swiperEl.querySelector(params.el);
5763 }
5764 if (el.length > 0) el = el[0];
5765 el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5766 let dragEl;
5767 if (el) {
5768 dragEl = el.querySelector(`.${swiper.params.scrollbar.dragClass}`);
5769 if (!dragEl) {
5770 dragEl = createElement('div', swiper.params.scrollbar.dragClass);
5771 el.append(dragEl);
5772 }
5773 }
5774 Object.assign(scrollbar, {
5775 el,
5776 dragEl
5777 });
5778 if (params.draggable) {
5779 enableDraggable();
5780 }
5781 if (el) {
5782 el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.scrollbar.lockClass);
5783 }
5784 }
5785 function destroy() {
5786 const params = swiper.params.scrollbar;
5787 const el = swiper.scrollbar.el;
5788 if (el) {
5789 el.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5790 }
5791 disableDraggable();
5792 }
5793 on('init', () => {
5794 if (swiper.params.scrollbar.enabled === false) {
5795 // eslint-disable-next-line
5796 disable();
5797 } else {
5798 init();
5799 updateSize();
5800 setTranslate();
5801 }
5802 });
5803 on('update resize observerUpdate lock unlock', () => {
5804 updateSize();
5805 });
5806 on('setTranslate', () => {
5807 setTranslate();
5808 });
5809 on('setTransition', (_s, duration) => {
5810 setTransition(duration);
5811 });
5812 on('enable disable', () => {
5813 const {
5814 el
5815 } = swiper.scrollbar;
5816 if (el) {
5817 el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.scrollbar.lockClass);
5818 }
5819 });
5820 on('destroy', () => {
5821 destroy();
5822 });
5823 const enable = () => {
5824 swiper.el.classList.remove(swiper.params.scrollbar.scrollbarDisabledClass);
5825 if (swiper.scrollbar.el) {
5826 swiper.scrollbar.el.classList.remove(swiper.params.scrollbar.scrollbarDisabledClass);
5827 }
5828 init();
5829 updateSize();
5830 setTranslate();
5831 };
5832 const disable = () => {
5833 swiper.el.classList.add(swiper.params.scrollbar.scrollbarDisabledClass);
5834 if (swiper.scrollbar.el) {
5835 swiper.scrollbar.el.classList.add(swiper.params.scrollbar.scrollbarDisabledClass);
5836 }
5837 destroy();
5838 };
5839 Object.assign(swiper.scrollbar, {
5840 enable,
5841 disable,
5842 updateSize,
5843 setTranslate,
5844 init,
5845 destroy
5846 });
5847 }
5848
5849 function Parallax(_ref) {
5850 let {
5851 swiper,
5852 extendParams,
5853 on
5854 } = _ref;
5855 extendParams({
5856 parallax: {
5857 enabled: false
5858 }
5859 });
5860 const setTransform = (el, progress) => {
5861 const {
5862 rtl
5863 } = swiper;
5864 const rtlFactor = rtl ? -1 : 1;
5865 const p = el.getAttribute('data-swiper-parallax') || '0';
5866 let x = el.getAttribute('data-swiper-parallax-x');
5867 let y = el.getAttribute('data-swiper-parallax-y');
5868 const scale = el.getAttribute('data-swiper-parallax-scale');
5869 const opacity = el.getAttribute('data-swiper-parallax-opacity');
5870 const rotate = el.getAttribute('data-swiper-parallax-rotate');
5871 if (x || y) {
5872 x = x || '0';
5873 y = y || '0';
5874 } else if (swiper.isHorizontal()) {
5875 x = p;
5876 y = '0';
5877 } else {
5878 y = p;
5879 x = '0';
5880 }
5881 if (x.indexOf('%') >= 0) {
5882 x = `${parseInt(x, 10) * progress * rtlFactor}%`;
5883 } else {
5884 x = `${x * progress * rtlFactor}px`;
5885 }
5886 if (y.indexOf('%') >= 0) {
5887 y = `${parseInt(y, 10) * progress}%`;
5888 } else {
5889 y = `${y * progress}px`;
5890 }
5891 if (typeof opacity !== 'undefined' && opacity !== null) {
5892 const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
5893 el.style.opacity = currentOpacity;
5894 }
5895 let transform = `translate3d(${x}, ${y}, 0px)`;
5896 if (typeof scale !== 'undefined' && scale !== null) {
5897 const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
5898 transform += ` scale(${currentScale})`;
5899 }
5900 if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
5901 const currentRotate = rotate * progress * -1;
5902 transform += ` rotate(${currentRotate}deg)`;
5903 }
5904 el.style.transform = transform;
5905 };
5906 const setTranslate = () => {
5907 const {
5908 el,
5909 slides,
5910 progress,
5911 snapGrid
5912 } = swiper;
5913 elementChildren(el, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(subEl => {
5914 setTransform(subEl, progress);
5915 });
5916 slides.forEach((slideEl, slideIndex) => {
5917 let slideProgress = slideEl.progress;
5918 if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
5919 slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
5920 }
5921 slideProgress = Math.min(Math.max(slideProgress, -1), 1);
5922 slideEl.querySelectorAll('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale], [data-swiper-parallax-rotate]').forEach(subEl => {
5923 setTransform(subEl, slideProgress);
5924 });
5925 });
5926 };
5927 const setTransition = function (duration) {
5928 if (duration === void 0) {
5929 duration = swiper.params.speed;
5930 }
5931 const {
5932 el
5933 } = swiper;
5934 el.querySelectorAll('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').forEach(parallaxEl => {
5935 let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
5936 if (duration === 0) parallaxDuration = 0;
5937 parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
5938 });
5939 };
5940 on('beforeInit', () => {
5941 if (!swiper.params.parallax.enabled) return;
5942 swiper.params.watchSlidesProgress = true;
5943 swiper.originalParams.watchSlidesProgress = true;
5944 });
5945 on('init', () => {
5946 if (!swiper.params.parallax.enabled) return;
5947 setTranslate();
5948 });
5949 on('setTranslate', () => {
5950 if (!swiper.params.parallax.enabled) return;
5951 setTranslate();
5952 });
5953 on('setTransition', (_swiper, duration) => {
5954 if (!swiper.params.parallax.enabled) return;
5955 setTransition(duration);
5956 });
5957 }
5958
5959 function Zoom(_ref) {
5960 let {
5961 swiper,
5962 extendParams,
5963 on,
5964 emit
5965 } = _ref;
5966 const window = getWindow();
5967 extendParams({
5968 zoom: {
5969 enabled: false,
5970 maxRatio: 3,
5971 minRatio: 1,
5972 toggle: true,
5973 containerClass: 'swiper-zoom-container',
5974 zoomedSlideClass: 'swiper-slide-zoomed'
5975 }
5976 });
5977 swiper.zoom = {
5978 enabled: false
5979 };
5980 let currentScale = 1;
5981 let isScaling = false;
5982 let fakeGestureTouched;
5983 let fakeGestureMoved;
5984 const evCache = [];
5985 const gesture = {
5986 originX: 0,
5987 originY: 0,
5988 slideEl: undefined,
5989 slideWidth: undefined,
5990 slideHeight: undefined,
5991 imageEl: undefined,
5992 imageWrapEl: undefined,
5993 maxRatio: 3
5994 };
5995 const image = {
5996 isTouched: undefined,
5997 isMoved: undefined,
5998 currentX: undefined,
5999 currentY: undefined,
6000 minX: undefined,
6001 minY: undefined,
6002 maxX: undefined,
6003 maxY: undefined,
6004 width: undefined,
6005 height: undefined,
6006 startX: undefined,
6007 startY: undefined,
6008 touchesStart: {},
6009 touchesCurrent: {}
6010 };
6011 const velocity = {
6012 x: undefined,
6013 y: undefined,
6014 prevPositionX: undefined,
6015 prevPositionY: undefined,
6016 prevTime: undefined
6017 };
6018 let scale = 1;
6019 Object.defineProperty(swiper.zoom, 'scale', {
6020 get() {
6021 return scale;
6022 },
6023 set(value) {
6024 if (scale !== value) {
6025 const imageEl = gesture.imageEl;
6026 const slideEl = gesture.slideEl;
6027 emit('zoomChange', value, imageEl, slideEl);
6028 }
6029 scale = value;
6030 }
6031 });
6032 function getDistanceBetweenTouches() {
6033 if (evCache.length < 2) return 1;
6034 const x1 = evCache[0].pageX;
6035 const y1 = evCache[0].pageY;
6036 const x2 = evCache[1].pageX;
6037 const y2 = evCache[1].pageY;
6038 const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
6039 return distance;
6040 }
6041 function getScaleOrigin() {
6042 if (evCache.length < 2) return {
6043 x: null,
6044 y: null
6045 };
6046 const box = gesture.imageEl.getBoundingClientRect();
6047 return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y) / currentScale];
6048 }
6049 function getSlideSelector() {
6050 return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
6051 }
6052 function eventWithinSlide(e) {
6053 const slideSelector = getSlideSelector();
6054 if (e.target.matches(slideSelector)) return true;
6055 if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;
6056 return false;
6057 }
6058 function eventWithinZoomContainer(e) {
6059 const selector = `.${swiper.params.zoom.containerClass}`;
6060 if (e.target.matches(selector)) return true;
6061 if ([...swiper.el.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;
6062 return false;
6063 }
6064
6065 // Events
6066 function onGestureStart(e) {
6067 if (e.pointerType === 'mouse') {
6068 evCache.splice(0, evCache.length);
6069 }
6070 if (!eventWithinSlide(e)) return;
6071 const params = swiper.params.zoom;
6072 fakeGestureTouched = false;
6073 fakeGestureMoved = false;
6074 evCache.push(e);
6075 if (evCache.length < 2) {
6076 return;
6077 }
6078 fakeGestureTouched = true;
6079 gesture.scaleStart = getDistanceBetweenTouches();
6080 if (!gesture.slideEl) {
6081 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6082 if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
6083 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6084 if (imageEl) {
6085 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6086 }
6087 gesture.imageEl = imageEl;
6088 if (imageEl) {
6089 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6090 } else {
6091 gesture.imageWrapEl = undefined;
6092 }
6093 if (!gesture.imageWrapEl) {
6094 gesture.imageEl = undefined;
6095 return;
6096 }
6097 gesture.maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6098 }
6099 if (gesture.imageEl) {
6100 const [originX, originY] = getScaleOrigin();
6101 gesture.originX = originX;
6102 gesture.originY = originY;
6103 gesture.imageEl.style.transitionDuration = '0ms';
6104 }
6105 isScaling = true;
6106 }
6107 function onGestureChange(e) {
6108 if (!eventWithinSlide(e)) return;
6109 const params = swiper.params.zoom;
6110 const zoom = swiper.zoom;
6111 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
6112 if (pointerIndex >= 0) evCache[pointerIndex] = e;
6113 if (evCache.length < 2) {
6114 return;
6115 }
6116 fakeGestureMoved = true;
6117 gesture.scaleMove = getDistanceBetweenTouches();
6118 if (!gesture.imageEl) {
6119 return;
6120 }
6121 zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;
6122 if (zoom.scale > gesture.maxRatio) {
6123 zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
6124 }
6125 if (zoom.scale < params.minRatio) {
6126 zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
6127 }
6128 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6129 }
6130 function onGestureEnd(e) {
6131 if (!eventWithinSlide(e)) return;
6132 if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
6133 const params = swiper.params.zoom;
6134 const zoom = swiper.zoom;
6135 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
6136 if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
6137 if (!fakeGestureTouched || !fakeGestureMoved) {
6138 return;
6139 }
6140 fakeGestureTouched = false;
6141 fakeGestureMoved = false;
6142 if (!gesture.imageEl) return;
6143 zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
6144 gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
6145 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6146 currentScale = zoom.scale;
6147 isScaling = false;
6148 if (zoom.scale > 1 && gesture.slideEl) {
6149 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6150 } else if (zoom.scale <= 1 && gesture.slideEl) {
6151 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6152 }
6153 if (zoom.scale === 1) {
6154 gesture.originX = 0;
6155 gesture.originY = 0;
6156 gesture.slideEl = undefined;
6157 }
6158 }
6159 function onTouchStart(e) {
6160 const device = swiper.device;
6161 if (!gesture.imageEl) return;
6162 if (image.isTouched) return;
6163 if (device.android && e.cancelable) e.preventDefault();
6164 image.isTouched = true;
6165 const event = evCache.length > 0 ? evCache[0] : e;
6166 image.touchesStart.x = event.pageX;
6167 image.touchesStart.y = event.pageY;
6168 }
6169 function onTouchMove(e) {
6170 if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
6171 const zoom = swiper.zoom;
6172 if (!gesture.imageEl) return;
6173 if (!image.isTouched || !gesture.slideEl) return;
6174 if (!image.isMoved) {
6175 image.width = gesture.imageEl.offsetWidth;
6176 image.height = gesture.imageEl.offsetHeight;
6177 image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
6178 image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
6179 gesture.slideWidth = gesture.slideEl.offsetWidth;
6180 gesture.slideHeight = gesture.slideEl.offsetHeight;
6181 gesture.imageWrapEl.style.transitionDuration = '0ms';
6182 }
6183 // Define if we need image drag
6184 const scaledWidth = image.width * zoom.scale;
6185 const scaledHeight = image.height * zoom.scale;
6186 if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;
6187 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6188 image.maxX = -image.minX;
6189 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6190 image.maxY = -image.minY;
6191 image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
6192 image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
6193 const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y));
6194 if (touchesDiff > 5) {
6195 swiper.allowClick = false;
6196 }
6197 if (!image.isMoved && !isScaling) {
6198 if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {
6199 image.isTouched = false;
6200 return;
6201 }
6202 if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {
6203 image.isTouched = false;
6204 return;
6205 }
6206 }
6207 if (e.cancelable) {
6208 e.preventDefault();
6209 }
6210 e.stopPropagation();
6211 image.isMoved = true;
6212 const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
6213 const {
6214 originX,
6215 originY
6216 } = gesture;
6217 image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
6218 image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
6219 if (image.currentX < image.minX) {
6220 image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
6221 }
6222 if (image.currentX > image.maxX) {
6223 image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
6224 }
6225 if (image.currentY < image.minY) {
6226 image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
6227 }
6228 if (image.currentY > image.maxY) {
6229 image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
6230 }
6231
6232 // Velocity
6233 if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
6234 if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
6235 if (!velocity.prevTime) velocity.prevTime = Date.now();
6236 velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
6237 velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
6238 if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
6239 if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
6240 velocity.prevPositionX = image.touchesCurrent.x;
6241 velocity.prevPositionY = image.touchesCurrent.y;
6242 velocity.prevTime = Date.now();
6243 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6244 }
6245 function onTouchEnd() {
6246 const zoom = swiper.zoom;
6247 if (!gesture.imageEl) return;
6248 if (!image.isTouched || !image.isMoved) {
6249 image.isTouched = false;
6250 image.isMoved = false;
6251 return;
6252 }
6253 image.isTouched = false;
6254 image.isMoved = false;
6255 let momentumDurationX = 300;
6256 let momentumDurationY = 300;
6257 const momentumDistanceX = velocity.x * momentumDurationX;
6258 const newPositionX = image.currentX + momentumDistanceX;
6259 const momentumDistanceY = velocity.y * momentumDurationY;
6260 const newPositionY = image.currentY + momentumDistanceY;
6261
6262 // Fix duration
6263 if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
6264 if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
6265 const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
6266 image.currentX = newPositionX;
6267 image.currentY = newPositionY;
6268 // Define if we need image drag
6269 const scaledWidth = image.width * zoom.scale;
6270 const scaledHeight = image.height * zoom.scale;
6271 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6272 image.maxX = -image.minX;
6273 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6274 image.maxY = -image.minY;
6275 image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
6276 image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
6277 gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
6278 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6279 }
6280 function onTransitionEnd() {
6281 const zoom = swiper.zoom;
6282 if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
6283 if (gesture.imageEl) {
6284 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6285 }
6286 if (gesture.imageWrapEl) {
6287 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6288 }
6289 gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
6290 zoom.scale = 1;
6291 currentScale = 1;
6292 gesture.slideEl = undefined;
6293 gesture.imageEl = undefined;
6294 gesture.imageWrapEl = undefined;
6295 gesture.originX = 0;
6296 gesture.originY = 0;
6297 }
6298 }
6299 function zoomIn(e) {
6300 const zoom = swiper.zoom;
6301 const params = swiper.params.zoom;
6302 if (!gesture.slideEl) {
6303 if (e && e.target) {
6304 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6305 }
6306 if (!gesture.slideEl) {
6307 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6308 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6309 } else {
6310 gesture.slideEl = swiper.slides[swiper.activeIndex];
6311 }
6312 }
6313 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6314 if (imageEl) {
6315 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6316 }
6317 gesture.imageEl = imageEl;
6318 if (imageEl) {
6319 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6320 } else {
6321 gesture.imageWrapEl = undefined;
6322 }
6323 }
6324 if (!gesture.imageEl || !gesture.imageWrapEl) return;
6325 if (swiper.params.cssMode) {
6326 swiper.wrapperEl.style.overflow = 'hidden';
6327 swiper.wrapperEl.style.touchAction = 'none';
6328 }
6329 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6330 let touchX;
6331 let touchY;
6332 let offsetX;
6333 let offsetY;
6334 let diffX;
6335 let diffY;
6336 let translateX;
6337 let translateY;
6338 let imageWidth;
6339 let imageHeight;
6340 let scaledWidth;
6341 let scaledHeight;
6342 let translateMinX;
6343 let translateMinY;
6344 let translateMaxX;
6345 let translateMaxY;
6346 let slideWidth;
6347 let slideHeight;
6348 if (typeof image.touchesStart.x === 'undefined' && e) {
6349 touchX = e.pageX;
6350 touchY = e.pageY;
6351 } else {
6352 touchX = image.touchesStart.x;
6353 touchY = image.touchesStart.y;
6354 }
6355 const forceZoomRatio = typeof e === 'number' ? e : null;
6356 if (currentScale === 1 && forceZoomRatio) {
6357 touchX = undefined;
6358 touchY = undefined;
6359 }
6360 zoom.scale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6361 currentScale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6362 if (e && !(currentScale === 1 && forceZoomRatio)) {
6363 slideWidth = gesture.slideEl.offsetWidth;
6364 slideHeight = gesture.slideEl.offsetHeight;
6365 offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
6366 offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
6367 diffX = offsetX + slideWidth / 2 - touchX;
6368 diffY = offsetY + slideHeight / 2 - touchY;
6369 imageWidth = gesture.imageEl.offsetWidth;
6370 imageHeight = gesture.imageEl.offsetHeight;
6371 scaledWidth = imageWidth * zoom.scale;
6372 scaledHeight = imageHeight * zoom.scale;
6373 translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
6374 translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
6375 translateMaxX = -translateMinX;
6376 translateMaxY = -translateMinY;
6377 translateX = diffX * zoom.scale;
6378 translateY = diffY * zoom.scale;
6379 if (translateX < translateMinX) {
6380 translateX = translateMinX;
6381 }
6382 if (translateX > translateMaxX) {
6383 translateX = translateMaxX;
6384 }
6385 if (translateY < translateMinY) {
6386 translateY = translateMinY;
6387 }
6388 if (translateY > translateMaxY) {
6389 translateY = translateMaxY;
6390 }
6391 } else {
6392 translateX = 0;
6393 translateY = 0;
6394 }
6395 if (forceZoomRatio && zoom.scale === 1) {
6396 gesture.originX = 0;
6397 gesture.originY = 0;
6398 }
6399 gesture.imageWrapEl.style.transitionDuration = '300ms';
6400 gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
6401 gesture.imageEl.style.transitionDuration = '300ms';
6402 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6403 }
6404 function zoomOut() {
6405 const zoom = swiper.zoom;
6406 const params = swiper.params.zoom;
6407 if (!gesture.slideEl) {
6408 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6409 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6410 } else {
6411 gesture.slideEl = swiper.slides[swiper.activeIndex];
6412 }
6413 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6414 if (imageEl) {
6415 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6416 }
6417 gesture.imageEl = imageEl;
6418 if (imageEl) {
6419 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6420 } else {
6421 gesture.imageWrapEl = undefined;
6422 }
6423 }
6424 if (!gesture.imageEl || !gesture.imageWrapEl) return;
6425 if (swiper.params.cssMode) {
6426 swiper.wrapperEl.style.overflow = '';
6427 swiper.wrapperEl.style.touchAction = '';
6428 }
6429 zoom.scale = 1;
6430 currentScale = 1;
6431 gesture.imageWrapEl.style.transitionDuration = '300ms';
6432 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6433 gesture.imageEl.style.transitionDuration = '300ms';
6434 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6435 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6436 gesture.slideEl = undefined;
6437 gesture.originX = 0;
6438 gesture.originY = 0;
6439 }
6440
6441 // Toggle Zoom
6442 function zoomToggle(e) {
6443 const zoom = swiper.zoom;
6444 if (zoom.scale && zoom.scale !== 1) {
6445 // Zoom Out
6446 zoomOut();
6447 } else {
6448 // Zoom In
6449 zoomIn(e);
6450 }
6451 }
6452 function getListeners() {
6453 const passiveListener = swiper.params.passiveListeners ? {
6454 passive: true,
6455 capture: false
6456 } : false;
6457 const activeListenerWithCapture = swiper.params.passiveListeners ? {
6458 passive: false,
6459 capture: true
6460 } : true;
6461 return {
6462 passiveListener,
6463 activeListenerWithCapture
6464 };
6465 }
6466
6467 // Attach/Detach Events
6468 function enable() {
6469 const zoom = swiper.zoom;
6470 if (zoom.enabled) return;
6471 zoom.enabled = true;
6472 const {
6473 passiveListener,
6474 activeListenerWithCapture
6475 } = getListeners();
6476
6477 // Scale image
6478 swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
6479 swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6480 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
6481 swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
6482 });
6483
6484 // Move image
6485 swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6486 }
6487 function disable() {
6488 const zoom = swiper.zoom;
6489 if (!zoom.enabled) return;
6490 zoom.enabled = false;
6491 const {
6492 passiveListener,
6493 activeListenerWithCapture
6494 } = getListeners();
6495
6496 // Scale image
6497 swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
6498 swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6499 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
6500 swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
6501 });
6502
6503 // Move image
6504 swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6505 }
6506 on('init', () => {
6507 if (swiper.params.zoom.enabled) {
6508 enable();
6509 }
6510 });
6511 on('destroy', () => {
6512 disable();
6513 });
6514 on('touchStart', (_s, e) => {
6515 if (!swiper.zoom.enabled) return;
6516 onTouchStart(e);
6517 });
6518 on('touchEnd', (_s, e) => {
6519 if (!swiper.zoom.enabled) return;
6520 onTouchEnd();
6521 });
6522 on('doubleTap', (_s, e) => {
6523 if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
6524 zoomToggle(e);
6525 }
6526 });
6527 on('transitionEnd', () => {
6528 if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
6529 onTransitionEnd();
6530 }
6531 });
6532 on('slideChange', () => {
6533 if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
6534 onTransitionEnd();
6535 }
6536 });
6537 Object.assign(swiper.zoom, {
6538 enable,
6539 disable,
6540 in: zoomIn,
6541 out: zoomOut,
6542 toggle: zoomToggle
6543 });
6544 }
6545
6546 /* eslint no-bitwise: ["error", { "allow": [">>"] }] */
6547 function Controller(_ref) {
6548 let {
6549 swiper,
6550 extendParams,
6551 on
6552 } = _ref;
6553 extendParams({
6554 controller: {
6555 control: undefined,
6556 inverse: false,
6557 by: 'slide' // or 'container'
6558 }
6559 });
6560
6561 swiper.controller = {
6562 control: undefined
6563 };
6564 function LinearSpline(x, y) {
6565 const binarySearch = function search() {
6566 let maxIndex;
6567 let minIndex;
6568 let guess;
6569 return (array, val) => {
6570 minIndex = -1;
6571 maxIndex = array.length;
6572 while (maxIndex - minIndex > 1) {
6573 guess = maxIndex + minIndex >> 1;
6574 if (array[guess] <= val) {
6575 minIndex = guess;
6576 } else {
6577 maxIndex = guess;
6578 }
6579 }
6580 return maxIndex;
6581 };
6582 }();
6583 this.x = x;
6584 this.y = y;
6585 this.lastIndex = x.length - 1;
6586 // Given an x value (x2), return the expected y2 value:
6587 // (x1,y1) is the known point before given value,
6588 // (x3,y3) is the known point after given value.
6589 let i1;
6590 let i3;
6591 this.interpolate = function interpolate(x2) {
6592 if (!x2) return 0;
6593
6594 // Get the indexes of x1 and x3 (the array indexes before and after given x2):
6595 i3 = binarySearch(this.x, x2);
6596 i1 = i3 - 1;
6597
6598 // We have our indexes i1 & i3, so we can calculate already:
6599 // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
6600 return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
6601 };
6602 return this;
6603 }
6604 function getInterpolateFunction(c) {
6605 swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);
6606 }
6607 function setTranslate(_t, byController) {
6608 const controlled = swiper.controller.control;
6609 let multiplier;
6610 let controlledTranslate;
6611 const Swiper = swiper.constructor;
6612 function setControlledTranslate(c) {
6613 if (c.destroyed) return;
6614
6615 // this will create an Interpolate function based on the snapGrids
6616 // x is the Grid of the scrolled scroller and y will be the controlled scroller
6617 // it makes sense to create this only once and recall it for the interpolation
6618 // the function does a lot of value caching for performance
6619 const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
6620 if (swiper.params.controller.by === 'slide') {
6621 getInterpolateFunction(c);
6622 // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
6623 // but it did not work out
6624 controlledTranslate = -swiper.controller.spline.interpolate(-translate);
6625 }
6626 if (!controlledTranslate || swiper.params.controller.by === 'container') {
6627 multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
6628 if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
6629 multiplier = 1;
6630 }
6631 controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
6632 }
6633 if (swiper.params.controller.inverse) {
6634 controlledTranslate = c.maxTranslate() - controlledTranslate;
6635 }
6636 c.updateProgress(controlledTranslate);
6637 c.setTranslate(controlledTranslate, swiper);
6638 c.updateActiveIndex();
6639 c.updateSlidesClasses();
6640 }
6641 if (Array.isArray(controlled)) {
6642 for (let i = 0; i < controlled.length; i += 1) {
6643 if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
6644 setControlledTranslate(controlled[i]);
6645 }
6646 }
6647 } else if (controlled instanceof Swiper && byController !== controlled) {
6648 setControlledTranslate(controlled);
6649 }
6650 }
6651 function setTransition(duration, byController) {
6652 const Swiper = swiper.constructor;
6653 const controlled = swiper.controller.control;
6654 let i;
6655 function setControlledTransition(c) {
6656 if (c.destroyed) return;
6657 c.setTransition(duration, swiper);
6658 if (duration !== 0) {
6659 c.transitionStart();
6660 if (c.params.autoHeight) {
6661 nextTick(() => {
6662 c.updateAutoHeight();
6663 });
6664 }
6665 elementTransitionEnd(c.wrapperEl, () => {
6666 if (!controlled) return;
6667 c.transitionEnd();
6668 });
6669 }
6670 }
6671 if (Array.isArray(controlled)) {
6672 for (i = 0; i < controlled.length; i += 1) {
6673 if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
6674 setControlledTransition(controlled[i]);
6675 }
6676 }
6677 } else if (controlled instanceof Swiper && byController !== controlled) {
6678 setControlledTransition(controlled);
6679 }
6680 }
6681 function removeSpline() {
6682 if (!swiper.controller.control) return;
6683 if (swiper.controller.spline) {
6684 swiper.controller.spline = undefined;
6685 delete swiper.controller.spline;
6686 }
6687 }
6688 on('beforeInit', () => {
6689 if (typeof window !== 'undefined' && (
6690 // eslint-disable-line
6691 typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) {
6692 const controlElement = document.querySelector(swiper.params.controller.control);
6693 if (controlElement && controlElement.swiper) {
6694 swiper.controller.control = controlElement.swiper;
6695 } else if (controlElement) {
6696 const onControllerSwiper = e => {
6697 swiper.controller.control = e.detail[0];
6698 swiper.update();
6699 controlElement.removeEventListener('init', onControllerSwiper);
6700 };
6701 controlElement.addEventListener('init', onControllerSwiper);
6702 }
6703 return;
6704 }
6705 swiper.controller.control = swiper.params.controller.control;
6706 });
6707 on('update', () => {
6708 removeSpline();
6709 });
6710 on('resize', () => {
6711 removeSpline();
6712 });
6713 on('observerUpdate', () => {
6714 removeSpline();
6715 });
6716 on('setTranslate', (_s, translate, byController) => {
6717 if (!swiper.controller.control || swiper.controller.control.destroyed) return;
6718 swiper.controller.setTranslate(translate, byController);
6719 });
6720 on('setTransition', (_s, duration, byController) => {
6721 if (!swiper.controller.control || swiper.controller.control.destroyed) return;
6722 swiper.controller.setTransition(duration, byController);
6723 });
6724 Object.assign(swiper.controller, {
6725 setTranslate,
6726 setTransition
6727 });
6728 }
6729
6730 function A11y(_ref) {
6731 let {
6732 swiper,
6733 extendParams,
6734 on
6735 } = _ref;
6736 extendParams({
6737 a11y: {
6738 enabled: true,
6739 notificationClass: 'swiper-notification',
6740 prevSlideMessage: 'Previous slide',
6741 nextSlideMessage: 'Next slide',
6742 firstSlideMessage: 'This is the first slide',
6743 lastSlideMessage: 'This is the last slide',
6744 paginationBulletMessage: 'Go to slide {{index}}',
6745 slideLabelMessage: '{{index}} / {{slidesLength}}',
6746 containerMessage: null,
6747 containerRoleDescriptionMessage: null,
6748 itemRoleDescriptionMessage: null,
6749 slideRole: 'group',
6750 id: null
6751 }
6752 });
6753 swiper.a11y = {
6754 clicked: false
6755 };
6756 let liveRegion = null;
6757 function notify(message) {
6758 const notification = liveRegion;
6759 if (notification.length === 0) return;
6760 notification.innerHTML = '';
6761 notification.innerHTML = message;
6762 }
6763 const makeElementsArray = el => {
6764 if (!Array.isArray(el)) el = [el].filter(e => !!e);
6765 return el;
6766 };
6767 function getRandomNumber(size) {
6768 if (size === void 0) {
6769 size = 16;
6770 }
6771 const randomChar = () => Math.round(16 * Math.random()).toString(16);
6772 return 'x'.repeat(size).replace(/x/g, randomChar);
6773 }
6774 function makeElFocusable(el) {
6775 el = makeElementsArray(el);
6776 el.forEach(subEl => {
6777 subEl.setAttribute('tabIndex', '0');
6778 });
6779 }
6780 function makeElNotFocusable(el) {
6781 el = makeElementsArray(el);
6782 el.forEach(subEl => {
6783 subEl.setAttribute('tabIndex', '-1');
6784 });
6785 }
6786 function addElRole(el, role) {
6787 el = makeElementsArray(el);
6788 el.forEach(subEl => {
6789 subEl.setAttribute('role', role);
6790 });
6791 }
6792 function addElRoleDescription(el, description) {
6793 el = makeElementsArray(el);
6794 el.forEach(subEl => {
6795 subEl.setAttribute('aria-roledescription', description);
6796 });
6797 }
6798 function addElControls(el, controls) {
6799 el = makeElementsArray(el);
6800 el.forEach(subEl => {
6801 subEl.setAttribute('aria-controls', controls);
6802 });
6803 }
6804 function addElLabel(el, label) {
6805 el = makeElementsArray(el);
6806 el.forEach(subEl => {
6807 subEl.setAttribute('aria-label', label);
6808 });
6809 }
6810 function addElId(el, id) {
6811 el = makeElementsArray(el);
6812 el.forEach(subEl => {
6813 subEl.setAttribute('id', id);
6814 });
6815 }
6816 function addElLive(el, live) {
6817 el = makeElementsArray(el);
6818 el.forEach(subEl => {
6819 subEl.setAttribute('aria-live', live);
6820 });
6821 }
6822 function disableEl(el) {
6823 el = makeElementsArray(el);
6824 el.forEach(subEl => {
6825 subEl.setAttribute('aria-disabled', true);
6826 });
6827 }
6828 function enableEl(el) {
6829 el = makeElementsArray(el);
6830 el.forEach(subEl => {
6831 subEl.setAttribute('aria-disabled', false);
6832 });
6833 }
6834 function onEnterOrSpaceKey(e) {
6835 if (e.keyCode !== 13 && e.keyCode !== 32) return;
6836 const params = swiper.params.a11y;
6837 const targetEl = e.target;
6838 if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
6839 if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
6840 }
6841 if (swiper.navigation && swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) {
6842 if (!(swiper.isEnd && !swiper.params.loop)) {
6843 swiper.slideNext();
6844 }
6845 if (swiper.isEnd) {
6846 notify(params.lastSlideMessage);
6847 } else {
6848 notify(params.nextSlideMessage);
6849 }
6850 }
6851 if (swiper.navigation && swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl) {
6852 if (!(swiper.isBeginning && !swiper.params.loop)) {
6853 swiper.slidePrev();
6854 }
6855 if (swiper.isBeginning) {
6856 notify(params.firstSlideMessage);
6857 } else {
6858 notify(params.prevSlideMessage);
6859 }
6860 }
6861 if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
6862 targetEl.click();
6863 }
6864 }
6865 function updateNavigation() {
6866 if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
6867 const {
6868 nextEl,
6869 prevEl
6870 } = swiper.navigation;
6871 if (prevEl) {
6872 if (swiper.isBeginning) {
6873 disableEl(prevEl);
6874 makeElNotFocusable(prevEl);
6875 } else {
6876 enableEl(prevEl);
6877 makeElFocusable(prevEl);
6878 }
6879 }
6880 if (nextEl) {
6881 if (swiper.isEnd) {
6882 disableEl(nextEl);
6883 makeElNotFocusable(nextEl);
6884 } else {
6885 enableEl(nextEl);
6886 makeElFocusable(nextEl);
6887 }
6888 }
6889 }
6890 function hasPagination() {
6891 return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
6892 }
6893 function hasClickablePagination() {
6894 return hasPagination() && swiper.params.pagination.clickable;
6895 }
6896 function updatePagination() {
6897 const params = swiper.params.a11y;
6898 if (!hasPagination()) return;
6899 swiper.pagination.bullets.forEach(bulletEl => {
6900 if (swiper.params.pagination.clickable) {
6901 makeElFocusable(bulletEl);
6902 if (!swiper.params.pagination.renderBullet) {
6903 addElRole(bulletEl, 'button');
6904 addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
6905 }
6906 }
6907 if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
6908 bulletEl.setAttribute('aria-current', 'true');
6909 } else {
6910 bulletEl.removeAttribute('aria-current');
6911 }
6912 });
6913 }
6914 const initNavEl = (el, wrapperId, message) => {
6915 makeElFocusable(el);
6916 if (el.tagName !== 'BUTTON') {
6917 addElRole(el, 'button');
6918 el.addEventListener('keydown', onEnterOrSpaceKey);
6919 }
6920 addElLabel(el, message);
6921 addElControls(el, wrapperId);
6922 };
6923 const handlePointerDown = () => {
6924 swiper.a11y.clicked = true;
6925 };
6926 const handlePointerUp = () => {
6927 requestAnimationFrame(() => {
6928 requestAnimationFrame(() => {
6929 if (!swiper.destroyed) {
6930 swiper.a11y.clicked = false;
6931 }
6932 });
6933 });
6934 };
6935 const handleFocus = e => {
6936 if (swiper.a11y.clicked) return;
6937 const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6938 if (!slideEl || !swiper.slides.includes(slideEl)) return;
6939 const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
6940 const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
6941 if (isActive || isVisible) return;
6942 if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
6943 if (swiper.isHorizontal()) {
6944 swiper.el.scrollLeft = 0;
6945 } else {
6946 swiper.el.scrollTop = 0;
6947 }
6948 swiper.slideTo(swiper.slides.indexOf(slideEl), 0);
6949 };
6950 const initSlides = () => {
6951 const params = swiper.params.a11y;
6952 if (params.itemRoleDescriptionMessage) {
6953 addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
6954 }
6955 if (params.slideRole) {
6956 addElRole(swiper.slides, params.slideRole);
6957 }
6958 const slidesLength = swiper.slides.length;
6959 if (params.slideLabelMessage) {
6960 swiper.slides.forEach((slideEl, index) => {
6961 const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
6962 const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
6963 addElLabel(slideEl, ariaLabelMessage);
6964 });
6965 }
6966 };
6967 const init = () => {
6968 const params = swiper.params.a11y;
6969 swiper.el.append(liveRegion);
6970
6971 // Container
6972 const containerEl = swiper.el;
6973 if (params.containerRoleDescriptionMessage) {
6974 addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
6975 }
6976 if (params.containerMessage) {
6977 addElLabel(containerEl, params.containerMessage);
6978 }
6979
6980 // Wrapper
6981 const wrapperEl = swiper.wrapperEl;
6982 const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
6983 const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
6984 addElId(wrapperEl, wrapperId);
6985 addElLive(wrapperEl, live);
6986
6987 // Slide
6988 initSlides();
6989
6990 // Navigation
6991 let {
6992 nextEl,
6993 prevEl
6994 } = swiper.navigation ? swiper.navigation : {};
6995 nextEl = makeElementsArray(nextEl);
6996 prevEl = makeElementsArray(prevEl);
6997 if (nextEl) {
6998 nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage));
6999 }
7000 if (prevEl) {
7001 prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage));
7002 }
7003
7004 // Pagination
7005 if (hasClickablePagination()) {
7006 const paginationEl = Array.isArray(swiper.pagination.el) ? swiper.pagination.el : [swiper.pagination.el];
7007 paginationEl.forEach(el => {
7008 el.addEventListener('keydown', onEnterOrSpaceKey);
7009 });
7010 }
7011
7012 // Tab focus
7013 swiper.el.addEventListener('focus', handleFocus, true);
7014 swiper.el.addEventListener('pointerdown', handlePointerDown, true);
7015 swiper.el.addEventListener('pointerup', handlePointerUp, true);
7016 };
7017 function destroy() {
7018 if (liveRegion) liveRegion.remove();
7019 let {
7020 nextEl,
7021 prevEl
7022 } = swiper.navigation ? swiper.navigation : {};
7023 nextEl = makeElementsArray(nextEl);
7024 prevEl = makeElementsArray(prevEl);
7025 if (nextEl) {
7026 nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
7027 }
7028 if (prevEl) {
7029 prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
7030 }
7031
7032 // Pagination
7033 if (hasClickablePagination()) {
7034 const paginationEl = Array.isArray(swiper.pagination.el) ? swiper.pagination.el : [swiper.pagination.el];
7035 paginationEl.forEach(el => {
7036 el.removeEventListener('keydown', onEnterOrSpaceKey);
7037 });
7038 }
7039
7040 // Tab focus
7041 swiper.el.removeEventListener('focus', handleFocus, true);
7042 swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
7043 swiper.el.removeEventListener('pointerup', handlePointerUp, true);
7044 }
7045 on('beforeInit', () => {
7046 liveRegion = createElement('span', swiper.params.a11y.notificationClass);
7047 liveRegion.setAttribute('aria-live', 'assertive');
7048 liveRegion.setAttribute('aria-atomic', 'true');
7049 });
7050 on('afterInit', () => {
7051 if (!swiper.params.a11y.enabled) return;
7052 init();
7053 });
7054 on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
7055 if (!swiper.params.a11y.enabled) return;
7056 initSlides();
7057 });
7058 on('fromEdge toEdge afterInit lock unlock', () => {
7059 if (!swiper.params.a11y.enabled) return;
7060 updateNavigation();
7061 });
7062 on('paginationUpdate', () => {
7063 if (!swiper.params.a11y.enabled) return;
7064 updatePagination();
7065 });
7066 on('destroy', () => {
7067 if (!swiper.params.a11y.enabled) return;
7068 destroy();
7069 });
7070 }
7071
7072 function History(_ref) {
7073 let {
7074 swiper,
7075 extendParams,
7076 on
7077 } = _ref;
7078 extendParams({
7079 history: {
7080 enabled: false,
7081 root: '',
7082 replaceState: false,
7083 key: 'slides',
7084 keepQuery: false
7085 }
7086 });
7087 let initialized = false;
7088 let paths = {};
7089 const slugify = text => {
7090 return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
7091 };
7092 const getPathValues = urlOverride => {
7093 const window = getWindow();
7094 let location;
7095 if (urlOverride) {
7096 location = new URL(urlOverride);
7097 } else {
7098 location = window.location;
7099 }
7100 const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
7101 const total = pathArray.length;
7102 const key = pathArray[total - 2];
7103 const value = pathArray[total - 1];
7104 return {
7105 key,
7106 value
7107 };
7108 };
7109 const setHistory = (key, index) => {
7110 const window = getWindow();
7111 if (!initialized || !swiper.params.history.enabled) return;
7112 let location;
7113 if (swiper.params.url) {
7114 location = new URL(swiper.params.url);
7115 } else {
7116 location = window.location;
7117 }
7118 const slide = swiper.slides[index];
7119 let value = slugify(slide.getAttribute('data-history'));
7120 if (swiper.params.history.root.length > 0) {
7121 let root = swiper.params.history.root;
7122 if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
7123 value = `${root}/${key ? `${key}/` : ''}${value}`;
7124 } else if (!location.pathname.includes(key)) {
7125 value = `${key ? `${key}/` : ''}${value}`;
7126 }
7127 if (swiper.params.history.keepQuery) {
7128 value += location.search;
7129 }
7130 const currentState = window.history.state;
7131 if (currentState && currentState.value === value) {
7132 return;
7133 }
7134 if (swiper.params.history.replaceState) {
7135 window.history.replaceState({
7136 value
7137 }, null, value);
7138 } else {
7139 window.history.pushState({
7140 value
7141 }, null, value);
7142 }
7143 };
7144 const scrollToSlide = (speed, value, runCallbacks) => {
7145 if (value) {
7146 for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
7147 const slide = swiper.slides[i];
7148 const slideHistory = slugify(slide.getAttribute('data-history'));
7149 if (slideHistory === value) {
7150 const index = swiper.getSlideIndex(slide);
7151 swiper.slideTo(index, speed, runCallbacks);
7152 }
7153 }
7154 } else {
7155 swiper.slideTo(0, speed, runCallbacks);
7156 }
7157 };
7158 const setHistoryPopState = () => {
7159 paths = getPathValues(swiper.params.url);
7160 scrollToSlide(swiper.params.speed, paths.value, false);
7161 };
7162 const init = () => {
7163 const window = getWindow();
7164 if (!swiper.params.history) return;
7165 if (!window.history || !window.history.pushState) {
7166 swiper.params.history.enabled = false;
7167 swiper.params.hashNavigation.enabled = true;
7168 return;
7169 }
7170 initialized = true;
7171 paths = getPathValues(swiper.params.url);
7172 if (!paths.key && !paths.value) {
7173 if (!swiper.params.history.replaceState) {
7174 window.addEventListener('popstate', setHistoryPopState);
7175 }
7176 return;
7177 }
7178 scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
7179 if (!swiper.params.history.replaceState) {
7180 window.addEventListener('popstate', setHistoryPopState);
7181 }
7182 };
7183 const destroy = () => {
7184 const window = getWindow();
7185 if (!swiper.params.history.replaceState) {
7186 window.removeEventListener('popstate', setHistoryPopState);
7187 }
7188 };
7189 on('init', () => {
7190 if (swiper.params.history.enabled) {
7191 init();
7192 }
7193 });
7194 on('destroy', () => {
7195 if (swiper.params.history.enabled) {
7196 destroy();
7197 }
7198 });
7199 on('transitionEnd _freeModeNoMomentumRelease', () => {
7200 if (initialized) {
7201 setHistory(swiper.params.history.key, swiper.activeIndex);
7202 }
7203 });
7204 on('slideChange', () => {
7205 if (initialized && swiper.params.cssMode) {
7206 setHistory(swiper.params.history.key, swiper.activeIndex);
7207 }
7208 });
7209 }
7210
7211 function HashNavigation(_ref) {
7212 let {
7213 swiper,
7214 extendParams,
7215 emit,
7216 on
7217 } = _ref;
7218 let initialized = false;
7219 const document = getDocument();
7220 const window = getWindow();
7221 extendParams({
7222 hashNavigation: {
7223 enabled: false,
7224 replaceState: false,
7225 watchState: false,
7226 getSlideIndex(_s, hash) {
7227 if (swiper.virtual && swiper.params.virtual.enabled) {
7228 const slideWithHash = swiper.slides.filter(slideEl => slideEl.getAttribute('data-hash') === hash)[0];
7229 if (!slideWithHash) return 0;
7230 const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
7231 return index;
7232 }
7233 return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]);
7234 }
7235 }
7236 });
7237 const onHashChange = () => {
7238 emit('hashChange');
7239 const newHash = document.location.hash.replace('#', '');
7240 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
7241 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
7242 if (newHash !== activeSlideHash) {
7243 const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
7244 if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
7245 swiper.slideTo(newIndex);
7246 }
7247 };
7248 const setHash = () => {
7249 if (!initialized || !swiper.params.hashNavigation.enabled) return;
7250 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
7251 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : '';
7252 if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
7253 window.history.replaceState(null, null, `#${activeSlideHash}` || '');
7254 emit('hashSet');
7255 } else {
7256 document.location.hash = activeSlideHash || '';
7257 emit('hashSet');
7258 }
7259 };
7260 const init = () => {
7261 if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
7262 initialized = true;
7263 const hash = document.location.hash.replace('#', '');
7264 if (hash) {
7265 const speed = 0;
7266 const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
7267 swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
7268 }
7269 if (swiper.params.hashNavigation.watchState) {
7270 window.addEventListener('hashchange', onHashChange);
7271 }
7272 };
7273 const destroy = () => {
7274 if (swiper.params.hashNavigation.watchState) {
7275 window.removeEventListener('hashchange', onHashChange);
7276 }
7277 };
7278 on('init', () => {
7279 if (swiper.params.hashNavigation.enabled) {
7280 init();
7281 }
7282 });
7283 on('destroy', () => {
7284 if (swiper.params.hashNavigation.enabled) {
7285 destroy();
7286 }
7287 });
7288 on('transitionEnd _freeModeNoMomentumRelease', () => {
7289 if (initialized) {
7290 setHash();
7291 }
7292 });
7293 on('slideChange', () => {
7294 if (initialized && swiper.params.cssMode) {
7295 setHash();
7296 }
7297 });
7298 }
7299
7300 /* eslint no-underscore-dangle: "off" */
7301 /* eslint no-use-before-define: "off" */
7302 function Autoplay(_ref) {
7303 let {
7304 swiper,
7305 extendParams,
7306 on,
7307 emit,
7308 params
7309 } = _ref;
7310 swiper.autoplay = {
7311 running: false,
7312 paused: false,
7313 timeLeft: 0
7314 };
7315 extendParams({
7316 autoplay: {
7317 enabled: false,
7318 delay: 3000,
7319 waitForTransition: true,
7320 disableOnInteraction: true,
7321 stopOnLastSlide: false,
7322 reverseDirection: false,
7323 pauseOnMouseEnter: false
7324 }
7325 });
7326 let timeout;
7327 let raf;
7328 let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
7329 let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
7330 let autoplayTimeLeft;
7331 let autoplayStartTime = new Date().getTime;
7332 let wasPaused;
7333 let isTouched;
7334 let pausedByTouch;
7335 let touchStartTimeout;
7336 let slideChanged;
7337 let pausedByInteraction;
7338 function onTransitionEnd(e) {
7339 if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
7340 if (e.target !== swiper.wrapperEl) return;
7341 swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
7342 resume();
7343 }
7344 const calcTimeLeft = () => {
7345 if (swiper.destroyed || !swiper.autoplay.running) return;
7346 if (swiper.autoplay.paused) {
7347 wasPaused = true;
7348 } else if (wasPaused) {
7349 autoplayDelayCurrent = autoplayTimeLeft;
7350 wasPaused = false;
7351 }
7352 const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
7353 swiper.autoplay.timeLeft = timeLeft;
7354 emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
7355 raf = requestAnimationFrame(() => {
7356 calcTimeLeft();
7357 });
7358 };
7359 const getSlideDelay = () => {
7360 let activeSlideEl;
7361 if (swiper.virtual && swiper.params.virtual.enabled) {
7362 activeSlideEl = swiper.slides.filter(slideEl => slideEl.classList.contains('swiper-slide-active'))[0];
7363 } else {
7364 activeSlideEl = swiper.slides[swiper.activeIndex];
7365 }
7366 if (!activeSlideEl) return undefined;
7367 const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
7368 return currentSlideDelay;
7369 };
7370 const run = delayForce => {
7371 if (swiper.destroyed || !swiper.autoplay.running) return;
7372 cancelAnimationFrame(raf);
7373 calcTimeLeft();
7374 let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
7375 autoplayDelayTotal = swiper.params.autoplay.delay;
7376 autoplayDelayCurrent = swiper.params.autoplay.delay;
7377 const currentSlideDelay = getSlideDelay();
7378 if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
7379 delay = currentSlideDelay;
7380 autoplayDelayTotal = currentSlideDelay;
7381 autoplayDelayCurrent = currentSlideDelay;
7382 }
7383 autoplayTimeLeft = delay;
7384 const speed = swiper.params.speed;
7385 const proceed = () => {
7386 if (!swiper || swiper.destroyed) return;
7387 if (swiper.params.autoplay.reverseDirection) {
7388 if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
7389 swiper.slidePrev(speed, true, true);
7390 emit('autoplay');
7391 } else if (!swiper.params.autoplay.stopOnLastSlide) {
7392 swiper.slideTo(swiper.slides.length - 1, speed, true, true);
7393 emit('autoplay');
7394 }
7395 } else {
7396 if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
7397 swiper.slideNext(speed, true, true);
7398 emit('autoplay');
7399 } else if (!swiper.params.autoplay.stopOnLastSlide) {
7400 swiper.slideTo(0, speed, true, true);
7401 emit('autoplay');
7402 }
7403 }
7404 if (swiper.params.cssMode) {
7405 autoplayStartTime = new Date().getTime();
7406 requestAnimationFrame(() => {
7407 run();
7408 });
7409 }
7410 };
7411 if (delay > 0) {
7412 clearTimeout(timeout);
7413 timeout = setTimeout(() => {
7414 proceed();
7415 }, delay);
7416 } else {
7417 requestAnimationFrame(() => {
7418 proceed();
7419 });
7420 }
7421
7422 // eslint-disable-next-line
7423 return delay;
7424 };
7425 const start = () => {
7426 swiper.autoplay.running = true;
7427 run();
7428 emit('autoplayStart');
7429 };
7430 const stop = () => {
7431 swiper.autoplay.running = false;
7432 clearTimeout(timeout);
7433 cancelAnimationFrame(raf);
7434 emit('autoplayStop');
7435 };
7436 const pause = (internal, reset) => {
7437 if (swiper.destroyed || !swiper.autoplay.running) return;
7438 clearTimeout(timeout);
7439 if (!internal) {
7440 pausedByInteraction = true;
7441 }
7442 const proceed = () => {
7443 emit('autoplayPause');
7444 if (swiper.params.autoplay.waitForTransition) {
7445 swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
7446 } else {
7447 resume();
7448 }
7449 };
7450 swiper.autoplay.paused = true;
7451 if (reset) {
7452 if (slideChanged) {
7453 autoplayTimeLeft = swiper.params.autoplay.delay;
7454 }
7455 slideChanged = false;
7456 proceed();
7457 return;
7458 }
7459 const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
7460 autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
7461 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
7462 if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
7463 proceed();
7464 };
7465 const resume = () => {
7466 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
7467 autoplayStartTime = new Date().getTime();
7468 if (pausedByInteraction) {
7469 pausedByInteraction = false;
7470 run(autoplayTimeLeft);
7471 } else {
7472 run();
7473 }
7474 swiper.autoplay.paused = false;
7475 emit('autoplayResume');
7476 };
7477 const onVisibilityChange = () => {
7478 if (swiper.destroyed || !swiper.autoplay.running) return;
7479 const document = getDocument();
7480 if (document.visibilityState === 'hidden') {
7481 pausedByInteraction = true;
7482 pause(true);
7483 }
7484 if (document.visibilityState === 'visible') {
7485 resume();
7486 }
7487 };
7488 const onPointerEnter = e => {
7489 if (e.pointerType !== 'mouse') return;
7490 pausedByInteraction = true;
7491 pause(true);
7492 };
7493 const onPointerLeave = e => {
7494 if (e.pointerType !== 'mouse') return;
7495 if (swiper.autoplay.paused) {
7496 resume();
7497 }
7498 };
7499 const attachMouseEvents = () => {
7500 if (swiper.params.autoplay.pauseOnMouseEnter) {
7501 swiper.el.addEventListener('pointerenter', onPointerEnter);
7502 swiper.el.addEventListener('pointerleave', onPointerLeave);
7503 }
7504 };
7505 const detachMouseEvents = () => {
7506 swiper.el.removeEventListener('pointerenter', onPointerEnter);
7507 swiper.el.removeEventListener('pointerleave', onPointerLeave);
7508 };
7509 const attachDocumentEvents = () => {
7510 const document = getDocument();
7511 document.addEventListener('visibilitychange', onVisibilityChange);
7512 };
7513 const detachDocumentEvents = () => {
7514 const document = getDocument();
7515 document.removeEventListener('visibilitychange', onVisibilityChange);
7516 };
7517 on('init', () => {
7518 if (swiper.params.autoplay.enabled) {
7519 attachMouseEvents();
7520 attachDocumentEvents();
7521 autoplayStartTime = new Date().getTime();
7522 start();
7523 }
7524 });
7525 on('destroy', () => {
7526 detachMouseEvents();
7527 detachDocumentEvents();
7528 if (swiper.autoplay.running) {
7529 stop();
7530 }
7531 });
7532 on('beforeTransitionStart', (_s, speed, internal) => {
7533 if (swiper.destroyed || !swiper.autoplay.running) return;
7534 if (internal || !swiper.params.autoplay.disableOnInteraction) {
7535 pause(true, true);
7536 } else {
7537 stop();
7538 }
7539 });
7540 on('sliderFirstMove', () => {
7541 if (swiper.destroyed || !swiper.autoplay.running) return;
7542 if (swiper.params.autoplay.disableOnInteraction) {
7543 stop();
7544 return;
7545 }
7546 isTouched = true;
7547 pausedByTouch = false;
7548 pausedByInteraction = false;
7549 touchStartTimeout = setTimeout(() => {
7550 pausedByInteraction = true;
7551 pausedByTouch = true;
7552 pause(true);
7553 }, 200);
7554 });
7555 on('touchEnd', () => {
7556 if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
7557 clearTimeout(touchStartTimeout);
7558 clearTimeout(timeout);
7559 if (swiper.params.autoplay.disableOnInteraction) {
7560 pausedByTouch = false;
7561 isTouched = false;
7562 return;
7563 }
7564 if (pausedByTouch && swiper.params.cssMode) resume();
7565 pausedByTouch = false;
7566 isTouched = false;
7567 });
7568 on('slideChange', () => {
7569 if (swiper.destroyed || !swiper.autoplay.running) return;
7570 slideChanged = true;
7571 });
7572 Object.assign(swiper.autoplay, {
7573 start,
7574 stop,
7575 pause,
7576 resume
7577 });
7578 }
7579
7580 function Thumb(_ref) {
7581 let {
7582 swiper,
7583 extendParams,
7584 on
7585 } = _ref;
7586 extendParams({
7587 thumbs: {
7588 swiper: null,
7589 multipleActiveThumbs: true,
7590 autoScrollOffset: 0,
7591 slideThumbActiveClass: 'swiper-slide-thumb-active',
7592 thumbsContainerClass: 'swiper-thumbs'
7593 }
7594 });
7595 let initialized = false;
7596 let swiperCreated = false;
7597 swiper.thumbs = {
7598 swiper: null
7599 };
7600 function onThumbClick() {
7601 const thumbsSwiper = swiper.thumbs.swiper;
7602 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7603 const clickedIndex = thumbsSwiper.clickedIndex;
7604 const clickedSlide = thumbsSwiper.clickedSlide;
7605 if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
7606 if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
7607 let slideToIndex;
7608 if (thumbsSwiper.params.loop) {
7609 slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
7610 } else {
7611 slideToIndex = clickedIndex;
7612 }
7613 if (swiper.params.loop) {
7614 swiper.slideToLoop(slideToIndex);
7615 } else {
7616 swiper.slideTo(slideToIndex);
7617 }
7618 }
7619 function init() {
7620 const {
7621 thumbs: thumbsParams
7622 } = swiper.params;
7623 if (initialized) return false;
7624 initialized = true;
7625 const SwiperClass = swiper.constructor;
7626 if (thumbsParams.swiper instanceof SwiperClass) {
7627 swiper.thumbs.swiper = thumbsParams.swiper;
7628 Object.assign(swiper.thumbs.swiper.originalParams, {
7629 watchSlidesProgress: true,
7630 slideToClickedSlide: false
7631 });
7632 Object.assign(swiper.thumbs.swiper.params, {
7633 watchSlidesProgress: true,
7634 slideToClickedSlide: false
7635 });
7636 swiper.thumbs.swiper.update();
7637 } else if (isObject$1(thumbsParams.swiper)) {
7638 const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
7639 Object.assign(thumbsSwiperParams, {
7640 watchSlidesProgress: true,
7641 slideToClickedSlide: false
7642 });
7643 swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
7644 swiperCreated = true;
7645 }
7646 swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
7647 swiper.thumbs.swiper.on('tap', onThumbClick);
7648 return true;
7649 }
7650 function update(initial) {
7651 const thumbsSwiper = swiper.thumbs.swiper;
7652 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7653 const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
7654
7655 // Activate thumbs
7656 let thumbsToActivate = 1;
7657 const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
7658 if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
7659 thumbsToActivate = swiper.params.slidesPerView;
7660 }
7661 if (!swiper.params.thumbs.multipleActiveThumbs) {
7662 thumbsToActivate = 1;
7663 }
7664 thumbsToActivate = Math.floor(thumbsToActivate);
7665 thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
7666 if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
7667 for (let i = 0; i < thumbsToActivate; i += 1) {
7668 elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
7669 slideEl.classList.add(thumbActiveClass);
7670 });
7671 }
7672 } else {
7673 for (let i = 0; i < thumbsToActivate; i += 1) {
7674 if (thumbsSwiper.slides[swiper.realIndex + i]) {
7675 thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
7676 }
7677 }
7678 }
7679 const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
7680 const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
7681 if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
7682 const currentThumbsIndex = thumbsSwiper.activeIndex;
7683 let newThumbsIndex;
7684 let direction;
7685 if (thumbsSwiper.params.loop) {
7686 const newThumbsSlide = thumbsSwiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`)[0];
7687 newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
7688 direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
7689 } else {
7690 newThumbsIndex = swiper.realIndex;
7691 direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
7692 }
7693 if (useOffset) {
7694 newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
7695 }
7696 if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
7697 if (thumbsSwiper.params.centeredSlides) {
7698 if (newThumbsIndex > currentThumbsIndex) {
7699 newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
7700 } else {
7701 newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
7702 }
7703 } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ;
7704 thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
7705 }
7706 }
7707 }
7708 on('beforeInit', () => {
7709 const {
7710 thumbs
7711 } = swiper.params;
7712 if (!thumbs || !thumbs.swiper) return;
7713 if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
7714 const document = getDocument();
7715 const getThumbsElementAndInit = () => {
7716 const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
7717 if (thumbsElement && thumbsElement.swiper) {
7718 thumbs.swiper = thumbsElement.swiper;
7719 init();
7720 update(true);
7721 } else if (thumbsElement) {
7722 const onThumbsSwiper = e => {
7723 thumbs.swiper = e.detail[0];
7724 thumbsElement.removeEventListener('init', onThumbsSwiper);
7725 init();
7726 update(true);
7727 thumbs.swiper.update();
7728 swiper.update();
7729 };
7730 thumbsElement.addEventListener('init', onThumbsSwiper);
7731 }
7732 return thumbsElement;
7733 };
7734 const watchForThumbsToAppear = () => {
7735 if (swiper.destroyed) return;
7736 const thumbsElement = getThumbsElementAndInit();
7737 if (!thumbsElement) {
7738 requestAnimationFrame(watchForThumbsToAppear);
7739 }
7740 };
7741 requestAnimationFrame(watchForThumbsToAppear);
7742 } else {
7743 init();
7744 update(true);
7745 }
7746 });
7747 on('slideChange update resize observerUpdate', () => {
7748 update();
7749 });
7750 on('setTransition', (_s, duration) => {
7751 const thumbsSwiper = swiper.thumbs.swiper;
7752 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7753 thumbsSwiper.setTransition(duration);
7754 });
7755 on('beforeDestroy', () => {
7756 const thumbsSwiper = swiper.thumbs.swiper;
7757 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7758 if (swiperCreated) {
7759 thumbsSwiper.destroy();
7760 }
7761 });
7762 Object.assign(swiper.thumbs, {
7763 init,
7764 update
7765 });
7766 }
7767
7768 function freeMode(_ref) {
7769 let {
7770 swiper,
7771 extendParams,
7772 emit,
7773 once
7774 } = _ref;
7775 extendParams({
7776 freeMode: {
7777 enabled: false,
7778 momentum: true,
7779 momentumRatio: 1,
7780 momentumBounce: true,
7781 momentumBounceRatio: 1,
7782 momentumVelocityRatio: 1,
7783 sticky: false,
7784 minimumVelocity: 0.02
7785 }
7786 });
7787 function onTouchStart() {
7788 if (swiper.params.cssMode) return;
7789 const translate = swiper.getTranslate();
7790 swiper.setTranslate(translate);
7791 swiper.setTransition(0);
7792 swiper.touchEventsData.velocities.length = 0;
7793 swiper.freeMode.onTouchEnd({
7794 currentPos: swiper.rtl ? swiper.translate : -swiper.translate
7795 });
7796 }
7797 function onTouchMove() {
7798 if (swiper.params.cssMode) return;
7799 const {
7800 touchEventsData: data,
7801 touches
7802 } = swiper;
7803 // Velocity
7804 if (data.velocities.length === 0) {
7805 data.velocities.push({
7806 position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
7807 time: data.touchStartTime
7808 });
7809 }
7810 data.velocities.push({
7811 position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
7812 time: now()
7813 });
7814 }
7815 function onTouchEnd(_ref2) {
7816 let {
7817 currentPos
7818 } = _ref2;
7819 if (swiper.params.cssMode) return;
7820 const {
7821 params,
7822 wrapperEl,
7823 rtlTranslate: rtl,
7824 snapGrid,
7825 touchEventsData: data
7826 } = swiper;
7827 // Time diff
7828 const touchEndTime = now();
7829 const timeDiff = touchEndTime - data.touchStartTime;
7830 if (currentPos < -swiper.minTranslate()) {
7831 swiper.slideTo(swiper.activeIndex);
7832 return;
7833 }
7834 if (currentPos > -swiper.maxTranslate()) {
7835 if (swiper.slides.length < snapGrid.length) {
7836 swiper.slideTo(snapGrid.length - 1);
7837 } else {
7838 swiper.slideTo(swiper.slides.length - 1);
7839 }
7840 return;
7841 }
7842 if (params.freeMode.momentum) {
7843 if (data.velocities.length > 1) {
7844 const lastMoveEvent = data.velocities.pop();
7845 const velocityEvent = data.velocities.pop();
7846 const distance = lastMoveEvent.position - velocityEvent.position;
7847 const time = lastMoveEvent.time - velocityEvent.time;
7848 swiper.velocity = distance / time;
7849 swiper.velocity /= 2;
7850 if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
7851 swiper.velocity = 0;
7852 }
7853 // this implies that the user stopped moving a finger then released.
7854 // There would be no events with distance zero, so the last event is stale.
7855 if (time > 150 || now() - lastMoveEvent.time > 300) {
7856 swiper.velocity = 0;
7857 }
7858 } else {
7859 swiper.velocity = 0;
7860 }
7861 swiper.velocity *= params.freeMode.momentumVelocityRatio;
7862 data.velocities.length = 0;
7863 let momentumDuration = 1000 * params.freeMode.momentumRatio;
7864 const momentumDistance = swiper.velocity * momentumDuration;
7865 let newPosition = swiper.translate + momentumDistance;
7866 if (rtl) newPosition = -newPosition;
7867 let doBounce = false;
7868 let afterBouncePosition;
7869 const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
7870 let needsLoopFix;
7871 if (newPosition < swiper.maxTranslate()) {
7872 if (params.freeMode.momentumBounce) {
7873 if (newPosition + swiper.maxTranslate() < -bounceAmount) {
7874 newPosition = swiper.maxTranslate() - bounceAmount;
7875 }
7876 afterBouncePosition = swiper.maxTranslate();
7877 doBounce = true;
7878 data.allowMomentumBounce = true;
7879 } else {
7880 newPosition = swiper.maxTranslate();
7881 }
7882 if (params.loop && params.centeredSlides) needsLoopFix = true;
7883 } else if (newPosition > swiper.minTranslate()) {
7884 if (params.freeMode.momentumBounce) {
7885 if (newPosition - swiper.minTranslate() > bounceAmount) {
7886 newPosition = swiper.minTranslate() + bounceAmount;
7887 }
7888 afterBouncePosition = swiper.minTranslate();
7889 doBounce = true;
7890 data.allowMomentumBounce = true;
7891 } else {
7892 newPosition = swiper.minTranslate();
7893 }
7894 if (params.loop && params.centeredSlides) needsLoopFix = true;
7895 } else if (params.freeMode.sticky) {
7896 let nextSlide;
7897 for (let j = 0; j < snapGrid.length; j += 1) {
7898 if (snapGrid[j] > -newPosition) {
7899 nextSlide = j;
7900 break;
7901 }
7902 }
7903 if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
7904 newPosition = snapGrid[nextSlide];
7905 } else {
7906 newPosition = snapGrid[nextSlide - 1];
7907 }
7908 newPosition = -newPosition;
7909 }
7910 if (needsLoopFix) {
7911 once('transitionEnd', () => {
7912 swiper.loopFix();
7913 });
7914 }
7915 // Fix duration
7916 if (swiper.velocity !== 0) {
7917 if (rtl) {
7918 momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
7919 } else {
7920 momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
7921 }
7922 if (params.freeMode.sticky) {
7923 // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
7924 // event, then durations can be 20+ seconds to slide one (or zero!) slides.
7925 // It's easy to see this when simulating touch with mouse events. To fix this,
7926 // limit single-slide swipes to the default slide duration. This also has the
7927 // nice side effect of matching slide speed if the user stopped moving before
7928 // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
7929 // For faster swipes, also apply limits (albeit higher ones).
7930 const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
7931 const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
7932 if (moveDistance < currentSlideSize) {
7933 momentumDuration = params.speed;
7934 } else if (moveDistance < 2 * currentSlideSize) {
7935 momentumDuration = params.speed * 1.5;
7936 } else {
7937 momentumDuration = params.speed * 2.5;
7938 }
7939 }
7940 } else if (params.freeMode.sticky) {
7941 swiper.slideToClosest();
7942 return;
7943 }
7944 if (params.freeMode.momentumBounce && doBounce) {
7945 swiper.updateProgress(afterBouncePosition);
7946 swiper.setTransition(momentumDuration);
7947 swiper.setTranslate(newPosition);
7948 swiper.transitionStart(true, swiper.swipeDirection);
7949 swiper.animating = true;
7950 elementTransitionEnd(wrapperEl, () => {
7951 if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
7952 emit('momentumBounce');
7953 swiper.setTransition(params.speed);
7954 setTimeout(() => {
7955 swiper.setTranslate(afterBouncePosition);
7956 elementTransitionEnd(wrapperEl, () => {
7957 if (!swiper || swiper.destroyed) return;
7958 swiper.transitionEnd();
7959 });
7960 }, 0);
7961 });
7962 } else if (swiper.velocity) {
7963 emit('_freeModeNoMomentumRelease');
7964 swiper.updateProgress(newPosition);
7965 swiper.setTransition(momentumDuration);
7966 swiper.setTranslate(newPosition);
7967 swiper.transitionStart(true, swiper.swipeDirection);
7968 if (!swiper.animating) {
7969 swiper.animating = true;
7970 elementTransitionEnd(wrapperEl, () => {
7971 if (!swiper || swiper.destroyed) return;
7972 swiper.transitionEnd();
7973 });
7974 }
7975 } else {
7976 swiper.updateProgress(newPosition);
7977 }
7978 swiper.updateActiveIndex();
7979 swiper.updateSlidesClasses();
7980 } else if (params.freeMode.sticky) {
7981 swiper.slideToClosest();
7982 return;
7983 } else if (params.freeMode) {
7984 emit('_freeModeNoMomentumRelease');
7985 }
7986 if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
7987 swiper.updateProgress();
7988 swiper.updateActiveIndex();
7989 swiper.updateSlidesClasses();
7990 }
7991 }
7992 Object.assign(swiper, {
7993 freeMode: {
7994 onTouchStart,
7995 onTouchMove,
7996 onTouchEnd
7997 }
7998 });
7999 }
8000
8001 function Grid(_ref) {
8002 let {
8003 swiper,
8004 extendParams
8005 } = _ref;
8006 extendParams({
8007 grid: {
8008 rows: 1,
8009 fill: 'column'
8010 }
8011 });
8012 let slidesNumberEvenToRows;
8013 let slidesPerRow;
8014 let numFullColumns;
8015 const getSpaceBetween = () => {
8016 let spaceBetween = swiper.params.spaceBetween;
8017 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
8018 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
8019 } else if (typeof spaceBetween === 'string') {
8020 spaceBetween = parseFloat(spaceBetween);
8021 }
8022 return spaceBetween;
8023 };
8024 const initSlides = slidesLength => {
8025 const {
8026 slidesPerView
8027 } = swiper.params;
8028 const {
8029 rows,
8030 fill
8031 } = swiper.params.grid;
8032 numFullColumns = Math.floor(slidesLength / rows);
8033 if (Math.floor(slidesLength / rows) === slidesLength / rows) {
8034 slidesNumberEvenToRows = slidesLength;
8035 } else {
8036 slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
8037 }
8038 if (slidesPerView !== 'auto' && fill === 'row') {
8039 slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
8040 }
8041 slidesPerRow = slidesNumberEvenToRows / rows;
8042 };
8043 const updateSlide = (i, slide, slidesLength, getDirectionLabel) => {
8044 const {
8045 slidesPerGroup
8046 } = swiper.params;
8047 const spaceBetween = getSpaceBetween();
8048 const {
8049 rows,
8050 fill
8051 } = swiper.params.grid;
8052 // Set slides order
8053 let newSlideOrderIndex;
8054 let column;
8055 let row;
8056 if (fill === 'row' && slidesPerGroup > 1) {
8057 const groupIndex = Math.floor(i / (slidesPerGroup * rows));
8058 const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
8059 const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
8060 row = Math.floor(slideIndexInGroup / columnsInGroup);
8061 column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
8062 newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;
8063 slide.style.order = newSlideOrderIndex;
8064 } else if (fill === 'column') {
8065 column = Math.floor(i / rows);
8066 row = i - column * rows;
8067 if (column > numFullColumns || column === numFullColumns && row === rows - 1) {
8068 row += 1;
8069 if (row >= rows) {
8070 row = 0;
8071 column += 1;
8072 }
8073 }
8074 } else {
8075 row = Math.floor(i / slidesPerRow);
8076 column = i - row * slidesPerRow;
8077 }
8078 slide.row = row;
8079 slide.column = column;
8080 slide.style[getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
8081 };
8082 const updateWrapperSize = (slideSize, snapGrid, getDirectionLabel) => {
8083 const {
8084 centeredSlides,
8085 roundLengths
8086 } = swiper.params;
8087 const spaceBetween = getSpaceBetween();
8088 const {
8089 rows
8090 } = swiper.params.grid;
8091 swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
8092 swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
8093 swiper.wrapperEl.style[getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
8094 if (centeredSlides) {
8095 const newSlidesGrid = [];
8096 for (let i = 0; i < snapGrid.length; i += 1) {
8097 let slidesGridItem = snapGrid[i];
8098 if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
8099 if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
8100 }
8101 snapGrid.splice(0, snapGrid.length);
8102 snapGrid.push(...newSlidesGrid);
8103 }
8104 };
8105 swiper.grid = {
8106 initSlides,
8107 updateSlide,
8108 updateWrapperSize
8109 };
8110 }
8111
8112 function appendSlide(slides) {
8113 const swiper = this;
8114 const {
8115 params,
8116 slidesEl
8117 } = swiper;
8118 if (params.loop) {
8119 swiper.loopDestroy();
8120 }
8121 const appendElement = slideEl => {
8122 if (typeof slideEl === 'string') {
8123 const tempDOM = document.createElement('div');
8124 tempDOM.innerHTML = slideEl;
8125 slidesEl.append(tempDOM.children[0]);
8126 tempDOM.innerHTML = '';
8127 } else {
8128 slidesEl.append(slideEl);
8129 }
8130 };
8131 if (typeof slides === 'object' && 'length' in slides) {
8132 for (let i = 0; i < slides.length; i += 1) {
8133 if (slides[i]) appendElement(slides[i]);
8134 }
8135 } else {
8136 appendElement(slides);
8137 }
8138 swiper.recalcSlides();
8139 if (params.loop) {
8140 swiper.loopCreate();
8141 }
8142 if (!params.observer || swiper.isElement) {
8143 swiper.update();
8144 }
8145 }
8146
8147 function prependSlide(slides) {
8148 const swiper = this;
8149 const {
8150 params,
8151 activeIndex,
8152 slidesEl
8153 } = swiper;
8154 if (params.loop) {
8155 swiper.loopDestroy();
8156 }
8157 let newActiveIndex = activeIndex + 1;
8158 const prependElement = slideEl => {
8159 if (typeof slideEl === 'string') {
8160 const tempDOM = document.createElement('div');
8161 tempDOM.innerHTML = slideEl;
8162 slidesEl.prepend(tempDOM.children[0]);
8163 tempDOM.innerHTML = '';
8164 } else {
8165 slidesEl.prepend(slideEl);
8166 }
8167 };
8168 if (typeof slides === 'object' && 'length' in slides) {
8169 for (let i = 0; i < slides.length; i += 1) {
8170 if (slides[i]) prependElement(slides[i]);
8171 }
8172 newActiveIndex = activeIndex + slides.length;
8173 } else {
8174 prependElement(slides);
8175 }
8176 swiper.recalcSlides();
8177 if (params.loop) {
8178 swiper.loopCreate();
8179 }
8180 if (!params.observer || swiper.isElement) {
8181 swiper.update();
8182 }
8183 swiper.slideTo(newActiveIndex, 0, false);
8184 }
8185
8186 function addSlide(index, slides) {
8187 const swiper = this;
8188 const {
8189 params,
8190 activeIndex,
8191 slidesEl
8192 } = swiper;
8193 let activeIndexBuffer = activeIndex;
8194 if (params.loop) {
8195 activeIndexBuffer -= swiper.loopedSlides;
8196 swiper.loopDestroy();
8197 swiper.recalcSlides();
8198 }
8199 const baseLength = swiper.slides.length;
8200 if (index <= 0) {
8201 swiper.prependSlide(slides);
8202 return;
8203 }
8204 if (index >= baseLength) {
8205 swiper.appendSlide(slides);
8206 return;
8207 }
8208 let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
8209 const slidesBuffer = [];
8210 for (let i = baseLength - 1; i >= index; i -= 1) {
8211 const currentSlide = swiper.slides[i];
8212 currentSlide.remove();
8213 slidesBuffer.unshift(currentSlide);
8214 }
8215 if (typeof slides === 'object' && 'length' in slides) {
8216 for (let i = 0; i < slides.length; i += 1) {
8217 if (slides[i]) slidesEl.append(slides[i]);
8218 }
8219 newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
8220 } else {
8221 slidesEl.append(slides);
8222 }
8223 for (let i = 0; i < slidesBuffer.length; i += 1) {
8224 slidesEl.append(slidesBuffer[i]);
8225 }
8226 swiper.recalcSlides();
8227 if (params.loop) {
8228 swiper.loopCreate();
8229 }
8230 if (!params.observer || swiper.isElement) {
8231 swiper.update();
8232 }
8233 if (params.loop) {
8234 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8235 } else {
8236 swiper.slideTo(newActiveIndex, 0, false);
8237 }
8238 }
8239
8240 function removeSlide(slidesIndexes) {
8241 const swiper = this;
8242 const {
8243 params,
8244 activeIndex
8245 } = swiper;
8246 let activeIndexBuffer = activeIndex;
8247 if (params.loop) {
8248 activeIndexBuffer -= swiper.loopedSlides;
8249 swiper.loopDestroy();
8250 }
8251 let newActiveIndex = activeIndexBuffer;
8252 let indexToRemove;
8253 if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
8254 for (let i = 0; i < slidesIndexes.length; i += 1) {
8255 indexToRemove = slidesIndexes[i];
8256 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8257 if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8258 }
8259 newActiveIndex = Math.max(newActiveIndex, 0);
8260 } else {
8261 indexToRemove = slidesIndexes;
8262 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8263 if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8264 newActiveIndex = Math.max(newActiveIndex, 0);
8265 }
8266 swiper.recalcSlides();
8267 if (params.loop) {
8268 swiper.loopCreate();
8269 }
8270 if (!params.observer || swiper.isElement) {
8271 swiper.update();
8272 }
8273 if (params.loop) {
8274 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8275 } else {
8276 swiper.slideTo(newActiveIndex, 0, false);
8277 }
8278 }
8279
8280 function removeAllSlides() {
8281 const swiper = this;
8282 const slidesIndexes = [];
8283 for (let i = 0; i < swiper.slides.length; i += 1) {
8284 slidesIndexes.push(i);
8285 }
8286 swiper.removeSlide(slidesIndexes);
8287 }
8288
8289 function Manipulation(_ref) {
8290 let {
8291 swiper
8292 } = _ref;
8293 Object.assign(swiper, {
8294 appendSlide: appendSlide.bind(swiper),
8295 prependSlide: prependSlide.bind(swiper),
8296 addSlide: addSlide.bind(swiper),
8297 removeSlide: removeSlide.bind(swiper),
8298 removeAllSlides: removeAllSlides.bind(swiper)
8299 });
8300 }
8301
8302 function effectInit(params) {
8303 const {
8304 effect,
8305 swiper,
8306 on,
8307 setTranslate,
8308 setTransition,
8309 overwriteParams,
8310 perspective,
8311 recreateShadows,
8312 getEffectParams
8313 } = params;
8314 on('beforeInit', () => {
8315 if (swiper.params.effect !== effect) return;
8316 swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
8317 if (perspective && perspective()) {
8318 swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
8319 }
8320 const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
8321 Object.assign(swiper.params, overwriteParamsResult);
8322 Object.assign(swiper.originalParams, overwriteParamsResult);
8323 });
8324 on('setTranslate', () => {
8325 if (swiper.params.effect !== effect) return;
8326 setTranslate();
8327 });
8328 on('setTransition', (_s, duration) => {
8329 if (swiper.params.effect !== effect) return;
8330 setTransition(duration);
8331 });
8332 on('transitionEnd', () => {
8333 if (swiper.params.effect !== effect) return;
8334 if (recreateShadows) {
8335 if (!getEffectParams || !getEffectParams().slideShadows) return;
8336 // remove shadows
8337 swiper.slides.forEach(slideEl => {
8338 slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => shadowEl.remove());
8339 });
8340 // create new one
8341 recreateShadows();
8342 }
8343 });
8344 let requireUpdateOnVirtual;
8345 on('virtualUpdate', () => {
8346 if (swiper.params.effect !== effect) return;
8347 if (!swiper.slides.length) {
8348 requireUpdateOnVirtual = true;
8349 }
8350 requestAnimationFrame(() => {
8351 if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {
8352 setTranslate();
8353 requireUpdateOnVirtual = false;
8354 }
8355 });
8356 });
8357 }
8358
8359 function effectTarget(effectParams, slideEl) {
8360 const transformEl = getSlideTransformEl(slideEl);
8361 if (transformEl !== slideEl) {
8362 transformEl.style.backfaceVisibility = 'hidden';
8363 transformEl.style['-webkit-backface-visibility'] = 'hidden';
8364 }
8365 return transformEl;
8366 }
8367
8368 function effectVirtualTransitionEnd(_ref) {
8369 let {
8370 swiper,
8371 duration,
8372 transformElements,
8373 allSlides
8374 } = _ref;
8375 const {
8376 activeIndex
8377 } = swiper;
8378 const getSlide = el => {
8379 if (!el.parentElement) {
8380 // assume shadow root
8381 const slide = swiper.slides.filter(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode)[0];
8382 return slide;
8383 }
8384 return el.parentElement;
8385 };
8386 if (swiper.params.virtualTranslate && duration !== 0) {
8387 let eventTriggered = false;
8388 let transitionEndTarget;
8389 if (allSlides) {
8390 transitionEndTarget = transformElements;
8391 } else {
8392 transitionEndTarget = transformElements.filter(transformEl => {
8393 const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
8394 return swiper.getSlideIndex(el) === activeIndex;
8395 });
8396 }
8397 transitionEndTarget.forEach(el => {
8398 elementTransitionEnd(el, () => {
8399 if (eventTriggered) return;
8400 if (!swiper || swiper.destroyed) return;
8401 eventTriggered = true;
8402 swiper.animating = false;
8403 const evt = new window.CustomEvent('transitionend', {
8404 bubbles: true,
8405 cancelable: true
8406 });
8407 swiper.wrapperEl.dispatchEvent(evt);
8408 });
8409 });
8410 }
8411 }
8412
8413 function EffectFade(_ref) {
8414 let {
8415 swiper,
8416 extendParams,
8417 on
8418 } = _ref;
8419 extendParams({
8420 fadeEffect: {
8421 crossFade: false
8422 }
8423 });
8424 const setTranslate = () => {
8425 const {
8426 slides
8427 } = swiper;
8428 const params = swiper.params.fadeEffect;
8429 for (let i = 0; i < slides.length; i += 1) {
8430 const slideEl = swiper.slides[i];
8431 const offset = slideEl.swiperSlideOffset;
8432 let tx = -offset;
8433 if (!swiper.params.virtualTranslate) tx -= swiper.translate;
8434 let ty = 0;
8435 if (!swiper.isHorizontal()) {
8436 ty = tx;
8437 tx = 0;
8438 }
8439 const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
8440 const targetEl = effectTarget(params, slideEl);
8441 targetEl.style.opacity = slideOpacity;
8442 targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
8443 }
8444 };
8445 const setTransition = duration => {
8446 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
8447 transformElements.forEach(el => {
8448 el.style.transitionDuration = `${duration}ms`;
8449 });
8450 effectVirtualTransitionEnd({
8451 swiper,
8452 duration,
8453 transformElements,
8454 allSlides: true
8455 });
8456 };
8457 effectInit({
8458 effect: 'fade',
8459 swiper,
8460 on,
8461 setTranslate,
8462 setTransition,
8463 overwriteParams: () => ({
8464 slidesPerView: 1,
8465 slidesPerGroup: 1,
8466 watchSlidesProgress: true,
8467 spaceBetween: 0,
8468 virtualTranslate: !swiper.params.cssMode
8469 })
8470 });
8471 }
8472
8473 function EffectCube(_ref) {
8474 let {
8475 swiper,
8476 extendParams,
8477 on
8478 } = _ref;
8479 extendParams({
8480 cubeEffect: {
8481 slideShadows: true,
8482 shadow: true,
8483 shadowOffset: 20,
8484 shadowScale: 0.94
8485 }
8486 });
8487 const createSlideShadows = (slideEl, progress, isHorizontal) => {
8488 let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
8489 let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
8490 if (!shadowBefore) {
8491 shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' '));
8492 slideEl.append(shadowBefore);
8493 }
8494 if (!shadowAfter) {
8495 shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' '));
8496 slideEl.append(shadowAfter);
8497 }
8498 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
8499 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
8500 };
8501 const recreateShadows = () => {
8502 // create new ones
8503 const isHorizontal = swiper.isHorizontal();
8504 swiper.slides.forEach(slideEl => {
8505 const progress = Math.max(Math.min(slideEl.progress, 1), -1);
8506 createSlideShadows(slideEl, progress, isHorizontal);
8507 });
8508 };
8509 const setTranslate = () => {
8510 const {
8511 el,
8512 wrapperEl,
8513 slides,
8514 width: swiperWidth,
8515 height: swiperHeight,
8516 rtlTranslate: rtl,
8517 size: swiperSize,
8518 browser
8519 } = swiper;
8520 const params = swiper.params.cubeEffect;
8521 const isHorizontal = swiper.isHorizontal();
8522 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
8523 let wrapperRotate = 0;
8524 let cubeShadowEl;
8525 if (params.shadow) {
8526 if (isHorizontal) {
8527 cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow');
8528 if (!cubeShadowEl) {
8529 cubeShadowEl = createElement('div', 'swiper-cube-shadow');
8530 swiper.wrapperEl.append(cubeShadowEl);
8531 }
8532 cubeShadowEl.style.height = `${swiperWidth}px`;
8533 } else {
8534 cubeShadowEl = el.querySelector('.swiper-cube-shadow');
8535 if (!cubeShadowEl) {
8536 cubeShadowEl = createElement('div', 'swiper-cube-shadow');
8537 el.append(cubeShadowEl);
8538 }
8539 }
8540 }
8541 for (let i = 0; i < slides.length; i += 1) {
8542 const slideEl = slides[i];
8543 let slideIndex = i;
8544 if (isVirtual) {
8545 slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
8546 }
8547 let slideAngle = slideIndex * 90;
8548 let round = Math.floor(slideAngle / 360);
8549 if (rtl) {
8550 slideAngle = -slideAngle;
8551 round = Math.floor(-slideAngle / 360);
8552 }
8553 const progress = Math.max(Math.min(slideEl.progress, 1), -1);
8554 let tx = 0;
8555 let ty = 0;
8556 let tz = 0;
8557 if (slideIndex % 4 === 0) {
8558 tx = -round * 4 * swiperSize;
8559 tz = 0;
8560 } else if ((slideIndex - 1) % 4 === 0) {
8561 tx = 0;
8562 tz = -round * 4 * swiperSize;
8563 } else if ((slideIndex - 2) % 4 === 0) {
8564 tx = swiperSize + round * 4 * swiperSize;
8565 tz = swiperSize;
8566 } else if ((slideIndex - 3) % 4 === 0) {
8567 tx = -swiperSize;
8568 tz = 3 * swiperSize + swiperSize * 4 * round;
8569 }
8570 if (rtl) {
8571 tx = -tx;
8572 }
8573 if (!isHorizontal) {
8574 ty = tx;
8575 tx = 0;
8576 }
8577 const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
8578 if (progress <= 1 && progress > -1) {
8579 wrapperRotate = slideIndex * 90 + progress * 90;
8580 if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
8581 }
8582 slideEl.style.transform = transform;
8583 if (params.slideShadows) {
8584 createSlideShadows(slideEl, progress, isHorizontal);
8585 }
8586 }
8587 wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
8588 wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
8589 if (params.shadow) {
8590 if (isHorizontal) {
8591 cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`;
8592 } else {
8593 const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
8594 const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
8595 const scale1 = params.shadowScale;
8596 const scale2 = params.shadowScale / multiplier;
8597 const offset = params.shadowOffset;
8598 cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`;
8599 }
8600 }
8601 const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
8602 wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`;
8603 wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
8604 };
8605 const setTransition = duration => {
8606 const {
8607 el,
8608 slides
8609 } = swiper;
8610 slides.forEach(slideEl => {
8611 slideEl.style.transitionDuration = `${duration}ms`;
8612 slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => {
8613 subEl.style.transitionDuration = `${duration}ms`;
8614 });
8615 });
8616 if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
8617 const shadowEl = el.querySelector('.swiper-cube-shadow');
8618 if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
8619 }
8620 };
8621 effectInit({
8622 effect: 'cube',
8623 swiper,
8624 on,
8625 setTranslate,
8626 setTransition,
8627 recreateShadows,
8628 getEffectParams: () => swiper.params.cubeEffect,
8629 perspective: () => true,
8630 overwriteParams: () => ({
8631 slidesPerView: 1,
8632 slidesPerGroup: 1,
8633 watchSlidesProgress: true,
8634 resistanceRatio: 0,
8635 spaceBetween: 0,
8636 centeredSlides: false,
8637 virtualTranslate: true
8638 })
8639 });
8640 }
8641
8642 function createShadow(suffix, slideEl, side) {
8643 const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`;
8644 const shadowContainer = getSlideTransformEl(slideEl);
8645 let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`);
8646 if (!shadowEl) {
8647 shadowEl = createElement('div', shadowClass.split(' '));
8648 shadowContainer.append(shadowEl);
8649 }
8650 return shadowEl;
8651 }
8652
8653 function EffectFlip(_ref) {
8654 let {
8655 swiper,
8656 extendParams,
8657 on
8658 } = _ref;
8659 extendParams({
8660 flipEffect: {
8661 slideShadows: true,
8662 limitRotation: true
8663 }
8664 });
8665 const createSlideShadows = (slideEl, progress) => {
8666 let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
8667 let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
8668 if (!shadowBefore) {
8669 shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top');
8670 }
8671 if (!shadowAfter) {
8672 shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
8673 }
8674 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
8675 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
8676 };
8677 const recreateShadows = () => {
8678 // Set shadows
8679 swiper.params.flipEffect;
8680 swiper.slides.forEach(slideEl => {
8681 let progress = slideEl.progress;
8682 if (swiper.params.flipEffect.limitRotation) {
8683 progress = Math.max(Math.min(slideEl.progress, 1), -1);
8684 }
8685 createSlideShadows(slideEl, progress);
8686 });
8687 };
8688 const setTranslate = () => {
8689 const {
8690 slides,
8691 rtlTranslate: rtl
8692 } = swiper;
8693 const params = swiper.params.flipEffect;
8694 for (let i = 0; i < slides.length; i += 1) {
8695 const slideEl = slides[i];
8696 let progress = slideEl.progress;
8697 if (swiper.params.flipEffect.limitRotation) {
8698 progress = Math.max(Math.min(slideEl.progress, 1), -1);
8699 }
8700 const offset = slideEl.swiperSlideOffset;
8701 const rotate = -180 * progress;
8702 let rotateY = rotate;
8703 let rotateX = 0;
8704 let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
8705 let ty = 0;
8706 if (!swiper.isHorizontal()) {
8707 ty = tx;
8708 tx = 0;
8709 rotateX = -rotateY;
8710 rotateY = 0;
8711 } else if (rtl) {
8712 rotateY = -rotateY;
8713 }
8714 slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
8715 if (params.slideShadows) {
8716 createSlideShadows(slideEl, progress);
8717 }
8718 const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
8719 const targetEl = effectTarget(params, slideEl);
8720 targetEl.style.transform = transform;
8721 }
8722 };
8723 const setTransition = duration => {
8724 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
8725 transformElements.forEach(el => {
8726 el.style.transitionDuration = `${duration}ms`;
8727 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
8728 shadowEl.style.transitionDuration = `${duration}ms`;
8729 });
8730 });
8731 effectVirtualTransitionEnd({
8732 swiper,
8733 duration,
8734 transformElements
8735 });
8736 };
8737 effectInit({
8738 effect: 'flip',
8739 swiper,
8740 on,
8741 setTranslate,
8742 setTransition,
8743 recreateShadows,
8744 getEffectParams: () => swiper.params.flipEffect,
8745 perspective: () => true,
8746 overwriteParams: () => ({
8747 slidesPerView: 1,
8748 slidesPerGroup: 1,
8749 watchSlidesProgress: true,
8750 spaceBetween: 0,
8751 virtualTranslate: !swiper.params.cssMode
8752 })
8753 });
8754 }
8755
8756 function EffectCoverflow(_ref) {
8757 let {
8758 swiper,
8759 extendParams,
8760 on
8761 } = _ref;
8762 extendParams({
8763 coverflowEffect: {
8764 rotate: 50,
8765 stretch: 0,
8766 depth: 100,
8767 scale: 1,
8768 modifier: 1,
8769 slideShadows: true
8770 }
8771 });
8772 const setTranslate = () => {
8773 const {
8774 width: swiperWidth,
8775 height: swiperHeight,
8776 slides,
8777 slidesSizesGrid
8778 } = swiper;
8779 const params = swiper.params.coverflowEffect;
8780 const isHorizontal = swiper.isHorizontal();
8781 const transform = swiper.translate;
8782 const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
8783 const rotate = isHorizontal ? params.rotate : -params.rotate;
8784 const translate = params.depth;
8785 // Each slide offset from center
8786 for (let i = 0, length = slides.length; i < length; i += 1) {
8787 const slideEl = slides[i];
8788 const slideSize = slidesSizesGrid[i];
8789 const slideOffset = slideEl.swiperSlideOffset;
8790 const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
8791 const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
8792 let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
8793 let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
8794 // var rotateZ = 0
8795 let translateZ = -translate * Math.abs(offsetMultiplier);
8796 let stretch = params.stretch;
8797 // Allow percentage to make a relative stretch for responsive sliders
8798 if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
8799 stretch = parseFloat(params.stretch) / 100 * slideSize;
8800 }
8801 let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
8802 let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
8803 let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
8804
8805 // Fix for ultra small values
8806 if (Math.abs(translateX) < 0.001) translateX = 0;
8807 if (Math.abs(translateY) < 0.001) translateY = 0;
8808 if (Math.abs(translateZ) < 0.001) translateZ = 0;
8809 if (Math.abs(rotateY) < 0.001) rotateY = 0;
8810 if (Math.abs(rotateX) < 0.001) rotateX = 0;
8811 if (Math.abs(scale) < 0.001) scale = 0;
8812 const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
8813 const targetEl = effectTarget(params, slideEl);
8814 targetEl.style.transform = slideTransform;
8815 slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
8816 if (params.slideShadows) {
8817 // Set shadows
8818 let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
8819 let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
8820 if (!shadowBeforeEl) {
8821 shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top');
8822 }
8823 if (!shadowAfterEl) {
8824 shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom');
8825 }
8826 if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
8827 if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
8828 }
8829 }
8830 };
8831 const setTransition = duration => {
8832 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
8833 transformElements.forEach(el => {
8834 el.style.transitionDuration = `${duration}ms`;
8835 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
8836 shadowEl.style.transitionDuration = `${duration}ms`;
8837 });
8838 });
8839 };
8840 effectInit({
8841 effect: 'coverflow',
8842 swiper,
8843 on,
8844 setTranslate,
8845 setTransition,
8846 perspective: () => true,
8847 overwriteParams: () => ({
8848 watchSlidesProgress: true
8849 })
8850 });
8851 }
8852
8853 function EffectCreative(_ref) {
8854 let {
8855 swiper,
8856 extendParams,
8857 on
8858 } = _ref;
8859 extendParams({
8860 creativeEffect: {
8861 limitProgress: 1,
8862 shadowPerProgress: false,
8863 progressMultiplier: 1,
8864 perspective: true,
8865 prev: {
8866 translate: [0, 0, 0],
8867 rotate: [0, 0, 0],
8868 opacity: 1,
8869 scale: 1
8870 },
8871 next: {
8872 translate: [0, 0, 0],
8873 rotate: [0, 0, 0],
8874 opacity: 1,
8875 scale: 1
8876 }
8877 }
8878 });
8879 const getTranslateValue = value => {
8880 if (typeof value === 'string') return value;
8881 return `${value}px`;
8882 };
8883 const setTranslate = () => {
8884 const {
8885 slides,
8886 wrapperEl,
8887 slidesSizesGrid
8888 } = swiper;
8889 const params = swiper.params.creativeEffect;
8890 const {
8891 progressMultiplier: multiplier
8892 } = params;
8893 const isCenteredSlides = swiper.params.centeredSlides;
8894 if (isCenteredSlides) {
8895 const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
8896 wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
8897 }
8898 for (let i = 0; i < slides.length; i += 1) {
8899 const slideEl = slides[i];
8900 const slideProgress = slideEl.progress;
8901 const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
8902 let originalProgress = progress;
8903 if (!isCenteredSlides) {
8904 originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
8905 }
8906 const offset = slideEl.swiperSlideOffset;
8907 const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
8908 const r = [0, 0, 0];
8909 let custom = false;
8910 if (!swiper.isHorizontal()) {
8911 t[1] = t[0];
8912 t[0] = 0;
8913 }
8914 let data = {
8915 translate: [0, 0, 0],
8916 rotate: [0, 0, 0],
8917 scale: 1,
8918 opacity: 1
8919 };
8920 if (progress < 0) {
8921 data = params.next;
8922 custom = true;
8923 } else if (progress > 0) {
8924 data = params.prev;
8925 custom = true;
8926 }
8927 // set translate
8928 t.forEach((value, index) => {
8929 t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
8930 });
8931 // set rotates
8932 r.forEach((value, index) => {
8933 r[index] = data.rotate[index] * Math.abs(progress * multiplier);
8934 });
8935 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
8936 const translateString = t.join(', ');
8937 const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
8938 const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
8939 const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
8940 const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
8941
8942 // Set shadows
8943 if (custom && data.shadow || !custom) {
8944 let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
8945 if (!shadowEl && data.shadow) {
8946 shadowEl = createShadow('creative', slideEl);
8947 }
8948 if (shadowEl) {
8949 const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
8950 shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
8951 }
8952 }
8953 const targetEl = effectTarget(params, slideEl);
8954 targetEl.style.transform = transform;
8955 targetEl.style.opacity = opacityString;
8956 if (data.origin) {
8957 targetEl.style.transformOrigin = data.origin;
8958 }
8959 }
8960 };
8961 const setTransition = duration => {
8962 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
8963 transformElements.forEach(el => {
8964 el.style.transitionDuration = `${duration}ms`;
8965 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
8966 shadowEl.style.transitionDuration = `${duration}ms`;
8967 });
8968 });
8969 effectVirtualTransitionEnd({
8970 swiper,
8971 duration,
8972 transformElements,
8973 allSlides: true
8974 });
8975 };
8976 effectInit({
8977 effect: 'creative',
8978 swiper,
8979 on,
8980 setTranslate,
8981 setTransition,
8982 perspective: () => swiper.params.creativeEffect.perspective,
8983 overwriteParams: () => ({
8984 watchSlidesProgress: true,
8985 virtualTranslate: !swiper.params.cssMode
8986 })
8987 });
8988 }
8989
8990 function EffectCards(_ref) {
8991 let {
8992 swiper,
8993 extendParams,
8994 on
8995 } = _ref;
8996 extendParams({
8997 cardsEffect: {
8998 slideShadows: true,
8999 rotate: true,
9000 perSlideRotate: 2,
9001 perSlideOffset: 8
9002 }
9003 });
9004 const setTranslate = () => {
9005 const {
9006 slides,
9007 activeIndex,
9008 rtlTranslate: rtl
9009 } = swiper;
9010 const params = swiper.params.cardsEffect;
9011 const {
9012 startTranslate,
9013 isTouched
9014 } = swiper.touchEventsData;
9015 const currentTranslate = rtl ? -swiper.translate : swiper.translate;
9016 for (let i = 0; i < slides.length; i += 1) {
9017 const slideEl = slides[i];
9018 const slideProgress = slideEl.progress;
9019 const progress = Math.min(Math.max(slideProgress, -4), 4);
9020 let offset = slideEl.swiperSlideOffset;
9021 if (swiper.params.centeredSlides && !swiper.params.cssMode) {
9022 swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
9023 }
9024 if (swiper.params.centeredSlides && swiper.params.cssMode) {
9025 offset -= slides[0].swiperSlideOffset;
9026 }
9027 let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
9028 let tY = 0;
9029 const tZ = -100 * Math.abs(progress);
9030 let scale = 1;
9031 let rotate = -params.perSlideRotate * progress;
9032 let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
9033 const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
9034 const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;
9035 const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;
9036 if (isSwipeToNext || isSwipeToPrev) {
9037 const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
9038 rotate += -28 * progress * subProgress;
9039 scale += -0.5 * subProgress;
9040 tXAdd += 96 * subProgress;
9041 tY = `${-25 * subProgress * Math.abs(progress)}%`;
9042 }
9043 if (progress < 0) {
9044 // next
9045 tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
9046 } else if (progress > 0) {
9047 // prev
9048 tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
9049 } else {
9050 tX = `${tX}px`;
9051 }
9052 if (!swiper.isHorizontal()) {
9053 const prevY = tY;
9054 tY = tX;
9055 tX = prevY;
9056 }
9057 const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
9058
9059 /* eslint-disable */
9060 const transform = `
9061 translate3d(${tX}, ${tY}, ${tZ}px)
9062 rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg)
9063 scale(${scaleString})
9064 `;
9065 /* eslint-enable */
9066
9067 if (params.slideShadows) {
9068 // Set shadows
9069 let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
9070 if (!shadowEl) {
9071 shadowEl = createShadow('cards', slideEl);
9072 }
9073 if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
9074 }
9075 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
9076 const targetEl = effectTarget(params, slideEl);
9077 targetEl.style.transform = transform;
9078 }
9079 };
9080 const setTransition = duration => {
9081 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
9082 transformElements.forEach(el => {
9083 el.style.transitionDuration = `${duration}ms`;
9084 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
9085 shadowEl.style.transitionDuration = `${duration}ms`;
9086 });
9087 });
9088 effectVirtualTransitionEnd({
9089 swiper,
9090 duration,
9091 transformElements
9092 });
9093 };
9094 effectInit({
9095 effect: 'cards',
9096 swiper,
9097 on,
9098 setTranslate,
9099 setTransition,
9100 perspective: () => true,
9101 overwriteParams: () => ({
9102 watchSlidesProgress: true,
9103 virtualTranslate: !swiper.params.cssMode
9104 })
9105 });
9106 }
9107
9108 /**
9109 * Swiper 10.0.4
9110 * Most modern mobile touch slider and framework with hardware accelerated transitions
9111 * https://swiperjs.com
9112 *
9113 * Copyright 2014-2023 Vladimir Kharlampidi
9114 *
9115 * Released under the MIT License
9116 *
9117 * Released on: July 8, 2023
9118 */
9119
9120
9121 // Swiper Class
9122 const modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards];
9123 Swiper.use(modules);
9124
9125 /* underscore in name -> watch for changes */
9126 const paramsList = ['eventsPrefix', 'injectStyles', 'injectStylesUrls', 'modules', 'init', '_direction', 'oneWayMovement', 'touchEventsTarget', 'initialSlide', '_speed', 'cssMode', 'updateOnWindowResize', 'resizeObserver', 'nested', 'focusableElements', '_enabled', '_width', '_height', 'preventInteractionOnTransition', 'userAgent', 'url', '_edgeSwipeDetection', '_edgeSwipeThreshold', '_freeMode', '_autoHeight', 'setWrapperSize', 'virtualTranslate', '_effect', 'breakpoints', '_spaceBetween', '_slidesPerView', 'maxBackfaceHiddenSlides', '_grid', '_slidesPerGroup', '_slidesPerGroupSkip', '_slidesPerGroupAuto', '_centeredSlides', '_centeredSlidesBounds', '_slidesOffsetBefore', '_slidesOffsetAfter', 'normalizeSlideIndex', '_centerInsufficientSlides', '_watchOverflow', 'roundLengths', 'touchRatio', 'touchAngle', 'simulateTouch', '_shortSwipes', '_longSwipes', 'longSwipesRatio', 'longSwipesMs', '_followFinger', 'allowTouchMove', '_threshold', 'touchMoveStopPropagation', 'touchStartPreventDefault', 'touchStartForcePreventDefault', 'touchReleaseOnEdges', 'uniqueNavElements', '_resistance', '_resistanceRatio', '_watchSlidesProgress', '_grabCursor', 'preventClicks', 'preventClicksPropagation', '_slideToClickedSlide', '_loop', 'loopedSlides', 'loopPreventsSliding', '_rewind', '_allowSlidePrev', '_allowSlideNext', '_swipeHandler', '_noSwiping', 'noSwipingClass', 'noSwipingSelector', 'passiveListeners', 'containerModifierClass', 'slideClass', 'slideActiveClass', 'slideVisibleClass', 'slideNextClass', 'slidePrevClass', 'wrapperClass', 'lazyPreloaderClass', 'lazyPreloadPrevNext', 'runCallbacksOnInit', 'observer', 'observeParents', 'observeSlideChildren',
9127 // modules
9128 'a11y', '_autoplay', '_controller', 'coverflowEffect', 'cubeEffect', 'fadeEffect', 'flipEffect', 'creativeEffect', 'cardsEffect', 'hashNavigation', 'history', 'keyboard', 'mousewheel', '_navigation', '_pagination', 'parallax', '_scrollbar', '_thumbs', 'virtual', 'zoom', 'control'];
9129
9130 function isObject(o) {
9131 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
9132 }
9133 function extend(target, src) {
9134 const noExtend = ['__proto__', 'constructor', 'prototype'];
9135 Object.keys(src).filter(key => noExtend.indexOf(key) < 0).forEach(key => {
9136 if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject(src[key]) && isObject(target[key]) && Object.keys(src[key]).length > 0) {
9137 if (src[key].__swiper__) target[key] = src[key];else extend(target[key], src[key]);
9138 } else {
9139 target[key] = src[key];
9140 }
9141 });
9142 }
9143 function needsNavigation(params) {
9144 if (params === void 0) {
9145 params = {};
9146 }
9147 return params.navigation && typeof params.navigation.nextEl === 'undefined' && typeof params.navigation.prevEl === 'undefined';
9148 }
9149 function needsPagination(params) {
9150 if (params === void 0) {
9151 params = {};
9152 }
9153 return params.pagination && typeof params.pagination.el === 'undefined';
9154 }
9155 function needsScrollbar(params) {
9156 if (params === void 0) {
9157 params = {};
9158 }
9159 return params.scrollbar && typeof params.scrollbar.el === 'undefined';
9160 }
9161 function attrToProp(attrName) {
9162 if (attrName === void 0) {
9163 attrName = '';
9164 }
9165 return attrName.replace(/-[a-z]/g, l => l.toUpperCase().replace('-', ''));
9166 }
9167
9168 function updateSwiper(_ref) {
9169 let {
9170 swiper,
9171 slides,
9172 passedParams,
9173 changedParams,
9174 nextEl,
9175 prevEl,
9176 scrollbarEl,
9177 paginationEl
9178 } = _ref;
9179 const updateParams = changedParams.filter(key => key !== 'children' && key !== 'direction' && key !== 'wrapperClass');
9180 const {
9181 params: currentParams,
9182 pagination,
9183 navigation,
9184 scrollbar,
9185 virtual,
9186 thumbs
9187 } = swiper;
9188 let needThumbsInit;
9189 let needControllerInit;
9190 let needPaginationInit;
9191 let needScrollbarInit;
9192 let needNavigationInit;
9193 let loopNeedDestroy;
9194 let loopNeedEnable;
9195 let loopNeedReloop;
9196 if (changedParams.includes('thumbs') && passedParams.thumbs && passedParams.thumbs.swiper && currentParams.thumbs && !currentParams.thumbs.swiper) {
9197 needThumbsInit = true;
9198 }
9199 if (changedParams.includes('controller') && passedParams.controller && passedParams.controller.control && currentParams.controller && !currentParams.controller.control) {
9200 needControllerInit = true;
9201 }
9202 if (changedParams.includes('pagination') && passedParams.pagination && (passedParams.pagination.el || paginationEl) && (currentParams.pagination || currentParams.pagination === false) && pagination && !pagination.el) {
9203 needPaginationInit = true;
9204 }
9205 if (changedParams.includes('scrollbar') && passedParams.scrollbar && (passedParams.scrollbar.el || scrollbarEl) && (currentParams.scrollbar || currentParams.scrollbar === false) && scrollbar && !scrollbar.el) {
9206 needScrollbarInit = true;
9207 }
9208 if (changedParams.includes('navigation') && passedParams.navigation && (passedParams.navigation.prevEl || prevEl) && (passedParams.navigation.nextEl || nextEl) && (currentParams.navigation || currentParams.navigation === false) && navigation && !navigation.prevEl && !navigation.nextEl) {
9209 needNavigationInit = true;
9210 }
9211 const destroyModule = mod => {
9212 if (!swiper[mod]) return;
9213 swiper[mod].destroy();
9214 if (mod === 'navigation') {
9215 if (swiper.isElement) {
9216 swiper[mod].prevEl.remove();
9217 swiper[mod].nextEl.remove();
9218 }
9219 currentParams[mod].prevEl = undefined;
9220 currentParams[mod].nextEl = undefined;
9221 swiper[mod].prevEl = undefined;
9222 swiper[mod].nextEl = undefined;
9223 } else {
9224 if (swiper.isElement) {
9225 swiper[mod].el.remove();
9226 }
9227 currentParams[mod].el = undefined;
9228 swiper[mod].el = undefined;
9229 }
9230 };
9231 if (changedParams.includes('loop') && swiper.isElement) {
9232 if (currentParams.loop && !passedParams.loop) {
9233 loopNeedDestroy = true;
9234 } else if (!currentParams.loop && passedParams.loop) {
9235 loopNeedEnable = true;
9236 } else {
9237 loopNeedReloop = true;
9238 }
9239 }
9240 updateParams.forEach(key => {
9241 if (isObject(currentParams[key]) && isObject(passedParams[key])) {
9242 extend(currentParams[key], passedParams[key]);
9243 if ((key === 'navigation' || key === 'pagination' || key === 'scrollbar') && 'enabled' in passedParams[key] && !passedParams[key].enabled) {
9244 destroyModule(key);
9245 }
9246 } else {
9247 const newValue = passedParams[key];
9248 if ((newValue === true || newValue === false) && (key === 'navigation' || key === 'pagination' || key === 'scrollbar')) {
9249 if (newValue === false) {
9250 destroyModule(key);
9251 }
9252 } else {
9253 currentParams[key] = passedParams[key];
9254 }
9255 }
9256 });
9257 if (updateParams.includes('controller') && !needControllerInit && swiper.controller && swiper.controller.control && currentParams.controller && currentParams.controller.control) {
9258 swiper.controller.control = currentParams.controller.control;
9259 }
9260 if (changedParams.includes('children') && slides && virtual && currentParams.virtual.enabled) {
9261 virtual.slides = slides;
9262 virtual.update(true);
9263 }
9264 if (changedParams.includes('children') && slides && currentParams.loop) {
9265 loopNeedReloop = true;
9266 }
9267 if (needThumbsInit) {
9268 const initialized = thumbs.init();
9269 if (initialized) thumbs.update(true);
9270 }
9271 if (needControllerInit) {
9272 swiper.controller.control = currentParams.controller.control;
9273 }
9274 if (needPaginationInit) {
9275 if (swiper.isElement && (!paginationEl || typeof paginationEl === 'string')) {
9276 paginationEl = document.createElement('div');
9277 paginationEl.classList.add('swiper-pagination');
9278 swiper.el.appendChild(paginationEl);
9279 }
9280 if (paginationEl) currentParams.pagination.el = paginationEl;
9281 pagination.init();
9282 pagination.render();
9283 pagination.update();
9284 }
9285 if (needScrollbarInit) {
9286 if (swiper.isElement && (!scrollbarEl || typeof scrollbarEl === 'string')) {
9287 scrollbarEl = document.createElement('div');
9288 scrollbarEl.classList.add('swiper-scrollbar');
9289 swiper.el.appendChild(scrollbarEl);
9290 }
9291 if (scrollbarEl) currentParams.scrollbar.el = scrollbarEl;
9292 scrollbar.init();
9293 scrollbar.updateSize();
9294 scrollbar.setTranslate();
9295 }
9296 if (needNavigationInit) {
9297 if (swiper.isElement) {
9298 if (!nextEl || typeof nextEl === 'string') {
9299 nextEl = document.createElement('div');
9300 nextEl.classList.add('swiper-button-next');
9301 nextEl.innerHTML = swiper.hostEl.nextButtonSvg;
9302 swiper.el.appendChild(nextEl);
9303 }
9304 if (!prevEl || typeof prevEl === 'string') {
9305 prevEl = document.createElement('div');
9306 prevEl.classList.add('swiper-button-prev');
9307 nextEl.innerHTML = swiper.hostEl.prevButtonSvg;
9308 swiper.el.appendChild(prevEl);
9309 }
9310 }
9311 if (nextEl) currentParams.navigation.nextEl = nextEl;
9312 if (prevEl) currentParams.navigation.prevEl = prevEl;
9313 navigation.init();
9314 navigation.update();
9315 }
9316 if (changedParams.includes('allowSlideNext')) {
9317 swiper.allowSlideNext = passedParams.allowSlideNext;
9318 }
9319 if (changedParams.includes('allowSlidePrev')) {
9320 swiper.allowSlidePrev = passedParams.allowSlidePrev;
9321 }
9322 if (changedParams.includes('direction')) {
9323 swiper.changeDirection(passedParams.direction, false);
9324 }
9325 if (loopNeedDestroy || loopNeedReloop) {
9326 swiper.loopDestroy();
9327 }
9328 if (loopNeedEnable || loopNeedReloop) {
9329 swiper.loopCreate();
9330 }
9331 swiper.update();
9332 }
9333
9334 const formatValue = val => {
9335 if (parseFloat(val) === Number(val)) return Number(val);
9336 if (val === 'true') return true;
9337 if (val === '') return true;
9338 if (val === 'false') return false;
9339 if (val === 'null') return null;
9340 if (val === 'undefined') return undefined;
9341 if (typeof val === 'string' && val.includes('{') && val.includes('}') && val.includes('"')) {
9342 let v;
9343 try {
9344 v = JSON.parse(val);
9345 } catch (err) {
9346 v = val;
9347 }
9348 return v;
9349 }
9350 return val;
9351 };
9352 const modulesParamsList = ['a11y', 'autoplay', 'controller', 'cards-effect', 'coverflow-effect', 'creative-effect', 'cube-effect', 'fade-effect', 'flip-effect', 'free-mode', 'grid', 'hash-navigation', 'history', 'keyboard', 'mousewheel', 'navigation', 'pagination', 'parallax', 'scrollbar', 'thumbs', 'virtual', 'zoom'];
9353 function getParams(element, propName, propValue) {
9354 const params = {};
9355 const passedParams = {};
9356 extend(params, defaults);
9357 const localParamsList = [...paramsList, 'on'];
9358 const allowedParams = localParamsList.map(key => key.replace(/_/, ''));
9359
9360 // First check props
9361 localParamsList.forEach(paramName => {
9362 paramName = paramName.replace('_', '');
9363 if (typeof element[paramName] !== 'undefined') {
9364 passedParams[paramName] = element[paramName];
9365 }
9366 });
9367
9368 // Attributes
9369 const attrsList = [...element.attributes];
9370 if (typeof propName === 'string' && typeof propValue !== 'undefined') {
9371 attrsList.push({
9372 name: propName,
9373 value: propValue
9374 });
9375 }
9376 attrsList.forEach(attr => {
9377 const moduleParam = modulesParamsList.filter(mParam => attr.name.indexOf(`${mParam}-`) === 0)[0];
9378 if (moduleParam) {
9379 const parentObjName = attrToProp(moduleParam);
9380 const subObjName = attrToProp(attr.name.split(`${moduleParam}-`)[1]);
9381 if (typeof passedParams[parentObjName] === 'undefined') passedParams[parentObjName] = {};
9382 if (passedParams[parentObjName] === true) {
9383 passedParams[parentObjName] = {
9384 enabled: true
9385 };
9386 }
9387 passedParams[parentObjName][subObjName] = formatValue(attr.value);
9388 } else {
9389 const name = attrToProp(attr.name);
9390 if (!allowedParams.includes(name)) return;
9391 const value = formatValue(attr.value);
9392 if (passedParams[name] && modulesParamsList.includes(attr.name)) {
9393 if (passedParams[name].constructor !== Object) {
9394 passedParams[name] = {};
9395 }
9396 passedParams[name].enabled = value;
9397 } else {
9398 passedParams[name] = value;
9399 }
9400 }
9401 });
9402 extend(params, passedParams);
9403 if (params.navigation) {
9404 params.navigation = {
9405 prevEl: '.swiper-button-prev',
9406 nextEl: '.swiper-button-next',
9407 ...(params.navigation !== true ? params.navigation : {})
9408 };
9409 } else if (params.navigation === false) {
9410 delete params.navigation;
9411 }
9412 if (params.scrollbar) {
9413 params.scrollbar = {
9414 el: '.swiper-scrollbar',
9415 ...(params.scrollbar !== true ? params.scrollbar : {})
9416 };
9417 } else if (params.scrollbar === false) {
9418 delete params.scrollbar;
9419 }
9420 if (params.pagination) {
9421 params.pagination = {
9422 el: '.swiper-pagination',
9423 ...(params.pagination !== true ? params.pagination : {})
9424 };
9425 } else if (params.pagination === false) {
9426 delete params.pagination;
9427 }
9428 return {
9429 params,
9430 passedParams
9431 };
9432 }
9433
9434 /**
9435 * Swiper Custom Element 10.0.4
9436 * Most modern mobile touch slider and framework with hardware accelerated transitions
9437 * https://swiperjs.com
9438 *
9439 * Copyright 2014-2023 Vladimir Kharlampidi
9440 *
9441 * Released under the MIT License
9442 *
9443 * Released on: July 8, 2023
9444 */
9445
9446
9447 /* eslint-disable spaced-comment */
9448
9449 const SwiperCSS = `:host{--swiper-theme-color:#007aff}:host{position:relative;display:block;margin-left:auto;margin-right:auto;z-index:1}.swiper{width:100%;height:100%;margin-left:auto;margin-right:auto;position:relative;overflow:hidden;overflow:clip;list-style:none;padding:0;z-index:1;display:block}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:flex;transition-property:transform;transition-timing-function:var(--swiper-wrapper-transition-timing-function,initial);box-sizing:content-box}.swiper-android ::slotted(swiper-slide),.swiper-ios ::slotted(swiper-slide),.swiper-wrapper{transform:translate3d(0px,0,0)}.swiper-horizontal{touch-action:pan-y}.swiper-vertical{touch-action:pan-x}::slotted(swiper-slide){flex-shrink:0;width:100%;height:100%;position:relative;transition-property:transform;display:block}::slotted(.swiper-slide-invisible-blank){visibility:hidden}.swiper-autoheight,.swiper-autoheight ::slotted(swiper-slide){height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden ::slotted(swiper-slide){transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d ::slotted(swiper-slide){transform-style:preserve-3d}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode ::slotted(swiper-slide){scroll-snap-align:start start}.swiper-css-mode.swiper-horizontal>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-css-mode.swiper-vertical>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-css-mode.swiper-free-mode>.swiper-wrapper{scroll-snap-type:none}.swiper-css-mode.swiper-free-mode ::slotted(swiper-slide){scroll-snap-align:none}.swiper-css-mode.swiper-centered>.swiper-wrapper::before{content:'';flex-shrink:0;order:9999}.swiper-css-mode.swiper-centered ::slotted(swiper-slide){scroll-snap-align:center center;scroll-snap-stop:always}.swiper-css-mode.swiper-centered.swiper-horizontal ::slotted(swiper-slide):first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper::before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-css-mode.swiper-centered.swiper-vertical ::slotted(swiper-slide):first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper::before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}.swiper-virtual ::slotted(swiper-slide){-webkit-backface-visibility:hidden;transform:translateZ(0)}.swiper-virtual.swiper-css-mode .swiper-wrapper::after{content:'';position:absolute;left:0;top:0;pointer-events:none}.swiper-virtual.swiper-css-mode.swiper-horizontal .swiper-wrapper::after{height:1px;width:var(--swiper-virtual-size)}.swiper-virtual.swiper-css-mode.swiper-vertical .swiper-wrapper::after{width:1px;height:var(--swiper-virtual-size)}:host{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next svg,.swiper-button-prev svg{width:100%;height:100%;object-fit:contain;transform-origin:center}.swiper-rtl .swiper-button-next svg,.swiper-rtl .swiper-button-prev svg{transform:rotate(180deg)}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:var(--swiper-navigation-sides-offset,10px);left:auto}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;transition:.3s opacity;transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-disabled>.swiper-pagination,.swiper-pagination.swiper-pagination-disabled{display:none!important}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:var(--swiper-pagination-bottom,8px);top:var(--swiper-pagination-top,auto);left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px));height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));display:inline-block;border-radius:var(--swiper-pagination-bullet-border-radius,50%);background:var(--swiper-pagination-bullet-inactive-color,#000);opacity:var(--swiper-pagination-bullet-inactive-opacity, .2)}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{opacity:var(--swiper-pagination-bullet-opacity, 1);background:var(--swiper-pagination-color,var(--swiper-theme-color))}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{right:var(--swiper-pagination-right,8px);left:var(--swiper-pagination-left,auto);top:50%;transform:translate3d(0px,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0;display:block}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:.2s transform,.2s top}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s left}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s right}.swiper-pagination-fraction{color:var(--swiper-pagination-fraction-color,inherit)}.swiper-pagination-progressbar{background:var(--swiper-pagination-progressbar-bg-color,rgba(0,0,0,.25));position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));position:absolute;left:0;top:0;width:100%;height:100%;transform:scale(0);transform-origin:left top}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:var(--swiper-pagination-progressbar-size,4px);left:0;top:0}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{width:var(--swiper-pagination-progressbar-size,4px);height:100%;left:0;top:0}.swiper-pagination-lock{display:none}.swiper-scrollbar{border-radius:var(--swiper-scrollbar-border-radius,10px);position:relative;-ms-touch-action:none;background:var(--swiper-scrollbar-bg-color,rgba(0,0,0,.1))}.swiper-scrollbar-disabled>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-disabled{display:none!important}.swiper-horizontal>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-horizontal{position:absolute;left:var(--swiper-scrollbar-sides-offset,1%);bottom:var(--swiper-scrollbar-bottom,4px);top:var(--swiper-scrollbar-top,auto);z-index:50;height:var(--swiper-scrollbar-size,4px);width:calc(100% - 2 * var(--swiper-scrollbar-sides-offset,1%))}.swiper-scrollbar.swiper-scrollbar-vertical,.swiper-vertical>.swiper-scrollbar{position:absolute;left:var(--swiper-scrollbar-left,auto);right:var(--swiper-scrollbar-right,4px);top:var(--swiper-scrollbar-sides-offset,1%);z-index:50;width:var(--swiper-scrollbar-size,4px);height:calc(100% - 2 * var(--swiper-scrollbar-sides-offset,1%))}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:var(--swiper-scrollbar-drag-bg-color,rgba(0,0,0,.5));border-radius:var(--swiper-scrollbar-border-radius,10px);left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}::slotted(.swiper-slide-zoomed){cursor:move;touch-action:none}.swiper .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-free-mode>.swiper-wrapper{transition-timing-function:ease-out;margin:0 auto}.swiper-grid>.swiper-wrapper{flex-wrap:wrap}.swiper-grid-column>.swiper-wrapper{flex-wrap:wrap;flex-direction:column}.swiper-fade.swiper-free-mode ::slotted(swiper-slide){transition-timing-function:ease-out}.swiper-fade ::slotted(swiper-slide){pointer-events:none;transition-property:opacity}.swiper-fade ::slotted(swiper-slide) ::slotted(swiper-slide){pointer-events:none}.swiper-fade ::slotted(.swiper-slide-active),.swiper-fade ::slotted(.swiper-slide-active) ::slotted(.swiper-slide-active){pointer-events:auto}.swiper-cube{overflow:visible}.swiper-cube ::slotted(swiper-slide){pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;visibility:hidden;transform-origin:0 0;width:100%;height:100%}.swiper-cube ::slotted(swiper-slide) ::slotted(swiper-slide){pointer-events:none}.swiper-cube.swiper-rtl ::slotted(swiper-slide){transform-origin:100% 0}.swiper-cube ::slotted(.swiper-slide-active),.swiper-cube ::slotted(.swiper-slide-active) ::slotted(.swiper-slide-active){pointer-events:auto}.swiper-cube ::slotted(.swiper-slide-active),.swiper-cube ::slotted(.swiper-slide-next),.swiper-cube ::slotted(.swiper-slide-prev){pointer-events:auto;visibility:visible}.swiper-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0px;width:100%;height:100%;opacity:.6;z-index:0}.swiper-cube .swiper-cube-shadow:before{content:'';background:#000;position:absolute;left:0;top:0;bottom:0;right:0;filter:blur(50px)}.swiper-cube ::slotted(.swiper-slide-next)+::slotted(swiper-slide){pointer-events:auto;visibility:visible}.swiper-flip{overflow:visible}.swiper-flip ::slotted(swiper-slide){pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-flip ::slotted(swiper-slide) ::slotted(swiper-slide){pointer-events:none}.swiper-flip ::slotted(.swiper-slide-active),.swiper-flip ::slotted(.swiper-slide-active) ::slotted(.swiper-slide-active){pointer-events:auto}.swiper-creative ::slotted(swiper-slide){-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;transition-property:transform,opacity,height}.swiper-cards{overflow:visible}.swiper-cards ::slotted(swiper-slide){transform-origin:center bottom;-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden}`;
9450 const SwiperSlideCSS = `::slotted(.swiper-slide-shadow),::slotted(.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-top){position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}::slotted(.swiper-slide-shadow){background:rgba(0,0,0,.15)}::slotted(.swiper-slide-shadow-left){background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-right){background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-top){background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-bottom){background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-lazy-preloader){animation:swiper-preloader-spin 1s infinite linear;width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;transform-origin:50%;box-sizing:border-box;border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top-color:transparent}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-top){z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-top){z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}`;
9451
9452 class DummyHTMLElement {}
9453 const ClassToExtend = typeof window === 'undefined' || typeof HTMLElement === 'undefined' ? DummyHTMLElement : HTMLElement;
9454 const arrowSvg = `<svg width="11" height="20" viewBox="0 0 11 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.38296 20.0762C0.111788 19.805 0.111788 19.3654 0.38296 19.0942L9.19758 10.2796L0.38296 1.46497C0.111788 1.19379 0.111788 0.754138 0.38296 0.482966C0.654131 0.211794 1.09379 0.211794 1.36496 0.482966L10.4341 9.55214C10.8359 9.9539 10.8359 10.6053 10.4341 11.007L1.36496 20.0762C1.09379 20.3474 0.654131 20.3474 0.38296 20.0762Z" fill="currentColor"/></svg>
9455 `;
9456 const addStyle = (shadowRoot, styles) => {
9457 if (typeof CSSStyleSheet !== 'undefined' && shadowRoot.adoptedStyleSheets) {
9458 const styleSheet = new CSSStyleSheet();
9459 styleSheet.replaceSync(styles);
9460 shadowRoot.adoptedStyleSheets = [styleSheet];
9461 } else {
9462 const style = document.createElement('style');
9463 style.rel = 'stylesheet';
9464 style.textContent = styles;
9465 shadowRoot.appendChild(style);
9466 }
9467 };
9468 class SwiperContainer extends ClassToExtend {
9469 constructor() {
9470 super();
9471 this.attachShadow({
9472 mode: 'open'
9473 });
9474 }
9475 static get nextButtonSvg() {
9476 return arrowSvg;
9477 }
9478 static get prevButtonSvg() {
9479 return arrowSvg.replace('/></svg>', ' transform-origin="center" transform="rotate(180)"/></svg>');
9480 }
9481 cssStyles() {
9482 return [SwiperCSS,
9483 // eslint-disable-line
9484 ...(this.injectStyles && Array.isArray(this.injectStyles) ? this.injectStyles : [])].join('\n');
9485 }
9486 cssLinks() {
9487 return this.injectStylesUrls || [];
9488 }
9489 render() {
9490 if (this.rendered) return;
9491
9492 // local styles
9493 const localStyles = this.cssStyles();
9494 if (localStyles.length) {
9495 addStyle(this.shadowRoot, localStyles);
9496 }
9497 this.cssLinks().forEach(url => {
9498 const linkExists = this.shadowRoot.querySelector(`link[href="${url}"]`);
9499 if (linkExists) return;
9500 const linkEl = document.createElement('link');
9501 linkEl.rel = 'stylesheet';
9502 linkEl.href = url;
9503 this.shadowRoot.appendChild(linkEl);
9504 });
9505 // prettier-ignore
9506 const el = document.createElement('div');
9507 el.classList.add('swiper');
9508 el.part = 'container';
9509 // prettier-ignore
9510 el.innerHTML = `
9511 <slot name="container-start"></slot>
9512 <div class="swiper-wrapper" part="wrapper">
9513 <slot></slot>
9514 </div>
9515 <slot name="container-end"></slot>
9516 ${needsNavigation(this.passedParams) ? `
9517 <div part="button-prev" class="swiper-button-prev">${this.constructor.prevButtonSvg}</div>
9518 <div part="button-next" class="swiper-button-next">${this.constructor.nextButtonSvg}</div>
9519 ` : ''}
9520 ${needsPagination(this.passedParams) ? `
9521 <div part="pagination" class="swiper-pagination"></div>
9522 ` : ''}
9523 ${needsScrollbar(this.passedParams) ? `
9524 <div part="scrollbar" class="swiper-scrollbar"></div>
9525 ` : ''}
9526 `;
9527 this.shadowRoot.appendChild(el);
9528 this.rendered = true;
9529 }
9530 initialize() {
9531 var _this = this;
9532 if (this.initialized) return;
9533 this.initialized = true;
9534 const {
9535 params: swiperParams,
9536 passedParams
9537 } = getParams(this);
9538 this.swiperParams = swiperParams;
9539 this.passedParams = passedParams;
9540 delete this.swiperParams.init;
9541 this.render();
9542 // eslint-disable-next-line
9543 this.swiper = new Swiper(this.shadowRoot.querySelector('.swiper'), {
9544 ...swiperParams,
9545 touchEventsTarget: 'container',
9546 ...(swiperParams.virtual ? {} : {
9547 observer: true
9548 }),
9549 onAny: function (name) {
9550 const eventName = swiperParams.eventsPrefix ? `${swiperParams.eventsPrefix}${name.toLowerCase()}` : name.toLowerCase();
9551 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
9552 args[_key - 1] = arguments[_key];
9553 }
9554 const event = new CustomEvent(eventName, {
9555 detail: args,
9556 bubbles: true,
9557 cancelable: true
9558 });
9559 _this.dispatchEvent(event);
9560 }
9561 });
9562 }
9563 connectedCallback() {
9564 if (this.initialized && this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
9565 return;
9566 }
9567 if (this.init === false || this.getAttribute('init') === 'false') {
9568 return;
9569 }
9570 this.initialize();
9571 }
9572 disconnectedCallback() {
9573 if (this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
9574 return;
9575 }
9576 if (this.swiper && this.swiper.destroy) {
9577 this.swiper.destroy();
9578 }
9579 this.initialized = false;
9580 }
9581 updateSwiperOnPropChange(propName, propValue) {
9582 const {
9583 params: swiperParams,
9584 passedParams
9585 } = getParams(this, propName, propValue);
9586 this.passedParams = passedParams;
9587 this.swiperParams = swiperParams;
9588 updateSwiper({
9589 swiper: this.swiper,
9590 passedParams: this.passedParams,
9591 changedParams: [attrToProp(propName)],
9592 ...(propName === 'navigation' && passedParams[propName] ? {
9593 prevEl: '.swiper-button-prev',
9594 nextEl: '.swiper-button-next'
9595 } : {}),
9596 ...(propName === 'pagination' && passedParams[propName] ? {
9597 paginationEl: '.swiper-pagination'
9598 } : {}),
9599 ...(propName === 'scrollbar' && passedParams[propName] ? {
9600 scrollbarEl: '.swiper-scrollbar'
9601 } : {})
9602 });
9603 }
9604 attributeChangedCallback(attr, prevValue, newValue) {
9605 if (!this.initialized) return;
9606 if (prevValue === 'true' && newValue === null) {
9607 newValue = false;
9608 }
9609 this.updateSwiperOnPropChange(attr, newValue);
9610 }
9611 static get observedAttributes() {
9612 const attrs = paramsList.filter(param => param.includes('_')).map(param => param.replace(/[A-Z]/g, v => `-${v}`).replace('_', '').toLowerCase());
9613 return attrs;
9614 }
9615 }
9616 paramsList.forEach(paramName => {
9617 if (paramName === 'init') return;
9618 paramName = paramName.replace('_', '');
9619 Object.defineProperty(SwiperContainer.prototype, paramName, {
9620 configurable: true,
9621 get() {
9622 return (this.passedParams || {})[paramName];
9623 },
9624 set(value) {
9625 if (!this.passedParams) this.passedParams = {};
9626 this.passedParams[paramName] = value;
9627 if (!this.initialized) return;
9628 this.updateSwiperOnPropChange(paramName);
9629 }
9630 });
9631 });
9632 class SwiperSlide extends ClassToExtend {
9633 constructor() {
9634 super();
9635 this.attachShadow({
9636 mode: 'open'
9637 });
9638 }
9639 render() {
9640 const lazy = this.lazy || this.getAttribute('lazy') === '' || this.getAttribute('lazy') === 'true';
9641 addStyle(this.shadowRoot, SwiperSlideCSS);
9642 this.shadowRoot.appendChild(document.createElement('slot'));
9643 if (lazy) {
9644 const lazyDiv = document.createElement('div');
9645 lazyDiv.classList.add('swiper-lazy-preloader');
9646 this.appendChild(lazyDiv);
9647 }
9648 }
9649 initialize() {
9650 this.render();
9651 }
9652 connectedCallback() {
9653 this.initialize();
9654 }
9655 }
9656
9657 // eslint-disable-next-line
9658 const register = () => {
9659 if (typeof window === 'undefined') return;
9660 if (!window.customElements.get('swiper-container')) window.customElements.define('swiper-container', SwiperContainer);
9661 if (!window.customElements.get('swiper-slide')) window.customElements.define('swiper-slide', SwiperSlide);
9662 };
9663 if (typeof window !== 'undefined') {
9664 window.SwiperElementRegisterParams = params => {
9665 paramsList.push(...params);
9666 };
9667 }
9668
9669 register();
9670
9671})();