UNPKG

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