PageSourceSearch

https://waldoswonders-project-id.web.app/build/swiper/swiper.bundle.js

js waldoswonders-project-id.web.app collected 2026-10-03 12:39:48 UTC 204,212 bytes, 6,418 lines download raw bytes

vendor: 3,320 bytes, lines 1-142
1/**
2 * SSR Window 2.0.0
3 * Better handling for window object in SSR environment
4 * https://github.com/nolimits4web/ssr-window
5 *
6 * Copyright 2020, Vladimir Kharlampidi
7 *
8 * Licensed under MIT
9 *
10 * Released on: May 12, 2020
11 */
12/* eslint-disable no-param-reassign */
13function isObject(obj) {
14    return (obj !== null &&
15        typeof obj === 'object' &&
16        'constructor' in obj &&
17        obj.constructor === Object);
18}
19function extend(target, src) {
20    if (target === void 0) { target = {}; }
21    if (src === void 0) { src = {}; }
22    Object.keys(src).forEach(function (key) {
23        if (typeof target[key] === 'undefined')
24            target[key] = src[key];
25        else if (isObject(src[key]) &&
26            isObject(target[key]) &&
27            Object.keys(src[key]).length > 0) {
28            extend(target[key], src[key]);
29        }
30    });
31}
32
33var doc = typeof document !== 'undefined' ? document : {};
34var ssrDocument = {
35    body: {},
36    addEventListener: function () { },
37    removeEventListener: function () { },
38    activeElement: {
39        blur: function () { },
40        nodeName: '',
41    },
42    querySelector: function () {
43        return null;
44    },
45    querySelectorAll: function () {
46        return [];
47    },
48    getElementById: function () {
49        return null;
50    },
51    createEvent: function () {
52        return {
53            initEvent: function () { },
54        };
55    },
56    createElement: function () {
57        return {
58            children: [],
59            childNodes: [],
60            style: {},
61            setAttribute: function () { },
62            getElementsByTagName: function () {
63                return [];
64            },
65        };
66    },
67    createElementNS: function () {
68        return {};
69    },
70    importNode: function () {
71        return null;
72    },
73    location: {
74        hash: '',
75        host: '',
76        hostname: '',
77        href: '',
78        origin: '',
79        pathname: '',
80        protocol: '',
81        search: '',
82    },
83};
84extend(doc, ssrDocument);
85
86var win = typeof window !== 'undefined' ? window : {};
87var ssrWindow = {
88    document: ssrDocument,
89    navigator: {
90        userAgent: '',
91    },
92    location: {
93        hash: '',
94        host: '',
95        hostname: '',
96        href: '',
97        origin: '',
98        pathname: '',
99        protocol: '',
100        search: '',
101    },
102    history: {
103        replaceState: function () { },
104        pushState: function () { },
105        go: function () { },
106        back: function () { },
107    },
108    CustomEvent: function CustomEvent() {
109        return this;
110    },
111    addEventListener: function () { },
112    removeEventListener: function () { },
113    getComputedStyle: function () {
114        return {
115            getPropertyValue: function () {
116                return '';
117            },
118        };
119    },
120    Image: function () { },
121    Date: function () { },
122    screen: {},
123    setTimeout: function () { },
124    clearTimeout: function () { },
125    matchMedia: function () {
126        return {};
127    },
128};
129extend(win, ssrWindow);
130
131/**
132 * Dom7 2.1.5
133 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
134 * http://framework7.io/docs/dom.html
135 *
136 * Copyright 2020, Vladimir Kharlampidi
137 * The iDangero.us
138 * http://www.idangero.us/
139 *
140 * Licensed under MIT
141 *
142 * Released on: May 15, 2020
vendor: 19,585 bytes, lines 142-833
142
143 */
144
145class Dom7 {
146  constructor(arr) {
147    const self = this;
148    // Create array-like object
149    for (let i = 0; i < arr.length; i += 1) {
150      self[i] = arr[i];
151    }
152    self.length = arr.length;
153    // Return collection with methods
154    return this;
155  }
156}
157
158function $(selector, context) {
159  const arr = [];
160  let i = 0;
161  if (selector && !context) {
162    if (selector instanceof Dom7) {
163      return selector;
164    }
165  }
166  if (selector) {
167      // String
168    if (typeof selector === 'string') {
169      let els;
170      let tempParent;
171      const html = selector.trim();
172      if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
173        let toCreate = 'div';
174        if (html.indexOf('<li') === 0) toCreate = 'ul';
175        if (html.indexOf('<tr') === 0) toCreate = 'tbody';
176        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
177        if (html.indexOf('<tbody') === 0) toCreate = 'table';
178        if (html.indexOf('<option') === 0) toCreate = 'select';
179        tempParent = doc.createElement(toCreate);
180        tempParent.innerHTML = html;
181        for (i = 0; i < tempParent.childNodes.length; i += 1) {
182          arr.push(tempParent.childNodes[i]);
183        }
184      } else {
185        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
186          // Pure ID selector
187          els = [doc.getElementById(selector.trim().split('#')[1])];
188        } else {
189          // Other selectors
190          els = (context || doc).querySelectorAll(selector.trim());
191        }
192        for (i = 0; i < els.length; i += 1) {
193          if (els[i]) arr.push(els[i]);
194        }
195      }
196    } else if (selector.nodeType || selector === win || selector === doc) {
197      // Node/element
198      arr.push(selector);
199    } else if (selector.length > 0 && selector[0].nodeType) {
200      // Array of elements or instance of Dom
201      for (i = 0; i < selector.length; i += 1) {
202        arr.push(selector[i]);
203      }
204    }
205  }
206  return new Dom7(arr);
207}
208
209$.fn = Dom7.prototype;
210$.Class = Dom7;
211$.Dom7 = Dom7;
212
213function unique(arr) {
214  const uniqueArray = [];
215  for (let i = 0; i < arr.length; i += 1) {
216    if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]);
217  }
218  return uniqueArray;
219}
220
221// Classes and attributes
222function addClass(className) {
223  if (typeof className === 'undefined') {
224    return this;
225  }
226  const classes = className.split(' ');
227  for (let i = 0; i < classes.length; i += 1) {
228    for (let j = 0; j < this.length; j += 1) {
229      if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') this[j].classList.add(classes[i]);
230    }
231  }
232  return this;
233}
234function removeClass(className) {
235  const classes = className.split(' ');
236  for (let i = 0; i < classes.length; i += 1) {
237    for (let j = 0; j < this.length; j += 1) {
238      if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') this[j].classList.remove(classes[i]);
239    }
240  }
241  return this;
242}
243function hasClass(className) {
244  if (!this[0]) return false;
245  return this[0].classList.contains(className);
246}
247function toggleClass(className) {
248  const classes = className.split(' ');
249  for (let i = 0; i < classes.length; i += 1) {
250    for (let j = 0; j < this.length; j += 1) {
251      if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') this[j].classList.toggle(classes[i]);
252    }
253  }
254  return this;
255}
256function attr(attrs, value) {
257  if (arguments.length === 1 && typeof attrs === 'string') {
258    // Get attr
259    if (this[0]) return this[0].getAttribute(attrs);
260    return undefined;
261  }
262
263  // Set attrs
264  for (let i = 0; i < this.length; i += 1) {
265    if (arguments.length === 2) {
266      // String
267      this[i].setAttribute(attrs, value);
268    } else {
269      // Object
270      // eslint-disable-next-line
271      for (const attrName in attrs) {
272        this[i][attrName] = attrs[attrName];
273        this[i].setAttribute(attrName, attrs[attrName]);
274      }
275    }
276  }
277  return this;
278}
279// eslint-disable-next-line
280function removeAttr(attr) {
281  for (let i = 0; i < this.length; i += 1) {
282    this[i].removeAttribute(attr);
283  }
284  return this;
285}
286function data(key, value) {
287  let el;
288  if (typeof value === 'undefined') {
289    el = this[0];
290    // Get value
291    if (el) {
292      if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) {
293        return el.dom7ElementDataStorage[key];
294      }
295
296      const dataKey = el.getAttribute(`data-${key}`);
297      if (dataKey) {
298        return dataKey;
299      }
300      return undefined;
301    }
302    return undefined;
303  }
304
305  // Set value
306  for (let i = 0; i < this.length; i += 1) {
307    el = this[i];
308    if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
309    el.dom7ElementDataStorage[key] = value;
310  }
311  return this;
312}
313// Transforms
314// eslint-disable-next-line
315function transform(transform) {
316  for (let i = 0; i < this.length; i += 1) {
317    const elStyle = this[i].style;
318    elStyle.webkitTransform = transform;
319    elStyle.transform = transform;
320  }
321  return this;
322}
323function transition(duration) {
324  if (typeof duration !== 'string') {
325    duration = `${duration}ms`; // eslint-disable-line
326  }
327  for (let i = 0; i < this.length; i += 1) {
328    const elStyle = this[i].style;
329    elStyle.webkitTransitionDuration = duration;
330    elStyle.transitionDuration = duration;
331  }
332  return this;
333}
334// Events
335function on(...args) {
336  let [eventType, targetSelector, listener, capture] = args;
337  if (typeof args[1] === 'function') {
338    [eventType, listener, capture] = args;
339    targetSelector = undefined;
340  }
341  if (!capture) capture = false;
342
343  function handleLiveEvent(e) {
344    const target = e.target;
345    if (!target) return;
346    const eventData = e.target.dom7EventData || [];
347    if (eventData.indexOf(e) < 0) {
348      eventData.unshift(e);
349    }
350    if ($(target).is(targetSelector)) listener.apply(target, eventData);
351    else {
352      const parents = $(target).parents(); // eslint-disable-line
353      for (let k = 0; k < parents.length; k += 1) {
354        if ($(parents[k]).is(targetSelector)) listener.apply(parents[k], eventData);
355      }
356    }
357  }
358  function handleEvent(e) {
359    const eventData = e && e.target ? e.target.dom7EventData || [] : [];
360    if (eventData.indexOf(e) < 0) {
361      eventData.unshift(e);
362    }
363    listener.apply(this, eventData);
364  }
365  const events = eventType.split(' ');
366  let j;
367  for (let i = 0; i < this.length; i += 1) {
368    const el = this[i];
369    if (!targetSelector) {
370      for (j = 0; j < events.length; j += 1) {
371        const event = events[j];
372        if (!el.dom7Listeners) el.dom7Listeners = {};
373        if (!el.dom7Listeners[event]) el.dom7Listeners[event] = [];
374        el.dom7Listeners[event].push({
375          listener,
376          proxyListener: handleEvent,
377        });
378        el.addEventListener(event, handleEvent, capture);
379      }
380    } else {
381      // Live events
382      for (j = 0; j < events.length; j += 1) {
383        const event = events[j];
384        if (!el.dom7LiveListeners) el.dom7LiveListeners = {};
385        if (!el.dom7LiveListeners[event]) el.dom7LiveListeners[event] = [];
386        el.dom7LiveListeners[event].push({
387          listener,
388          proxyListener: handleLiveEvent,
389        });
390        el.addEventListener(event, handleLiveEvent, capture);
391      }
392    }
393  }
394  return this;
395}
396function off(...args) {
397  let [eventType, targetSelector, listener, capture] = args;
398  if (typeof args[1] === 'function') {
399    [eventType, listener, capture] = args;
400    targetSelector = undefined;
401  }
402  if (!capture) capture = false;
403
404  const events = eventType.split(' ');
405  for (let i = 0; i < events.length; i += 1) {
406    const event = events[i];
407    for (let j = 0; j < this.length; j += 1) {
408      const el = this[j];
409      let handlers;
410      if (!targetSelector && el.dom7Listeners) {
411        handlers = el.dom7Listeners[event];
412      } else if (targetSelector && el.dom7LiveListeners) {
413        handlers = el.dom7LiveListeners[event];
414      }
415      if (handlers && handlers.length) {
416        for (let k = handlers.length - 1; k >= 0; k -= 1) {
417          const handler = handlers[k];
418          if (listener && handler.listener === listener) {
419            el.removeEventListener(event, handler.proxyListener, capture);
420            handlers.splice(k, 1);
421          } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {
422            el.removeEventListener(event, handler.proxyListener, capture);
423            handlers.splice(k, 1);
424          } else if (!listener) {
425            el.removeEventListener(event, handler.proxyListener, capture);
426            handlers.splice(k, 1);
427          }
428        }
429      }
430    }
431  }
432  return this;
433}
434function trigger(...args) {
435  const events = args[0].split(' ');
436  const eventData = args[1];
437  for (let i = 0; i < events.length; i += 1) {
438    const event = events[i];
439    for (let j = 0; j < this.length; j += 1) {
440      const el = this[j];
441      let evt;
442      try {
443        evt = new win.CustomEvent(event, {
444          detail: eventData,
445          bubbles: true,
446          cancelable: true,
447        });
448      } catch (e) {
449        evt = doc.createEvent('Event');
450        evt.initEvent(event, true, true);
451        evt.detail = eventData;
452      }
453      // eslint-disable-next-line
454      el.dom7EventData = args.filter((data, dataIndex) => dataIndex > 0);
455      el.dispatchEvent(evt);
456      el.dom7EventData = [];
457      delete el.dom7EventData;
458    }
459  }
460  return this;
461}
462function transitionEnd(callback) {
463  const events = ['webkitTransitionEnd', 'transitionend'];
464  const dom = this;
465  let i;
466  function fireCallBack(e) {
467    /* jshint validthis:true */
468    if (e.target !== this) return;
469    callback.call(this, e);
470    for (i = 0; i < events.length; i += 1) {
471      dom.off(events[i], fireCallBack);
472    }
473  }
474  if (callback) {
475    for (i = 0; i < events.length; i += 1) {
476      dom.on(events[i], fireCallBack);
477    }
478  }
479  return this;
480}
481function outerWidth(includeMargins) {
482  if (this.length > 0) {
483    if (includeMargins) {
484      // eslint-disable-next-line
485      const styles = this.styles();
486      return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));
487    }
488    return this[0].offsetWidth;
489  }
490  return null;
491}
492function outerHeight(includeMargins) {
493  if (this.length > 0) {
494    if (includeMargins) {
495      // eslint-disable-next-line
496      const styles = this.styles();
497      return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));
498    }
499    return this[0].offsetHeight;
500  }
501  return null;
502}
503function offset() {
504  if (this.length > 0) {
505    const el = this[0];
506    const box = el.getBoundingClientRect();
507    const body = doc.body;
508    const clientTop = el.clientTop || body.clientTop || 0;
509    const clientLeft = el.clientLeft || body.clientLeft || 0;
510    const scrollTop = el === win ? win.scrollY : el.scrollTop;
511    const scrollLeft = el === win ? win.scrollX : el.scrollLeft;
512    return {
513      top: (box.top + scrollTop) - clientTop,
514      left: (box.left + scrollLeft) - clientLeft,
515    };
516  }
517
518  return null;
519}
520function styles() {
521  if (this[0]) return win.getComputedStyle(this[0], null);
522  return {};
523}
524function css(props, value) {
525  let i;
526  if (arguments.length === 1) {
527    if (typeof props === 'string') {
528      if (this[0]) return win.getComputedStyle(this[0], null).getPropertyValue(props);
529    } else {
530      for (i = 0; i < this.length; i += 1) {
531        // eslint-disable-next-line
532        for (let prop in props) {
533          this[i].style[prop] = props[prop];
534        }
535      }
536      return this;
537    }
538  }
539  if (arguments.length === 2 && typeof props === 'string') {
540    for (i = 0; i < this.length; i += 1) {
541      this[i].style[props] = value;
542    }
543    return this;
544  }
545  return this;
546}
547// Iterate over the collection passing elements to `callback`
548function each(callback) {
549  // Don't bother continuing without a callback
550  if (!callback) return this;
551  // Iterate over the current collection
552  for (let i = 0; i < this.length; i += 1) {
553    // If the callback returns false
554    if (callback.call(this[i], i, this[i]) === false) {
555      // End the loop early
556      return this;
557    }
558  }
559  // Return `this` to allow chained DOM operations
560  return this;
561}
562function filter(callback) {
563  const matchedItems = [];
564  const dom = this;
565  for (let i = 0; i < dom.length; i += 1) {
566    if (callback.call(dom[i], i, dom[i])) matchedItems.push(dom[i]);
567  }
568  return new Dom7(matchedItems);
569}
570// eslint-disable-next-line
571function html(html) {
572  if (typeof html === 'undefined') {
573    return this[0] ? this[0].innerHTML : undefined;
574  }
575
576  for (let i = 0; i < this.length; i += 1) {
577    this[i].innerHTML = html;
578  }
579  return this;
580}
581// eslint-disable-next-line
582function text(text) {
583  if (typeof text === 'undefined') {
584    if (this[0]) {
585      return this[0].textContent.trim();
586    }
587    return null;
588  }
589
590  for (let i = 0; i < this.length; i += 1) {
591    this[i].textContent = text;
592  }
593  return this;
594}
595function is(selector) {
596  const el = this[0];
597  let compareWith;
598  let i;
599  if (!el || typeof selector === 'undefined') return false;
600  if (typeof selector === 'string') {
601    if (el.matches) return el.matches(selector);
602    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
603    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);
604
605    compareWith = $(selector);
606    for (i = 0; i < compareWith.length; i += 1) {
607      if (compareWith[i] === el) return true;
608    }
609    return false;
610  } else if (selector === doc) return el === doc;
611  else if (selector === win) return el === win;
612
613  if (selector.nodeType || selector instanceof Dom7) {
614    compareWith = selector.nodeType ? [selector] : selector;
615    for (i = 0; i < compareWith.length; i += 1) {
616      if (compareWith[i] === el) return true;
617    }
618    return false;
619  }
620  return false;
621}
622function index() {
623  let child = this[0];
624  let i;
625  if (child) {
626    i = 0;
627    // eslint-disable-next-line
628    while ((child = child.previousSibling) !== null) {
629      if (child.nodeType === 1) i += 1;
630    }
631    return i;
632  }
633  return undefined;
634}
635// eslint-disable-next-line
636function eq(index) {
637  if (typeof index === 'undefined') return this;
638  const length = this.length;
639  let returnIndex;
640  if (index > length - 1) {
641    return new Dom7([]);
642  }
643  if (index < 0) {
644    returnIndex = length + index;
645    if (returnIndex < 0) return new Dom7([]);
646    return new Dom7([this[returnIndex]]);
647  }
648  return new Dom7([this[index]]);
649}
650function append(...args) {
651  let newChild;
652
653  for (let k = 0; k < args.length; k += 1) {
654    newChild = args[k];
655    for (let i = 0; i < this.length; i += 1) {
656      if (typeof newChild === 'string') {
657        const tempDiv = doc.createElement('div');
658        tempDiv.innerHTML = newChild;
659        while (tempDiv.firstChild) {
660          this[i].appendChild(tempDiv.firstChild);
661        }
662      } else if (newChild instanceof Dom7) {
663        for (let j = 0; j < newChild.length; j += 1) {
664          this[i].appendChild(newChild[j]);
665        }
666      } else {
667        this[i].appendChild(newChild);
668      }
669    }
670  }
671
672  return this;
673}
674function prepend(newChild) {
675  let i;
676  let j;
677  for (i = 0; i < this.length; i += 1) {
678    if (typeof newChild === 'string') {
679      const tempDiv = doc.createElement('div');
680      tempDiv.innerHTML = newChild;
681      for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
682        this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
683      }
684    } else if (newChild instanceof Dom7) {
685      for (j = 0; j < newChild.length; j += 1) {
686        this[i].insertBefore(newChild[j], this[i].childNodes[0]);
687      }
688    } else {
689      this[i].insertBefore(newChild, this[i].childNodes[0]);
690    }
691  }
692  return this;
693}
694function next(selector) {
695  if (this.length > 0) {
696    if (selector) {
697      if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
698        return new Dom7([this[0].nextElementSibling]);
699      }
700      return new Dom7([]);
701    }
702
703    if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);
704    return new Dom7([]);
705  }
706  return new Dom7([]);
707}
708function nextAll(selector) {
709  const nextEls = [];
710  let el = this[0];
711  if (!el) return new Dom7([]);
712  while (el.nextElementSibling) {
713    const next = el.nextElementSibling; // eslint-disable-line
714    if (selector) {
715      if ($(next).is(selector)) nextEls.push(next);
716    } else nextEls.push(next);
717    el = next;
718  }
719  return new Dom7(nextEls);
720}
721function prev(selector) {
722  if (this.length > 0) {
723    const el = this[0];
724    if (selector) {
725      if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
726        return new Dom7([el.previousElementSibling]);
727      }
728      return new Dom7([]);
729    }
730
731    if (el.previousElementSibling) return new Dom7([el.previousElementSibling]);
732    return new Dom7([]);
733  }
734  return new Dom7([]);
735}
736function prevAll(selector) {
737  const prevEls = [];
738  let el = this[0];
739  if (!el) return new Dom7([]);
740  while (el.previousElementSibling) {
741    const prev = el.previousElementSibling; // eslint-disable-line
742    if (selector) {
743      if ($(prev).is(selector)) prevEls.push(prev);
744    } else prevEls.push(prev);
745    el = prev;
746  }
747  return new Dom7(prevEls);
748}
749function parent(selector) {
750  const parents = []; // eslint-disable-line
751  for (let i = 0; i < this.length; i += 1) {
752    if (this[i].parentNode !== null) {
753      if (selector) {
754        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
755      } else {
756        parents.push(this[i].parentNode);
757      }
758    }
759  }
760  return $(unique(parents));
761}
762function parents(selector) {
763  const parents = []; // eslint-disable-line
764  for (let i = 0; i < this.length; i += 1) {
765    let parent = this[i].parentNode; // eslint-disable-line
766    while (parent) {
767      if (selector) {
768        if ($(parent).is(selector)) parents.push(parent);
769      } else {
770        parents.push(parent);
771      }
772      parent = parent.parentNode;
773    }
774  }
775  return $(unique(parents));
776}
777function closest(selector) {
778  let closest = this; // eslint-disable-line
779  if (typeof selector === 'undefined') {
780    return new Dom7([]);
781  }
782  if (!closest.is(selector)) {
783    closest = closest.parents(selector).eq(0);
784  }
785  return closest;
786}
787function find(selector) {
788  const foundElements = [];
789  for (let i = 0; i < this.length; i += 1) {
790    const found = this[i].querySelectorAll(selector);
791    for (let j = 0; j < found.length; j += 1) {
792      foundElements.push(found[j]);
793    }
794  }
795  return new Dom7(foundElements);
796}
797function children(selector) {
798  const children = []; // eslint-disable-line
799  for (let i = 0; i < this.length; i += 1) {
800    const childNodes = this[i].childNodes;
801
802    for (let j = 0; j < childNodes.length; j += 1) {
803      if (!selector) {
804        if (childNodes[j].nodeType === 1) children.push(childNodes[j]);
805      } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) {
806        children.push(childNodes[j]);
807      }
808    }
809  }
810  return new Dom7(unique(children));
811}
812function remove() {
813  for (let i = 0; i < this.length; i += 1) {
814    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
815  }
816  return this;
817}
818function add(...args) {
819  const dom = this;
820  let i;
821  let j;
822  for (i = 0; i < args.length; i += 1) {
823    const toAdd = $(args[i]);
824    for (j = 0; j < toAdd.length; j += 1) {
825      dom[dom.length] = toAdd[j];
826      dom.length += 1;
827    }
828  }
829  return dom;
830}
831
832/**
833 * Swiper 5.
vendor: 3,774 bytes, lines 833-975
8334.1
834 * Most modern mobile touch slider and framework with hardware accelerated transitions
835 * http://swiperjs.com
836 *
837 * Copyright 2014-2020 Vladimir Kharlampidi
838 *
839 * Released under the MIT License
840 *
841 * Released on: May 20, 2020
842 */
843
844const Methods = {
845  addClass,
846  removeClass,
847  hasClass,
848  toggleClass,
849  attr,
850  removeAttr,
851  data,
852  transform,
853  transition: transition,
854  on,
855  off,
856  trigger,
857  transitionEnd: transitionEnd,
858  outerWidth,
859  outerHeight,
860  offset,
861  css,
862  each,
863  html,
864  text,
865  is,
866  index,
867  eq,
868  append,
869  prepend,
870  next,
871  nextAll,
872  prev,
873  prevAll,
874  parent,
875  parents,
876  closest,
877  find,
878  children,
879  filter,
880  remove,
881  add,
882  styles,
883};
884
885Object.keys(Methods).forEach((methodName) => {
886  $.fn[methodName] = $.fn[methodName] || Methods[methodName];
887});
888
889const Utils = {
890  deleteProps(obj) {
891    const object = obj;
892    Object.keys(object).forEach((key) => {
893      try {
894        object[key] = null;
895      } catch (e) {
896        // no getter for object
897      }
898      try {
899        delete object[key];
900      } catch (e) {
901        // something got wrong
902      }
903    });
904  },
905  nextTick(callback, delay = 0) {
906    return setTimeout(callback, delay);
907  },
908  now() {
909    return Date.now();
910  },
911  getTranslate(el, axis = 'x') {
912    let matrix;
913    let curTransform;
914    let transformMatrix;
915
916    const curStyle = win.getComputedStyle(el, null);
917
918    if (win.WebKitCSSMatrix) {
919      curTransform = curStyle.transform || curStyle.webkitTransform;
920      if (curTransform.split(',').length > 6) {
921        curTransform = curTransform.split(', ').map((a) => a.replace(',', '.')).join(', ');
922      }
923      // Some old versions of Webkit choke when 'none' is passed; pass
924      // empty string instead in this case
925      transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
926    } else {
927      transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
928      matrix = transformMatrix.toString().split(',');
929    }
930
931    if (axis === 'x') {
932      // Latest Chrome and webkits Fix
933      if (win.WebKitCSSMatrix) curTransform = transformMatrix.m41;
934      // Crazy IE10 Matrix
935      else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
936      // Normal Browsers
937      else curTransform = parseFloat(matrix[4]);
938    }
939    if (axis === 'y') {
940      // Latest Chrome and webkits Fix
941      if (win.WebKitCSSMatrix) curTransform = transformMatrix.m42;
942      // Crazy IE10 Matrix
943      else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
944      // Normal Browsers
945      else curTransform = parseFloat(matrix[5]);
946    }
947    return curTransform || 0;
948  },
949  parseUrlQuery(url) {
950    const query = {};
951    let urlToParse = url || win.location.href;
952    let i;
953    let params;
954    let param;
955    let length;
956    if (typeof urlToParse === 'string' && urlToParse.length) {
957      urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : '';
958      params = urlToParse.split('&').filter((paramsPart) => paramsPart !== '');
959      length = params.length;
960
961      for (i = 0; i < length; i += 1) {
962        param = params[i].replace(/#\S+/g, '').split('=');
963        query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param[1]) || '';
964      }
965    }
966    return query;
967  },
968  isObject(o) {
969    return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;
970  },
971  extend(...args) {
972    const to = Object(args[0]);
973    for (let i = 1; i < args.length; i += 1) {
974      const nextSource = args[i];
975      if (nextSource !== undefined && nextSource !== null) {
976        const keysArray = Object.keys(Object(nextSource));
977        for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
978          const nextKey = keysArray[nextIndex];
979          const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
980          if (desc !== undefined && desc.enumerable) {
981            if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
982              Utils.extend(to[nextKey], nextSource[nextKey]);
983            } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
984              to[nextKey] = {};
985              Utils.extend(to[nextKey], nextSource[nextKey]);
986            } else {
987              to[nextKey] = nextSource[nextKey];
988            }
989          }
990        }
991      }
992    }
993    return to;
994  },
995};
996
997const Support = (function Support() {
998  return {
999    touch: !!(('ontouchstart' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch)),
1000
1001    pointerEvents: !!win.PointerEvent && ('maxTouchPoints' in win.navigator) && win.navigator.maxTouchPoints >=
vendor: 14,472 bytes, lines 1001-1423
1001 0,
1002
1003    observer: (function checkObserver() {
1004      return ('MutationObserver' in win || 'WebkitMutationObserver' in win);
1005    }()),
1006
1007    passiveListener: (function checkPassiveListener() {
1008      let supportsPassive = false;
1009      try {
1010        const opts = Object.defineProperty({}, 'passive', {
1011          // eslint-disable-next-line
1012          get() {
1013            supportsPassive = true;
1014          },
1015        });
1016        win.addEventListener('testPassiveListener', null, opts);
1017      } catch (e) {
1018        // No support
1019      }
1020      return supportsPassive;
1021    }()),
1022
1023    gestures: (function checkGestures() {
1024      return 'ongesturestart' in win;
1025    }()),
1026  };
1027}());
1028
1029class SwiperClass {
1030  constructor(params = {}) {
1031    const self = this;
1032    self.params = params;
1033
1034    // Events
1035    self.eventsListeners = {};
1036
1037    if (self.params && self.params.on) {
1038      Object.keys(self.params.on).forEach((eventName) => {
1039        self.on(eventName, self.params.on[eventName]);
1040      });
1041    }
1042  }
1043
1044  on(events, handler, priority) {
1045    const self = this;
1046    if (typeof handler !== 'function') return self;
1047    const method = priority ? 'unshift' : 'push';
1048    events.split(' ').forEach((event) => {
1049      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
1050      self.eventsListeners[event][method](handler);
1051    });
1052    return self;
1053  }
1054
1055  once(events, handler, priority) {
1056    const self = this;
1057    if (typeof handler !== 'function') return self;
1058    function onceHandler(...args) {
1059      self.off(events, onceHandler);
1060      if (onceHandler.f7proxy) {
1061        delete onceHandler.f7proxy;
1062      }
1063      handler.apply(self, args);
1064    }
1065    onceHandler.f7proxy = handler;
1066    return self.on(events, onceHandler, priority);
1067  }
1068
1069  off(events, handler) {
1070    const self = this;
1071    if (!self.eventsListeners) return self;
1072    events.split(' ').forEach((event) => {
1073      if (typeof handler === 'undefined') {
1074        self.eventsListeners[event] = [];
1075      } else if (self.eventsListeners[event] && self.eventsListeners[event].length) {
1076        self.eventsListeners[event].forEach((eventHandler, index) => {
1077          if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) {
1078            self.eventsListeners[event].splice(index, 1);
1079          }
1080        });
1081      }
1082    });
1083    return self;
1084  }
1085
1086  emit(...args) {
1087    const self = this;
1088    if (!self.eventsListeners) return self;
1089    let events;
1090    let data;
1091    let context;
1092    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
1093      events = args[0];
1094      data = args.slice(1, args.length);
1095      context = self;
1096    } else {
1097      events = args[0].events;
1098      data = args[0].data;
1099      context = args[0].context || self;
1100    }
1101    const eventsArray = Array.isArray(events) ? events : events.split(' ');
1102    eventsArray.forEach((event) => {
1103      if (self.eventsListeners && self.eventsListeners[event]) {
1104        const handlers = [];
1105        self.eventsListeners[event].forEach((eventHandler) => {
1106          handlers.push(eventHandler);
1107        });
1108        handlers.forEach((eventHandler) => {
1109          eventHandler.apply(context, data);
1110        });
1111      }
1112    });
1113    return self;
1114  }
1115
1116  useModulesParams(instanceParams) {
1117    const instance = this;
1118    if (!instance.modules) return;
1119    Object.keys(instance.modules).forEach((moduleName) => {
1120      const module = instance.modules[moduleName];
1121      // Extend params
1122      if (module.params) {
1123        Utils.extend(instanceParams, module.params);
1124      }
1125    });
1126  }
1127
1128  useModules(modulesParams = {}) {
1129    const instance = this;
1130    if (!instance.modules) return;
1131    Object.keys(instance.modules).forEach((moduleName) => {
1132      const module = instance.modules[moduleName];
1133      const moduleParams = modulesParams[moduleName] || {};
1134      // Extend instance methods and props
1135      if (module.instance) {
1136        Object.keys(module.instance).forEach((modulePropName) => {
1137          const moduleProp = module.instance[modulePropName];
1138          if (typeof moduleProp === 'function') {
1139            instance[modulePropName] = moduleProp.bind(instance);
1140          } else {
1141            instance[modulePropName] = moduleProp;
1142          }
1143        });
1144      }
1145      // Add event listeners
1146      if (module.on && instance.on) {
1147        Object.keys(module.on).forEach((moduleEventName) => {
1148          instance.on(moduleEventName, module.on[moduleEventName]);
1149        });
1150      }
1151
1152      // Module create callback
1153      if (module.create) {
1154        module.create.bind(instance)(moduleParams);
1155      }
1156    });
1157  }
1158
1159  static set components(components) {
1160    const Class = this;
1161    if (!Class.use) return;
1162    Class.use(components);
1163  }
1164
1165  static installModule(module, ...params) {
1166    const Class = this;
1167    if (!Class.prototype.modules) Class.prototype.modules = {};
1168    const name = module.name || (`${Object.keys(Class.prototype.modules).length}_${Utils.now()}`);
1169    Class.prototype.modules[name] = module;
1170    // Prototype
1171    if (module.proto) {
1172      Object.keys(module.proto).forEach((key) => {
1173        Class.prototype[key] = module.proto[key];
1174      });
1175    }
1176    // Class
1177    if (module.static) {
1178      Object.keys(module.static).forEach((key) => {
1179        Class[key] = module.static[key];
1180      });
1181    }
1182    // Callback
1183    if (module.install) {
1184      module.install.apply(Class, params);
1185    }
1186    return Class;
1187  }
1188
1189  static use(module, ...params) {
1190    const Class = this;
1191    if (Array.isArray(module)) {
1192      module.forEach((m) => Class.installModule(m));
1193      return Class;
1194    }
1195    return Class.installModule(module, ...params);
1196  }
1197}
1198
1199function updateSize () {
1200  const swiper = this;
1201  let width;
1202  let height;
1203  const $el = swiper.$el;
1204  if (typeof swiper.params.width !== 'undefined') {
1205    width = swiper.params.width;
1206  } else {
1207    width = $el[0].clientWidth;
1208  }
1209  if (typeof swiper.params.height !== 'undefined') {
1210    height = swiper.params.height;
1211  } else {
1212    height = $el[0].clientHeight;
1213  }
1214  if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) {
1215    return;
1216  }
1217
1218  // Subtract paddings
1219  width = width - parseInt($el.css('padding-left'), 10) - parseInt($el.css('padding-right'), 10);
1220  height = height - parseInt($el.css('padding-top'), 10) - parseInt($el.css('padding-bottom'), 10);
1221
1222  Utils.extend(swiper, {
1223    width,
1224    height,
1225    size: swiper.isHorizontal() ? width : height,
1226  });
1227}
1228
1229function updateSlides () {
1230  const swiper = this;
1231  const params = swiper.params;
1232
1233  const {
1234    $wrapperEl, size: swiperSize, rtlTranslate: rtl, wrongRTL,
1235  } = swiper;
1236  const isVirtual = swiper.virtual && params.virtual.enabled;
1237  const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
1238  const slides = $wrapperEl.children(`.${swiper.params.slideClass}`);
1239  const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
1240  let snapGrid = [];
1241  const slidesGrid = [];
1242  const slidesSizesGrid = [];
1243
1244  function slidesForMargin(slideIndex) {
1245    if (!params.cssMode) return true;
1246    if (slideIndex === slides.length - 1) {
1247      return false;
1248    }
1249    return true;
1250  }
1251
1252  let offsetBefore = params.slidesOffsetBefore;
1253  if (typeof offsetBefore === 'function') {
1254    offsetBefore = params.slidesOffsetBefore.call(swiper);
1255  }
1256
1257  let offsetAfter = params.slidesOffsetAfter;
1258  if (typeof offsetAfter === 'function') {
1259    offsetAfter = params.slidesOffsetAfter.call(swiper);
1260  }
1261
1262  const previousSnapGridLength = swiper.snapGrid.length;
1263  const previousSlidesGridLength = swiper.snapGrid.length;
1264
1265  let spaceBetween = params.spaceBetween;
1266  let slidePosition = -offsetBefore;
1267  let prevSlideSize = 0;
1268  let index = 0;
1269  if (typeof swiperSize === 'undefined') {
1270    return;
1271  }
1272  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
1273    spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize;
1274  }
1275
1276  swiper.virtualSize = -spaceBetween;
1277
1278  // reset margins
1279  if (rtl) slides.css({ marginLeft: '', marginTop: '' });
1280  else slides.css({ marginRight: '', marginBottom: '' });
1281
1282  let slidesNumberEvenToRows;
1283  if (params.slidesPerColumn > 1) {
1284    if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) {
1285      slidesNumberEvenToRows = slidesLength;
1286    } else {
1287      slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn;
1288    }
1289    if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') {
1290      slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn);
1291    }
1292  }
1293
1294  // Calc slides
1295  let slideSize;
1296  const slidesPerColumn = params.slidesPerColumn;
1297  const slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
1298  const numFullColumns = Math.floor(slidesLength / params.slidesPerColumn);
1299  for (let i = 0; i < slidesLength; i += 1) {
1300    slideSize = 0;
1301    const slide = slides.eq(i);
1302    if (params.slidesPerColumn > 1) {
1303      // Set slides order
1304      let newSlideOrderIndex;
1305      let column;
1306      let row;
1307      if (params.slidesPerColumnFill === 'row' && params.slidesPerGroup > 1) {
1308        const groupIndex = Math.floor(i / (params.slidesPerGroup * params.slidesPerColumn));
1309        const slideIndexInGroup = i - params.slidesPerColumn * params.slidesPerGroup * groupIndex;
1310        const columnsInGroup = groupIndex === 0
1311          ? params.slidesPerGroup
1312          : Math.min(Math.ceil((slidesLength - groupIndex * slidesPerColumn * params.slidesPerGroup) / slidesPerColumn), params.slidesPerGroup);
1313        row = Math.floor(slideIndexInGroup / columnsInGroup);
1314        column = (slideIndexInGroup - row * columnsInGroup) + groupIndex * params.slidesPerGroup;
1315
1316        newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn);
1317        slide
1318          .css({
1319            '-webkit-box-ordinal-group': newSlideOrderIndex,
1320            '-moz-box-ordinal-group': newSlideOrderIndex,
1321            '-ms-flex-order': newSlideOrderIndex,
1322            '-webkit-order': newSlideOrderIndex,
1323            order: newSlideOrderIndex,
1324          });
1325      } else if (params.slidesPerColumnFill === 'column') {
1326        column = Math.floor(i / slidesPerColumn);
1327        row = i - (column * slidesPerColumn);
1328        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) {
1329          row += 1;
1330          if (row >= slidesPerColumn) {
1331            row = 0;
1332            column += 1;
1333          }
1334        }
1335      } else {
1336        row = Math.floor(i / slidesPerRow);
1337        column = i - (row * slidesPerRow);
1338      }
1339      slide.css(
1340        `margin-${swiper.isHorizontal() ? 'top' : 'left'}`,
1341        (row !== 0 && params.spaceBetween) && (`${params.spaceBetween}px`)
1342      );
1343    }
1344    if (slide.css('display') === 'none') continue; // eslint-disable-line
1345
1346    if (params.slidesPerView === 'auto') {
1347      const slideStyles = win.getComputedStyle(slide[0], null);
1348      const currentTransform = slide[0].style.transform;
1349      const currentWebKitTransform = slide[0].style.webkitTransform;
1350      if (currentTransform) {
1351        slide[0].style.transform = 'none';
1352      }
1353      if (currentWebKitTransform) {
1354        slide[0].style.webkitTransform = 'none';
1355      }
1356      if (params.roundLengths) {
1357        slideSize = swiper.isHorizontal()
1358          ? slide.outerWidth(true)
1359          : slide.outerHeight(true);
1360      } else {
1361        // eslint-disable-next-line
1362        if (swiper.isHorizontal()) {
1363          const width = parseFloat(slideStyles.getPropertyValue('width'));
1364          const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left'));
1365          const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right'));
1366          const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left'));
1367          const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right'));
1368          const boxSizing = slideStyles.getPropertyValue('box-sizing');
1369          if (boxSizing && boxSizing === 'border-box') {
1370            slideSize = width + marginLeft + marginRight;
1371          } else {
1372            slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight;
1373          }
1374        } else {
1375          const height = parseFloat(slideStyles.getPropertyValue('height'));
1376          const paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top'));
1377          const paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom'));
1378          const marginTop = parseFloat(slideStyles.getPropertyValue('margin-top'));
1379          const marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom'));
1380          const boxSizing = slideStyles.getPropertyValue('box-sizing');
1381          if (boxSizing && boxSizing === 'border-box') {
1382            slideSize = height + marginTop + marginBottom;
1383          } else {
1384            slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom;
1385          }
1386        }
1387      }
1388      if (currentTransform) {
1389        slide[0].style.transform = currentTransform;
1390      }
1391      if (currentWebKitTransform) {
1392        slide[0].style.webkitTransform = currentWebKitTransform;
1393      }
1394      if (params.roundLengths) slideSize = Math.floor(slideSize);
1395    } else {
1396      slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView;
1397      if (params.roundLengths) slideSize = Math.floor(slideSize);
1398
1399      if (slides[i]) {
1400        if (swiper.isHorizontal()) {
1401          slides[i].style.width = `${slideSize}px`;
1402        } else {
1403          slides[i].style.height = `${slideSize}px`;
1404        }
1405      }
1406    }
1407    if (slides[i]) {
1408      slides[i].swiperSlideSize = slideSize;
1409    }
1410    slidesSizesGrid.push(slideSize);
1411
1412
1413    if (params.centeredSlides) {
1414      slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween;
1415      if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween;
1416      if (i === 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween;
1417      if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
1418      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
1419      if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
1420      slidesGrid.push(slidePosition);
1421    } else {
1422      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
1423      if ((index
vendor: 8,307 bytes, lines 1423-1661
1423 - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
1424      slidesGrid.push(slidePosition);
1425      slidePosition = slidePosition + slideSize + spaceBetween;
1426    }
1427
1428    swiper.virtualSize += slideSize + spaceBetween;
1429
1430    prevSlideSize = slideSize;
1431
1432    index += 1;
1433  }
1434  swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
1435  let newSlidesGrid;
1436
1437  if (
1438    rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
1439    $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` });
1440  }
1441  if (params.setWrapperSize) {
1442    if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` });
1443    else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` });
1444  }
1445
1446  if (params.slidesPerColumn > 1) {
1447    swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows;
1448    swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween;
1449    if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` });
1450    else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` });
1451    if (params.centeredSlides) {
1452      newSlidesGrid = [];
1453      for (let i = 0; i < snapGrid.length; i += 1) {
1454        let slidesGridItem = snapGrid[i];
1455        if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
1456        if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
1457      }
1458      snapGrid = newSlidesGrid;
1459    }
1460  }
1461
1462  // Remove last grid elements depending on width
1463  if (!params.centeredSlides) {
1464    newSlidesGrid = [];
1465    for (let i = 0; i < snapGrid.length; i += 1) {
1466      let slidesGridItem = snapGrid[i];
1467      if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
1468      if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
1469        newSlidesGrid.push(slidesGridItem);
1470      }
1471    }
1472    snapGrid = newSlidesGrid;
1473    if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
1474      snapGrid.push(swiper.virtualSize - swiperSize);
1475    }
1476  }
1477  if (snapGrid.length === 0) snapGrid = [0];
1478
1479  if (params.spaceBetween !== 0) {
1480    if (swiper.isHorizontal()) {
1481      if (rtl) slides.filter(slidesForMargin).css({ marginLeft: `${spaceBetween}px` });
1482      else slides.filter(slidesForMargin).css({ marginRight: `${spaceBetween}px` });
1483    } else slides.filter(slidesForMargin).css({ marginBottom: `${spaceBetween}px` });
1484  }
1485
1486  if (params.centeredSlides && params.centeredSlidesBounds) {
1487    let allSlidesSize = 0;
1488    slidesSizesGrid.forEach((slideSizeValue) => {
1489      allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
1490    });
1491    allSlidesSize -= params.spaceBetween;
1492    const maxSnap = allSlidesSize - swiperSize;
1493    snapGrid = snapGrid.map((snap) => {
1494      if (snap < 0) return -offsetBefore;
1495      if (snap > maxSnap) return maxSnap + offsetAfter;
1496      return snap;
1497    });
1498  }
1499
1500  if (params.centerInsufficientSlides) {
1501    let allSlidesSize = 0;
1502    slidesSizesGrid.forEach((slideSizeValue) => {
1503      allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
1504    });
1505    allSlidesSize -= params.spaceBetween;
1506    if (allSlidesSize < swiperSize) {
1507      const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
1508      snapGrid.forEach((snap, snapIndex) => {
1509        snapGrid[snapIndex] = snap - allSlidesOffset;
1510      });
1511      slidesGrid.forEach((snap, snapIndex) => {
1512        slidesGrid[snapIndex] = snap + allSlidesOffset;
1513      });
1514    }
1515  }
1516
1517  Utils.extend(swiper, {
1518    slides,
1519    snapGrid,
1520    slidesGrid,
1521    slidesSizesGrid,
1522  });
1523
1524  if (slidesLength !== previousSlidesLength) {
1525    swiper.emit('slidesLengthChange');
1526  }
1527  if (snapGrid.length !== previousSnapGridLength) {
1528    if (swiper.params.watchOverflow) swiper.checkOverflow();
1529    swiper.emit('snapGridLengthChange');
1530  }
1531  if (slidesGrid.length !== previousSlidesGridLength) {
1532    swiper.emit('slidesGridLengthChange');
1533  }
1534
1535  if (params.watchSlidesProgress || params.watchSlidesVisibility) {
1536    swiper.updateSlidesOffset();
1537  }
1538}
1539
1540function updateAutoHeight (speed) {
1541  const swiper = this;
1542  const activeSlides = [];
1543  let newHeight = 0;
1544  let i;
1545  if (typeof speed === 'number') {
1546    swiper.setTransition(speed);
1547  } else if (speed === true) {
1548    swiper.setTransition(swiper.params.speed);
1549  }
1550  // Find slides currently in view
1551  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1552    if (swiper.params.centeredSlides) {
1553      swiper.visibleSlides.each((index, slide) => {
1554        activeSlides.push(slide);
1555      });
1556    } else {
1557      for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1558        const index = swiper.activeIndex + i;
1559        if (index > swiper.slides.length) break;
1560        activeSlides.push(swiper.slides.eq(index)[0]);
1561      }
1562    }
1563  } else {
1564    activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]);
1565  }
1566
1567  // Find new height from highest slide in view
1568  for (i = 0; i < activeSlides.length; i += 1) {
1569    if (typeof activeSlides[i] !== 'undefined') {
1570      const height = activeSlides[i].offsetHeight;
1571      newHeight = height > newHeight ? height : newHeight;
1572    }
1573  }
1574
1575  // Update Height
1576  if (newHeight) swiper.$wrapperEl.css('height', `${newHeight}px`);
1577}
1578
1579function updateSlidesOffset () {
1580  const swiper = this;
1581  const slides = swiper.slides;
1582  for (let i = 0; i < slides.length; i += 1) {
1583    slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop;
1584  }
1585}
1586
1587function updateSlidesProgress (translate = (this && this.translate) || 0) {
1588  const swiper = this;
1589  const params = swiper.params;
1590
1591  const { slides, rtlTranslate: rtl } = swiper;
1592
1593  if (slides.length === 0) return;
1594  if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
1595
1596  let offsetCenter = -translate;
1597  if (rtl) offsetCenter = translate;
1598
1599  // Visible Slides
1600  slides.removeClass(params.slideVisibleClass);
1601
1602  swiper.visibleSlidesIndexes = [];
1603  swiper.visibleSlides = [];
1604
1605  for (let i = 0; i < slides.length; i += 1) {
1606    const slide = slides[i];
1607    const slideProgress = (
1608      (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0)) - slide.swiperSlideOffset
1609    ) / (slide.swiperSlideSize + params.spaceBetween);
1610    if (params.watchSlidesVisibility || (params.centeredSlides && params.autoHeight)) {
1611      const slideBefore = -(offsetCenter - slide.swiperSlideOffset);
1612      const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
1613      const isVisible = (slideBefore >= 0 && slideBefore < swiper.size - 1)
1614                || (slideAfter > 1 && slideAfter <= swiper.size)
1615                || (slideBefore <= 0 && slideAfter >= swiper.size);
1616      if (isVisible) {
1617        swiper.visibleSlides.push(slide);
1618        swiper.visibleSlidesIndexes.push(i);
1619        slides.eq(i).addClass(params.slideVisibleClass);
1620      }
1621    }
1622    slide.progress = rtl ? -slideProgress : slideProgress;
1623  }
1624  swiper.visibleSlides = $(swiper.visibleSlides);
1625}
1626
1627function updateProgress (translate) {
1628  const swiper = this;
1629  if (typeof translate === 'undefined') {
1630    const multiplier = swiper.rtlTranslate ? -1 : 1;
1631    // eslint-disable-next-line
1632    translate = (swiper && swiper.translate && (swiper.translate * multiplier)) || 0;
1633  }
1634  const params = swiper.params;
1635  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1636  let { progress, isBeginning, isEnd } = swiper;
1637  const wasBeginning = isBeginning;
1638  const wasEnd = isEnd;
1639  if (translatesDiff === 0) {
1640    progress = 0;
1641    isBeginning = true;
1642    isEnd = true;
1643  } else {
1644    progress = (translate - swiper.minTranslate()) / (translatesDiff);
1645    isBeginning = progress <= 0;
1646    isEnd = progress >= 1;
1647  }
1648  Utils.extend(swiper, {
1649    progress,
1650    isBeginning,
1651    isEnd,
1652  });
1653
1654  if (params.watchSlidesProgress || params.watchSlidesVisibility || (params.centeredSlides && params.autoHeight)) swiper.updateSlidesProgress(translate);
1655
1656  if (isBeginning && !wasBeginning) {
1657    swiper.emit('reachBeginning toEdge');
1658  }
1659  if (isEnd && !wasEnd) {
1660    swiper.emit('reachEnd toEdge');
1661  }
vendor: 4,842 bytes, lines 1662-1790
1662  if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) {
1663    swiper.emit('fromEdge');
1664  }
1665
1666  swiper.emit('progress', progress);
1667}
1668
1669function updateSlidesClasses () {
1670  const swiper = this;
1671
1672  const {
1673    slides, params, $wrapperEl, activeIndex, realIndex,
1674  } = swiper;
1675  const isVirtual = swiper.virtual && params.virtual.enabled;
1676
1677  slides.removeClass(`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`);
1678
1679  let activeSlide;
1680  if (isVirtual) {
1681    activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`);
1682  } else {
1683    activeSlide = slides.eq(activeIndex);
1684  }
1685
1686  // Active classes
1687  activeSlide.addClass(params.slideActiveClass);
1688
1689  if (params.loop) {
1690    // Duplicate to all looped slides
1691    if (activeSlide.hasClass(params.slideDuplicateClass)) {
1692      $wrapperEl
1693        .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${realIndex}"]`)
1694        .addClass(params.slideDuplicateActiveClass);
1695    } else {
1696      $wrapperEl
1697        .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${realIndex}"]`)
1698        .addClass(params.slideDuplicateActiveClass);
1699    }
1700  }
1701  // Next Slide
1702  let nextSlide = activeSlide.nextAll(`.${params.slideClass}`).eq(0).addClass(params.slideNextClass);
1703  if (params.loop && nextSlide.length === 0) {
1704    nextSlide = slides.eq(0);
1705    nextSlide.addClass(params.slideNextClass);
1706  }
1707  // Prev Slide
1708  let prevSlide = activeSlide.prevAll(`.${params.slideClass}`).eq(0).addClass(params.slidePrevClass);
1709  if (params.loop && prevSlide.length === 0) {
1710    prevSlide = slides.eq(-1);
1711    prevSlide.addClass(params.slidePrevClass);
1712  }
1713  if (params.loop) {
1714    // Duplicate to all looped slides
1715    if (nextSlide.hasClass(params.slideDuplicateClass)) {
1716      $wrapperEl
1717        .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`)
1718        .addClass(params.slideDuplicateNextClass);
1719    } else {
1720      $wrapperEl
1721        .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`)
1722        .addClass(params.slideDuplicateNextClass);
1723    }
1724    if (prevSlide.hasClass(params.slideDuplicateClass)) {
1725      $wrapperEl
1726        .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`)
1727        .addClass(params.slideDuplicatePrevClass);
1728    } else {
1729      $wrapperEl
1730        .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`)
1731        .addClass(params.slideDuplicatePrevClass);
1732    }
1733  }
1734}
1735
1736function updateActiveIndex (newActiveIndex) {
1737  const swiper = this;
1738  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1739  const {
1740    slidesGrid, snapGrid, params, activeIndex: previousIndex, realIndex: previousRealIndex, snapIndex: previousSnapIndex,
1741  } = swiper;
1742  let activeIndex = newActiveIndex;
1743  let snapIndex;
1744  if (typeof activeIndex === 'undefined') {
1745    for (let i = 0; i < slidesGrid.length; i += 1) {
1746      if (typeof slidesGrid[i + 1] !== 'undefined') {
1747        if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - ((slidesGrid[i + 1] - slidesGrid[i]) / 2)) {
1748          activeIndex = i;
1749        } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
1750          activeIndex = i + 1;
1751        }
1752      } else if (translate >= slidesGrid[i]) {
1753        activeIndex = i;
1754      }
1755    }
1756    // Normalize slideIndex
1757    if (params.normalizeSlideIndex) {
1758      if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1759    }
1760  }
1761  if (snapGrid.indexOf(translate) >= 0) {
1762    snapIndex = snapGrid.indexOf(translate);
1763  } else {
1764    const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
1765    snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
1766  }
1767  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1768  if (activeIndex === previousIndex) {
1769    if (snapIndex !== previousSnapIndex) {
1770      swiper.snapIndex = snapIndex;
1771      swiper.emit('snapIndexChange');
1772    }
1773    return;
1774  }
1775
1776  // Get real index
1777  const realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10);
1778
1779  Utils.extend(swiper, {
1780    snapIndex,
1781    realIndex,
1782    previousIndex,
1783    activeIndex,
1784  });
1785  swiper.emit('activeIndexChange');
1786  swiper.emit('snapIndexChange');
1787  if (previousRealIndex !== realIndex) {
1788    swiper.emit('realIndexChange');
1789  }
1790  if (swiper.initialized || swiper.params
vendor: 7,722 bytes, lines 1790-2080
1790.runCallbacksOnInit) {
1791    swiper.emit('slideChange');
1792  }
1793}
1794
1795function updateClickedSlide (e) {
1796  const swiper = this;
1797  const params = swiper.params;
1798  const slide = $(e.target).closest(`.${params.slideClass}`)[0];
1799  let slideFound = false;
1800  if (slide) {
1801    for (let i = 0; i < swiper.slides.length; i += 1) {
1802      if (swiper.slides[i] === slide) slideFound = true;
1803    }
1804  }
1805
1806  if (slide && slideFound) {
1807    swiper.clickedSlide = slide;
1808    if (swiper.virtual && swiper.params.virtual.enabled) {
1809      swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10);
1810    } else {
1811      swiper.clickedIndex = $(slide).index();
1812    }
1813  } else {
1814    swiper.clickedSlide = undefined;
1815    swiper.clickedIndex = undefined;
1816    return;
1817  }
1818  if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
1819    swiper.slideToClickedSlide();
1820  }
1821}
1822
1823var update = {
1824  updateSize,
1825  updateSlides,
1826  updateAutoHeight,
1827  updateSlidesOffset,
1828  updateSlidesProgress,
1829  updateProgress,
1830  updateSlidesClasses,
1831  updateActiveIndex,
1832  updateClickedSlide,
1833};
1834
1835function getTranslate (axis = this.isHorizontal() ? 'x' : 'y') {
1836  const swiper = this;
1837
1838  const {
1839    params, rtlTranslate: rtl, translate, $wrapperEl,
1840  } = swiper;
1841
1842  if (params.virtualTranslate) {
1843    return rtl ? -translate : translate;
1844  }
1845  if (params.cssMode) {
1846    return translate;
1847  }
1848
1849  let currentTranslate = Utils.getTranslate($wrapperEl[0], axis);
1850  if (rtl) currentTranslate = -currentTranslate;
1851
1852  return currentTranslate || 0;
1853}
1854
1855function setTranslate (translate, byController) {
1856  const swiper = this;
1857  const {
1858    rtlTranslate: rtl, params, $wrapperEl, wrapperEl, progress,
1859  } = swiper;
1860  let x = 0;
1861  let y = 0;
1862  const z = 0;
1863
1864  if (swiper.isHorizontal()) {
1865    x = rtl ? -translate : translate;
1866  } else {
1867    y = translate;
1868  }
1869
1870  if (params.roundLengths) {
1871    x = Math.floor(x);
1872    y = Math.floor(y);
1873  }
1874
1875  if (params.cssMode) {
1876    wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1877  } else if (!params.virtualTranslate) {
1878    $wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`);
1879  }
1880  swiper.previousTranslate = swiper.translate;
1881  swiper.translate = swiper.isHorizontal() ? x : y;
1882
1883  // Check if we need to update progress
1884  let newProgress;
1885  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1886  if (translatesDiff === 0) {
1887    newProgress = 0;
1888  } else {
1889    newProgress = (translate - swiper.minTranslate()) / (translatesDiff);
1890  }
1891  if (newProgress !== progress) {
1892    swiper.updateProgress(translate);
1893  }
1894
1895  swiper.emit('setTranslate', swiper.translate, byController);
1896}
1897
1898function minTranslate () {
1899  return (-this.snapGrid[0]);
1900}
1901
1902function maxTranslate () {
1903  return (-this.snapGrid[this.snapGrid.length - 1]);
1904}
1905
1906function translateTo (translate = 0, speed = this.params.speed, runCallbacks = true, translateBounds = true, internal) {
1907  const swiper = this;
1908
1909  const {
1910    params,
1911    wrapperEl,
1912  } = swiper;
1913
1914  if (swiper.animating && params.preventInteractionOnTransition) {
1915    return false;
1916  }
1917
1918  const minTranslate = swiper.minTranslate();
1919  const maxTranslate = swiper.maxTranslate();
1920  let newTranslate;
1921  if (translateBounds && translate > minTranslate) newTranslate = minTranslate;
1922  else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;
1923  else newTranslate = translate;
1924
1925  // Update progress
1926  swiper.updateProgress(newTranslate);
1927
1928  if (params.cssMode) {
1929    const isH = swiper.isHorizontal();
1930    if (speed === 0) {
1931      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1932    } else {
1933      // eslint-disable-next-line
1934      if (wrapperEl.scrollTo) {
1935        wrapperEl.scrollTo({
1936          [isH ? 'left' : 'top']: -newTranslate,
1937          behavior: 'smooth',
1938        });
1939      } else {
1940        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1941      }
1942    }
1943    return true;
1944  }
1945
1946  if (speed === 0) {
1947    swiper.setTransition(0);
1948    swiper.setTranslate(newTranslate);
1949    if (runCallbacks) {
1950      swiper.emit('beforeTransitionStart', speed, internal);
1951      swiper.emit('transitionEnd');
1952    }
1953  } else {
1954    swiper.setTransition(speed);
1955    swiper.setTranslate(newTranslate);
1956    if (runCallbacks) {
1957      swiper.emit('beforeTransitionStart', speed, internal);
1958      swiper.emit('transitionStart');
1959    }
1960    if (!swiper.animating) {
1961      swiper.animating = true;
1962      if (!swiper.onTranslateToWrapperTransitionEnd) {
1963        swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
1964          if (!swiper || swiper.destroyed) return;
1965          if (e.target !== this) return;
1966          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1967          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);
1968          swiper.onTranslateToWrapperTransitionEnd = null;
1969          delete swiper.onTranslateToWrapperTransitionEnd;
1970          if (runCallbacks) {
1971            swiper.emit('transitionEnd');
1972          }
1973        };
1974      }
1975      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1976      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);
1977    }
1978  }
1979
1980  return true;
1981}
1982
1983var translate = {
1984  getTranslate,
1985  setTranslate,
1986  minTranslate,
1987  maxTranslate,
1988  translateTo,
1989};
1990
1991function setTransition (duration, byController) {
1992  const swiper = this;
1993
1994  if (!swiper.params.cssMode) {
1995    swiper.$wrapperEl.transition(duration);
1996  }
1997
1998  swiper.emit('setTransition', duration, byController);
1999}
2000
2001function transitionStart (runCallbacks = true, direction) {
2002  const swiper = this;
2003  const { activeIndex, params, previousIndex } = swiper;
2004  if (params.cssMode) return;
2005  if (params.autoHeight) {
2006    swiper.updateAutoHeight();
2007  }
2008
2009  let dir = direction;
2010  if (!dir) {
2011    if (activeIndex > previousIndex) dir = 'next';
2012    else if (activeIndex < previousIndex) dir = 'prev';
2013    else dir = 'reset';
2014  }
2015
2016  swiper.emit('transitionStart');
2017
2018  if (runCallbacks && activeIndex !== previousIndex) {
2019    if (dir === 'reset') {
2020      swiper.emit('slideResetTransitionStart');
2021      return;
2022    }
2023    swiper.emit('slideChangeTransitionStart');
2024    if (dir === 'next') {
2025      swiper.emit('slideNextTransitionStart');
2026    } else {
2027      swiper.emit('slidePrevTransitionStart');
2028    }
2029  }
2030}
2031
2032function transitionEnd$1 (runCallbacks = true, direction) {
2033  const swiper = this;
2034  const { activeIndex, previousIndex, params } = swiper;
2035  swiper.animating = false;
2036  if (params.cssMode) return;
2037  swiper.setTransition(0);
2038
2039  let dir = direction;
2040  if (!dir) {
2041    if (activeIndex > previousIndex) dir = 'next';
2042    else if (activeIndex < previousIndex) dir = 'prev';
2043    else dir = 'reset';
2044  }
2045
2046  swiper.emit('transitionEnd');
2047
2048  if (runCallbacks && activeIndex !== previousIndex) {
2049    if (dir === 'reset') {
2050      swiper.emit('slideResetTransitionEnd');
2051      return;
2052    }
2053    swiper.emit('slideChangeTransitionEnd');
2054    if (dir === 'next') {
2055      swiper.emit('slideNextTransitionEnd');
2056    } else {
2057      swiper.emit('slidePrevTransitionEnd');
2058    }
2059  }
2060}
2061
2062var transition$1 = {
2063  setTransition,
2064  transitionStart,
2065  transitionEnd: transitionEnd$1,
2066};
2067
2068function slideTo (index = 0, speed = this.params.speed, runCallbacks = true, internal) {
2069  const swiper = this;
2070  let slideIndex = index;
2071  if (slideIndex < 0) slideIndex = 0;
2072
2073  const {
2074    params, snapGrid, slidesGrid, previousIndex, activeIndex, rtlTranslate: rtl, wrapperEl,
2075  } = swiper;
2076  if (swiper.animating && params.preventInteractionOnTransition) {
2077    return false;
2078  }
2079
2080  
vendor: 7,494 bytes, lines 2080-2286
2080const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
2081  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
2082  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
2083
2084  if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
2085    swiper.emit('beforeSlideChangeStart');
2086  }
2087
2088  const translate = -snapGrid[snapIndex];
2089
2090  // Update progress
2091  swiper.updateProgress(translate);
2092
2093  // Normalize slideIndex
2094  if (params.normalizeSlideIndex) {
2095    for (let i = 0; i < slidesGrid.length; i += 1) {
2096      if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) {
2097        slideIndex = i;
2098      }
2099    }
2100  }
2101  // Directions locks
2102  if (swiper.initialized && slideIndex !== activeIndex) {
2103    if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
2104      return false;
2105    }
2106    if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
2107      if ((activeIndex || 0) !== slideIndex) return false;
2108    }
2109  }
2110
2111  let direction;
2112  if (slideIndex > activeIndex) direction = 'next';
2113  else if (slideIndex < activeIndex) direction = 'prev';
2114  else direction = 'reset';
2115
2116
2117  // Update Index
2118  if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) {
2119    swiper.updateActiveIndex(slideIndex);
2120    // Update Height
2121    if (params.autoHeight) {
2122      swiper.updateAutoHeight();
2123    }
2124    swiper.updateSlidesClasses();
2125    if (params.effect !== 'slide') {
2126      swiper.setTranslate(translate);
2127    }
2128    if (direction !== 'reset') {
2129      swiper.transitionStart(runCallbacks, direction);
2130      swiper.transitionEnd(runCallbacks, direction);
2131    }
2132    return false;
2133  }
2134  if (params.cssMode) {
2135    const isH = swiper.isHorizontal();
2136    let t = -translate;
2137    if (rtl) {
2138      t = wrapperEl.scrollWidth - wrapperEl.offsetWidth - t;
2139    }
2140    if (speed === 0) {
2141      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
2142    } else {
2143      // eslint-disable-next-line
2144      if (wrapperEl.scrollTo) {
2145        wrapperEl.scrollTo({
2146          [isH ? 'left' : 'top']: t,
2147          behavior: 'smooth',
2148        });
2149      } else {
2150        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
2151      }
2152    }
2153    return true;
2154  }
2155
2156  if (speed === 0) {
2157    swiper.setTransition(0);
2158    swiper.setTranslate(translate);
2159    swiper.updateActiveIndex(slideIndex);
2160    swiper.updateSlidesClasses();
2161    swiper.emit('beforeTransitionStart', speed, internal);
2162    swiper.transitionStart(runCallbacks, direction);
2163    swiper.transitionEnd(runCallbacks, direction);
2164  } else {
2165    swiper.setTransition(speed);
2166    swiper.setTranslate(translate);
2167    swiper.updateActiveIndex(slideIndex);
2168    swiper.updateSlidesClasses();
2169    swiper.emit('beforeTransitionStart', speed, internal);
2170    swiper.transitionStart(runCallbacks, direction);
2171    if (!swiper.animating) {
2172      swiper.animating = true;
2173      if (!swiper.onSlideToWrapperTransitionEnd) {
2174        swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
2175          if (!swiper || swiper.destroyed) return;
2176          if (e.target !== this) return;
2177          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
2178          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
2179          swiper.onSlideToWrapperTransitionEnd = null;
2180          delete swiper.onSlideToWrapperTransitionEnd;
2181          swiper.transitionEnd(runCallbacks, direction);
2182        };
2183      }
2184      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
2185      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
2186    }
2187  }
2188
2189  return true;
2190}
2191
2192function slideToLoop (index = 0, speed = this.params.speed, runCallbacks = true, internal) {
2193  const swiper = this;
2194  let newIndex = index;
2195  if (swiper.params.loop) {
2196    newIndex += swiper.loopedSlides;
2197  }
2198
2199  return swiper.slideTo(newIndex, speed, runCallbacks, internal);
2200}
2201
2202/* eslint no-unused-vars: "off" */
2203function slideNext (speed = this.params.speed, runCallbacks = true, internal) {
2204  const swiper = this;
2205  const { params, animating } = swiper;
2206  const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup;
2207  if (params.loop) {
2208    if (animating) return false;
2209    swiper.loopFix();
2210    // eslint-disable-next-line
2211    swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
2212  }
2213  return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
2214}
2215
2216/* eslint no-unused-vars: "off" */
2217function slidePrev (speed = this.params.speed, runCallbacks = true, internal) {
2218  const swiper = this;
2219  const {
2220    params, animating, snapGrid, slidesGrid, rtlTranslate,
2221  } = swiper;
2222
2223  if (params.loop) {
2224    if (animating) return false;
2225    swiper.loopFix();
2226    // eslint-disable-next-line
2227    swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
2228  }
2229  const translate = rtlTranslate ? swiper.translate : -swiper.translate;
2230  function normalize(val) {
2231    if (val < 0) return -Math.floor(Math.abs(val));
2232    return Math.floor(val);
2233  }
2234  const normalizedTranslate = normalize(translate);
2235  const normalizedSnapGrid = snapGrid.map((val) => normalize(val));
2236  const normalizedSlidesGrid = slidesGrid.map((val) => normalize(val));
2237
2238  const currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)];
2239  let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2240  if (typeof prevSnap === 'undefined' && params.cssMode) {
2241    snapGrid.forEach((snap) => {
2242      if (!prevSnap && normalizedTranslate >= snap) prevSnap = snap;
2243    });
2244  }
2245  let prevIndex;
2246  if (typeof prevSnap !== 'undefined') {
2247    prevIndex = slidesGrid.indexOf(prevSnap);
2248    if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
2249  }
2250  return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2251}
2252
2253/* eslint no-unused-vars: "off" */
2254function slideReset (speed = this.params.speed, runCallbacks = true, internal) {
2255  const swiper = this;
2256  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
2257}
2258
2259/* eslint no-unused-vars: "off" */
2260function slideToClosest (speed = this.params.speed, runCallbacks = true, internal, threshold = 0.5) {
2261  const swiper = this;
2262  let index = swiper.activeIndex;
2263  const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
2264  const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
2265
2266  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
2267
2268  if (translate >= swiper.snapGrid[snapIndex]) {
2269    // The current translate is on or after the current snap index, so the choice
2270    // is between the current index and the one after it.
2271    const currentSnap = swiper.snapGrid[snapIndex];
2272    const nextSnap = swiper.snapGrid[snapIndex + 1];
2273    if ((translate - currentSnap) > (nextSnap - currentSnap) * threshold) {
2274      index += swiper.params.slidesPerGroup;
2275    }
2276  } else {
2277    // The current translate is before the current snap index, so the choice
2278    // is between the current index and the one before it.
2279    const prevSnap = swiper.snapGrid[snapIndex - 1];
2280    const currentSnap = swiper.snapGrid[snapIndex];
2281    if ((translate - prevSnap) <= (currentSnap - prevSnap) * threshold) {
2282      index -= swiper.params.slidesPerGroup;
2283    }
2284  }
2285  index = Math.max(index, 0);
2286  index = Math.min(index, swiper.slides
vendor: 15,944 bytes, lines 2286-2822
2286Grid.length - 1);
2287
2288  return swiper.slideTo(index, speed, runCallbacks, internal);
2289}
2290
2291function slideToClickedSlide () {
2292  const swiper = this;
2293  const { params, $wrapperEl } = swiper;
2294
2295  const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2296  let slideToIndex = swiper.clickedIndex;
2297  let realIndex;
2298  if (params.loop) {
2299    if (swiper.animating) return;
2300    realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);
2301    if (params.centeredSlides) {
2302      if (
2303        (slideToIndex < swiper.loopedSlides - (slidesPerView / 2))
2304        || (slideToIndex > (swiper.slides.length - swiper.loopedSlides) + (slidesPerView / 2))
2305      ) {
2306        swiper.loopFix();
2307        slideToIndex = $wrapperEl
2308          .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`)
2309          .eq(0)
2310          .index();
2311
2312        Utils.nextTick(() => {
2313          swiper.slideTo(slideToIndex);
2314        });
2315      } else {
2316        swiper.slideTo(slideToIndex);
2317      }
2318    } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2319      swiper.loopFix();
2320      slideToIndex = $wrapperEl
2321        .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`)
2322        .eq(0)
2323        .index();
2324
2325      Utils.nextTick(() => {
2326        swiper.slideTo(slideToIndex);
2327      });
2328    } else {
2329      swiper.slideTo(slideToIndex);
2330    }
2331  } else {
2332    swiper.slideTo(slideToIndex);
2333  }
2334}
2335
2336var slide = {
2337  slideTo,
2338  slideToLoop,
2339  slideNext,
2340  slidePrev,
2341  slideReset,
2342  slideToClosest,
2343  slideToClickedSlide,
2344};
2345
2346function loopCreate () {
2347  const swiper = this;
2348  const { params, $wrapperEl } = swiper;
2349  // Remove duplicated slides
2350  $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}`).remove();
2351
2352  let slides = $wrapperEl.children(`.${params.slideClass}`);
2353
2354  if (params.loopFillGroupWithBlank) {
2355    const blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup);
2356    if (blankSlidesNum !== params.slidesPerGroup) {
2357      for (let i = 0; i < blankSlidesNum; i += 1) {
2358        const blankNode = $(doc.createElement('div')).addClass(`${params.slideClass} ${params.slideBlankClass}`);
2359        $wrapperEl.append(blankNode);
2360      }
2361      slides = $wrapperEl.children(`.${params.slideClass}`);
2362    }
2363  }
2364
2365  if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;
2366
2367  swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));
2368  swiper.loopedSlides += params.loopAdditionalSlides;
2369  if (swiper.loopedSlides > slides.length) {
2370    swiper.loopedSlides = slides.length;
2371  }
2372
2373  const prependSlides = [];
2374  const appendSlides = [];
2375  slides.each((index, el) => {
2376    const slide = $(el);
2377    if (index < swiper.loopedSlides) appendSlides.push(el);
2378    if (index < slides.length && index >= slides.length - swiper.loopedSlides) prependSlides.push(el);
2379    slide.attr('data-swiper-slide-index', index);
2380  });
2381  for (let i = 0; i < appendSlides.length; i += 1) {
2382    $wrapperEl.append($(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));
2383  }
2384  for (let i = prependSlides.length - 1; i >= 0; i -= 1) {
2385    $wrapperEl.prepend($(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));
2386  }
2387}
2388
2389function loopFix () {
2390  const swiper = this;
2391
2392  swiper.emit('beforeLoopFix');
2393
2394  const {
2395    activeIndex, slides, loopedSlides, allowSlidePrev, allowSlideNext, snapGrid, rtlTranslate: rtl,
2396  } = swiper;
2397  let newIndex;
2398  swiper.allowSlidePrev = true;
2399  swiper.allowSlideNext = true;
2400
2401  const snapTranslate = -snapGrid[activeIndex];
2402  const diff = snapTranslate - swiper.getTranslate();
2403
2404  // Fix For Negative Oversliding
2405  if (activeIndex < loopedSlides) {
2406    newIndex = (slides.length - (loopedSlides * 3)) + activeIndex;
2407    newIndex += loopedSlides;
2408    const slideChanged = swiper.slideTo(newIndex, 0, false, true);
2409    if (slideChanged && diff !== 0) {
2410      swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
2411    }
2412  } else if (activeIndex >= slides.length - loopedSlides) {
2413    // Fix For Positive Oversliding
2414    newIndex = -slides.length + activeIndex + loopedSlides;
2415    newIndex += loopedSlides;
2416    const slideChanged = swiper.slideTo(newIndex, 0, false, true);
2417    if (slideChanged && diff !== 0) {
2418      swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
2419    }
2420  }
2421  swiper.allowSlidePrev = allowSlidePrev;
2422  swiper.allowSlideNext = allowSlideNext;
2423
2424  swiper.emit('loopFix');
2425}
2426
2427function loopDestroy () {
2428  const swiper = this;
2429  const { $wrapperEl, params, slides } = swiper;
2430  $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass}`).remove();
2431  slides.removeAttr('data-swiper-slide-index');
2432}
2433
2434var loop = {
2435  loopCreate,
2436  loopFix,
2437  loopDestroy,
2438};
2439
2440function setGrabCursor (moving) {
2441  const swiper = this;
2442  if (Support.touch || !swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked) || swiper.params.cssMode) return;
2443  const el = swiper.el;
2444  el.style.cursor = 'move';
2445  el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';
2446  el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab';
2447  el.style.cursor = moving ? 'grabbing' : 'grab';
2448}
2449
2450function unsetGrabCursor () {
2451  const swiper = this;
2452  if (Support.touch || (swiper.params.watchOverflow && swiper.isLocked) || swiper.params.cssMode) return;
2453  swiper.el.style.cursor = '';
2454}
2455
2456var grabCursor = {
2457  setGrabCursor,
2458  unsetGrabCursor,
2459};
2460
2461function appendSlide (slides) {
2462  const swiper = this;
2463  const { $wrapperEl, params } = swiper;
2464  if (params.loop) {
2465    swiper.loopDestroy();
2466  }
2467  if (typeof slides === 'object' && 'length' in slides) {
2468    for (let i = 0; i < slides.length; i += 1) {
2469      if (slides[i]) $wrapperEl.append(slides[i]);
2470    }
2471  } else {
2472    $wrapperEl.append(slides);
2473  }
2474  if (params.loop) {
2475    swiper.loopCreate();
2476  }
2477  if (!(params.observer && Support.observer)) {
2478    swiper.update();
2479  }
2480}
2481
2482function prependSlide (slides) {
2483  const swiper = this;
2484  const { params, $wrapperEl, activeIndex } = swiper;
2485
2486  if (params.loop) {
2487    swiper.loopDestroy();
2488  }
2489  let newActiveIndex = activeIndex + 1;
2490  if (typeof slides === 'object' && 'length' in slides) {
2491    for (let i = 0; i < slides.length; i += 1) {
2492      if (slides[i]) $wrapperEl.prepend(slides[i]);
2493    }
2494    newActiveIndex = activeIndex + slides.length;
2495  } else {
2496    $wrapperEl.prepend(slides);
2497  }
2498  if (params.loop) {
2499    swiper.loopCreate();
2500  }
2501  if (!(params.observer && Support.observer)) {
2502    swiper.update();
2503  }
2504  swiper.slideTo(newActiveIndex, 0, false);
2505}
2506
2507function addSlide (index, slides) {
2508  const swiper = this;
2509  const { $wrapperEl, params, activeIndex } = swiper;
2510  let activeIndexBuffer = activeIndex;
2511  if (params.loop) {
2512    activeIndexBuffer -= swiper.loopedSlides;
2513    swiper.loopDestroy();
2514    swiper.slides = $wrapperEl.children(`.${params.slideClass}`);
2515  }
2516  const baseLength = swiper.slides.length;
2517  if (index <= 0) {
2518    swiper.prependSlide(slides);
2519    return;
2520  }
2521  if (index >= baseLength) {
2522    swiper.appendSlide(slides);
2523    return;
2524  }
2525  let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
2526
2527  const slidesBuffer = [];
2528  for (let i = baseLength - 1; i >= index; i -= 1) {
2529    const currentSlide = swiper.slides.eq(i);
2530    currentSlide.remove();
2531    slidesBuffer.unshift(currentSlide);
2532  }
2533
2534  if (typeof slides === 'object' && 'length' in slides) {
2535    for (let i = 0; i < slides.length; i += 1) {
2536      if (slides[i]) $wrapperEl.append(slides[i]);
2537    }
2538    newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
2539  } else {
2540    $wrapperEl.append(slides);
2541  }
2542
2543  for (let i = 0; i < slidesBuffer.length; i += 1) {
2544    $wrapperEl.append(slidesBuffer[i]);
2545  }
2546
2547  if (params.loop) {
2548    swiper.loopCreate();
2549  }
2550  if (!(params.observer && Support.observer)) {
2551    swiper.update();
2552  }
2553  if (params.loop) {
2554    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
2555  } else {
2556    swiper.slideTo(newActiveIndex, 0, false);
2557  }
2558}
2559
2560function removeSlide (slidesIndexes) {
2561  const swiper = this;
2562  const { params, $wrapperEl, activeIndex } = swiper;
2563
2564  let activeIndexBuffer = activeIndex;
2565  if (params.loop) {
2566    activeIndexBuffer -= swiper.loopedSlides;
2567    swiper.loopDestroy();
2568    swiper.slides = $wrapperEl.children(`.${params.slideClass}`);
2569  }
2570  let newActiveIndex = activeIndexBuffer;
2571  let indexToRemove;
2572
2573  if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
2574    for (let i = 0; i < slidesIndexes.length; i += 1) {
2575      indexToRemove = slidesIndexes[i];
2576      if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();
2577      if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
2578    }
2579    newActiveIndex = Math.max(newActiveIndex, 0);
2580  } else {
2581    indexToRemove = slidesIndexes;
2582    if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();
2583    if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
2584    newActiveIndex = Math.max(newActiveIndex, 0);
2585  }
2586
2587  if (params.loop) {
2588    swiper.loopCreate();
2589  }
2590
2591  if (!(params.observer && Support.observer)) {
2592    swiper.update();
2593  }
2594  if (params.loop) {
2595    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
2596  } else {
2597    swiper.slideTo(newActiveIndex, 0, false);
2598  }
2599}
2600
2601function removeAllSlides () {
2602  const swiper = this;
2603
2604  const slidesIndexes = [];
2605  for (let i = 0; i < swiper.slides.length; i += 1) {
2606    slidesIndexes.push(i);
2607  }
2608  swiper.removeSlide(slidesIndexes);
2609}
2610
2611var manipulation = {
2612  appendSlide,
2613  prependSlide,
2614  addSlide,
2615  removeSlide,
2616  removeAllSlides,
2617};
2618
2619const Device = (function Device() {
2620  const platform = win.navigator.platform;
2621  const ua = win.navigator.userAgent;
2622
2623  const device = {
2624    ios: false,
2625    android: false,
2626    androidChrome: false,
2627    desktop: false,
2628    iphone: false,
2629    ipod: false,
2630    ipad: false,
2631    edge: false,
2632    ie: false,
2633    firefox: false,
2634    macos: false,
2635    windows: false,
2636    cordova: !!(win.cordova || win.phonegap),
2637    phonegap: !!(win.cordova || win.phonegap),
2638    electron: false,
2639  };
2640
2641  const screenWidth = win.screen.width;
2642  const screenHeight = win.screen.height;
2643
2644  const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2645  let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
2646  const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
2647  const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
2648  const ie = ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
2649  const edge = ua.indexOf('Edge/') >= 0;
2650  const firefox = ua.indexOf('Gecko/') >= 0 && ua.indexOf('Firefox/') >= 0;
2651  const windows = platform === 'Win32';
2652  const electron = ua.toLowerCase().indexOf('electron') >= 0;
2653  let macos = platform === 'MacIntel';
2654
2655  // iPadOs 13 fix
2656  if (!ipad
2657    && macos
2658    && Support.touch
2659    && (
2660      (screenWidth === 1024 && screenHeight === 1366) // Pro 12.9
2661      || (screenWidth === 834 && screenHeight === 1194) // Pro 11
2662      || (screenWidth === 834 && screenHeight === 1112) // Pro 10.5
2663      || (screenWidth === 768 && screenHeight === 1024) // other
2664    )
2665  ) {
2666    ipad = ua.match(/(Version)\/([\d.]+)/);
2667    macos = false;
2668  }
2669
2670  device.ie = ie;
2671  device.edge = edge;
2672  device.firefox = firefox;
2673
2674  // Android
2675  if (android && !windows) {
2676    device.os = 'android';
2677    device.osVersion = android[2];
2678    device.android = true;
2679    device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;
2680  }
2681  if (ipad || iphone || ipod) {
2682    device.os = 'ios';
2683    device.ios = true;
2684  }
2685  // iOS
2686  if (iphone && !ipod) {
2687    device.osVersion = iphone[2].replace(/_/g, '.');
2688    device.iphone = true;
2689  }
2690  if (ipad) {
2691    device.osVersion = ipad[2].replace(/_/g, '.');
2692    device.ipad = true;
2693  }
2694  if (ipod) {
2695    device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
2696    device.ipod = true;
2697  }
2698  // iOS 8+ changed UA
2699  if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {
2700    if (device.osVersion.split('.')[0] === '10') {
2701      device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];
2702    }
2703  }
2704
2705  // Webview
2706  device.webView = !!((iphone || ipad || ipod) && (ua.match(/.*AppleWebKit(?!.*Safari)/i) || win.navigator.standalone))
2707    || (win.matchMedia && win.matchMedia('(display-mode: standalone)').matches);
2708  device.webview = device.webView;
2709  device.standalone = device.webView;
2710
2711  // Desktop
2712  device.desktop = !(device.ios || device.android) || electron;
2713  if (device.desktop) {
2714    device.electron = electron;
2715    device.macos = macos;
2716    device.windows = windows;
2717    if (device.macos) {
2718      device.os = 'macos';
2719    }
2720    if (device.windows) {
2721      device.os = 'windows';
2722    }
2723  }
2724
2725  // Pixel Ratio
2726  device.pixelRatio = win.devicePixelRatio || 1;
2727
2728  // Export object
2729  return device;
2730}());
2731
2732function onTouchStart (event) {
2733  const swiper = this;
2734  const data = swiper.touchEventsData;
2735  const { params, touches } = swiper;
2736
2737  if (swiper.animating && params.preventInteractionOnTransition) {
2738    return;
2739  }
2740  let e = event;
2741  if (e.originalEvent) e = e.originalEvent;
2742  const $targetEl = $(e.target);
2743
2744  if (params.touchEventsTarget === 'wrapper') {
2745    if (!$targetEl.closest(swiper.wrapperEl).length) return;
2746  }
2747  data.isTouchEvent = e.type === 'touchstart';
2748  if (!data.isTouchEvent && 'which' in e && e.which === 3) return;
2749  if (!data.isTouchEvent && 'button' in e && e.button > 0) return;
2750  if (data.isTouched && data.isMoved) return;
2751  if (params.noSwiping && $targetEl.closest(params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`)[0]) {
2752    swiper.allowClick = true;
2753    return;
2754  }
2755  if (params.swipeHandler) {
2756    if (!$targetEl.closest(params.swipeHandler)[0]) return;
2757  }
2758
2759  touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
2760  touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
2761  const startX = touches.currentX;
2762  const startY = touches.currentY;
2763
2764  // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
2765
2766  const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
2767  const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
2768  if (
2769    edgeSwipeDetection
2770    && ((startX <= edgeSwipeThreshold)
2771    || (startX >= win.screen.width - edgeSwipeThreshold))
2772  ) {
2773    return;
2774  }
2775
2776  Utils.extend(data, {
2777    isTouched: true,
2778    isMoved: false,
2779    allowTouchCallbacks: true,
2780    isScrolling: undefined,
2781    startMoving: undefined,
2782  });
2783
2784  touches.startX = startX;
2785  touches.startY = startY;
2786  data.touchStartTime = Utils.now();
2787  swiper.allowClick = true;
2788  swiper.updateSize();
2789  swiper.swipeDirection = undefined;
2790  if (params.threshold > 0) data.allowThresholdMove = false;
2791  if (e.type !== 'touchstart') {
2792    let preventDefault = true;
2793    if ($targetEl.is(data.formElements)) preventDefault = false;
2794    if (
2795      doc.activeElement
2796      && $(doc.activeElement).is(data.formElements)
2797      && doc.activeElement !== $targetEl[0]
2798    ) {
2799      doc.activeElement.blur();
2800    }
2801
2802    const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
2803    if (params.touchStartForcePreventDefault || shouldPreventDefault) {
2804      e.preventDefault();
2805    }
2806  }
2807  swiper.emit('touchStart', e);
2808}
2809
2810function onTouchMove (event) {
2811  const swiper = this;
2812  const data = swiper.touchEventsData;
2813  const { params, touches, rtlTranslate: rtl } = swiper;
2814  let e = event;
2815  if (e.originalEvent) e = e.originalEvent;
2816  if (!data.isTouched) {
2817    if (data.startMoving && data.isScrolling) {
2818      swiper.emit('touchMoveOpposite', e);
2819    }
2820    return;
2821  }
2822  if (data.isTouchEvent && e.type 
vendor: 2,887 bytes, lines 2822-2910
2822!== 'touchmove') return;
2823  const targetTouch = e.type === 'touchmove' && e.targetTouches && (e.targetTouches[0] || e.changedTouches[0]);
2824  const pageX = e.type === 'touchmove' ? targetTouch.pageX : e.pageX;
2825  const pageY = e.type === 'touchmove' ? targetTouch.pageY : e.pageY;
2826  if (e.preventedByNestedSwiper) {
2827    touches.startX = pageX;
2828    touches.startY = pageY;
2829    return;
2830  }
2831  if (!swiper.allowTouchMove) {
2832    // isMoved = true;
2833    swiper.allowClick = false;
2834    if (data.isTouched) {
2835      Utils.extend(touches, {
2836        startX: pageX,
2837        startY: pageY,
2838        currentX: pageX,
2839        currentY: pageY,
2840      });
2841      data.touchStartTime = Utils.now();
2842    }
2843    return;
2844  }
2845  if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {
2846    if (swiper.isVertical()) {
2847      // Vertical
2848      if (
2849        (pageY < touches.startY && swiper.translate <= swiper.maxTranslate())
2850        || (pageY > touches.startY && swiper.translate >= swiper.minTranslate())
2851      ) {
2852        data.isTouched = false;
2853        data.isMoved = false;
2854        return;
2855      }
2856    } else if (
2857      (pageX < touches.startX && swiper.translate <= swiper.maxTranslate())
2858      || (pageX > touches.startX && swiper.translate >= swiper.minTranslate())
2859    ) {
2860      return;
2861    }
2862  }
2863  if (data.isTouchEvent && doc.activeElement) {
2864    if (e.target === doc.activeElement && $(e.target).is(data.formElements)) {
2865      data.isMoved = true;
2866      swiper.allowClick = false;
2867      return;
2868    }
2869  }
2870  if (data.allowTouchCallbacks) {
2871    swiper.emit('touchMove', e);
2872  }
2873  if (e.targetTouches && e.targetTouches.length > 1) return;
2874
2875  touches.currentX = pageX;
2876  touches.currentY = pageY;
2877
2878  const diffX = touches.currentX - touches.startX;
2879  const diffY = touches.currentY - touches.startY;
2880  if (swiper.params.threshold && Math.sqrt((diffX ** 2) + (diffY ** 2)) < swiper.params.threshold) return;
2881
2882  if (typeof data.isScrolling === 'undefined') {
2883    let touchAngle;
2884    if ((swiper.isHorizontal() && touches.currentY === touches.startY) || (swiper.isVertical() && touches.currentX === touches.startX)) {
2885      data.isScrolling = false;
2886    } else {
2887      // eslint-disable-next-line
2888      if ((diffX * diffX) + (diffY * diffY) >= 25) {
2889        touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI;
2890        data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : (90 - touchAngle > params.touchAngle);
2891      }
2892    }
2893  }
2894  if (data.isScrolling) {
2895    swiper.emit('touchMoveOpposite', e);
2896  }
2897  if (typeof data.startMoving === 'undefined') {
2898    if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
2899      data.startMoving = true;
2900    }
2901  }
2902  if (data.isScrolling) {
2903    data.isTouched = false;
2904    return;
2905  }
2906  if (!data.startMoving) {
2907    return;
2908  }
2909  swiper.allowClick = false;
2910  if (!params.cssMode && e.cancelabl
vendor: 10,434 bytes, lines 2910-3209
2910e) {
2911    e.preventDefault();
2912  }
2913  if (params.touchMoveStopPropagation && !params.nested) {
2914    e.stopPropagation();
2915  }
2916
2917  if (!data.isMoved) {
2918    if (params.loop) {
2919      swiper.loopFix();
2920    }
2921    data.startTranslate = swiper.getTranslate();
2922    swiper.setTransition(0);
2923    if (swiper.animating) {
2924      swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend');
2925    }
2926    data.allowMomentumBounce = false;
2927    // Grab Cursor
2928    if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2929      swiper.setGrabCursor(true);
2930    }
2931    swiper.emit('sliderFirstMove', e);
2932  }
2933  swiper.emit('sliderMove', e);
2934  data.isMoved = true;
2935
2936  let diff = swiper.isHorizontal() ? diffX : diffY;
2937  touches.diff = diff;
2938
2939  diff *= params.touchRatio;
2940  if (rtl) diff = -diff;
2941
2942  swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
2943  data.currentTranslate = diff + data.startTranslate;
2944
2945  let disableParentSwiper = true;
2946  let resistanceRatio = params.resistanceRatio;
2947  if (params.touchReleaseOnEdges) {
2948    resistanceRatio = 0;
2949  }
2950  if ((diff > 0 && data.currentTranslate > swiper.minTranslate())) {
2951    disableParentSwiper = false;
2952    if (params.resistance) data.currentTranslate = (swiper.minTranslate() - 1) + ((-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio);
2953  } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {
2954    disableParentSwiper = false;
2955    if (params.resistance) data.currentTranslate = (swiper.maxTranslate() + 1) - ((swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio);
2956  }
2957
2958  if (disableParentSwiper) {
2959    e.preventedByNestedSwiper = true;
2960  }
2961
2962  // Directions locks
2963  if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
2964    data.currentTranslate = data.startTranslate;
2965  }
2966  if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
2967    data.currentTranslate = data.startTranslate;
2968  }
2969
2970
2971  // Threshold
2972  if (params.threshold > 0) {
2973    if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2974      if (!data.allowThresholdMove) {
2975        data.allowThresholdMove = true;
2976        touches.startX = touches.currentX;
2977        touches.startY = touches.currentY;
2978        data.currentTranslate = data.startTranslate;
2979        touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
2980        return;
2981      }
2982    } else {
2983      data.currentTranslate = data.startTranslate;
2984      return;
2985    }
2986  }
2987
2988  if (!params.followFinger || params.cssMode) return;
2989
2990  // Update active index in free mode
2991  if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) {
2992    swiper.updateActiveIndex();
2993    swiper.updateSlidesClasses();
2994  }
2995  if (params.freeMode) {
2996    // Velocity
2997    if (data.velocities.length === 0) {
2998      data.velocities.push({
2999        position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
3000        time: data.touchStartTime,
3001      });
3002    }
3003    data.velocities.push({
3004      position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
3005      time: Utils.now(),
3006    });
3007  }
3008  // Update progress
3009  swiper.updateProgress(data.currentTranslate);
3010  // Update translate
3011  swiper.setTranslate(data.currentTranslate);
3012}
3013
3014function onTouchEnd (event) {
3015  const swiper = this;
3016  const data = swiper.touchEventsData;
3017
3018  const {
3019    params, touches, rtlTranslate: rtl, $wrapperEl, slidesGrid, snapGrid,
3020  } = swiper;
3021  let e = event;
3022  if (e.originalEvent) e = e.originalEvent;
3023  if (data.allowTouchCallbacks) {
3024    swiper.emit('touchEnd', e);
3025  }
3026  data.allowTouchCallbacks = false;
3027  if (!data.isTouched) {
3028    if (data.isMoved && params.grabCursor) {
3029      swiper.setGrabCursor(false);
3030    }
3031    data.isMoved = false;
3032    data.startMoving = false;
3033    return;
3034  }
3035  // Return Grab Cursor
3036  if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
3037    swiper.setGrabCursor(false);
3038  }
3039
3040  // Time diff
3041  const touchEndTime = Utils.now();
3042  const timeDiff = touchEndTime - data.touchStartTime;
3043
3044  // Tap, doubleTap, Click
3045  if (swiper.allowClick) {
3046    swiper.updateClickedSlide(e);
3047    swiper.emit('tap click', e);
3048    if (timeDiff < 300 && (touchEndTime - data.lastClickTime) < 300) {
3049      swiper.emit('doubleTap doubleClick', e);
3050    }
3051  }
3052
3053  data.lastClickTime = Utils.now();
3054  Utils.nextTick(() => {
3055    if (!swiper.destroyed) swiper.allowClick = true;
3056  });
3057
3058  if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {
3059    data.isTouched = false;
3060    data.isMoved = false;
3061    data.startMoving = false;
3062    return;
3063  }
3064  data.isTouched = false;
3065  data.isMoved = false;
3066  data.startMoving = false;
3067
3068  let currentPos;
3069  if (params.followFinger) {
3070    currentPos = rtl ? swiper.translate : -swiper.translate;
3071  } else {
3072    currentPos = -data.currentTranslate;
3073  }
3074
3075  if (params.cssMode) {
3076    return;
3077  }
3078
3079  if (params.freeMode) {
3080    if (currentPos < -swiper.minTranslate()) {
3081      swiper.slideTo(swiper.activeIndex);
3082      return;
3083    }
3084    if (currentPos > -swiper.maxTranslate()) {
3085      if (swiper.slides.length < snapGrid.length) {
3086        swiper.slideTo(snapGrid.length - 1);
3087      } else {
3088        swiper.slideTo(swiper.slides.length - 1);
3089      }
3090      return;
3091    }
3092
3093    if (params.freeModeMomentum) {
3094      if (data.velocities.length > 1) {
3095        const lastMoveEvent = data.velocities.pop();
3096        const velocityEvent = data.velocities.pop();
3097
3098        const distance = lastMoveEvent.position - velocityEvent.position;
3099        const time = lastMoveEvent.time - velocityEvent.time;
3100        swiper.velocity = distance / time;
3101        swiper.velocity /= 2;
3102        if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) {
3103          swiper.velocity = 0;
3104        }
3105        // this implies that the user stopped moving a finger then released.
3106        // There would be no events with distance zero, so the last event is stale.
3107        if (time > 150 || (Utils.now() - lastMoveEvent.time) > 300) {
3108          swiper.velocity = 0;
3109        }
3110      } else {
3111        swiper.velocity = 0;
3112      }
3113      swiper.velocity *= params.freeModeMomentumVelocityRatio;
3114
3115      data.velocities.length = 0;
3116      let momentumDuration = 1000 * params.freeModeMomentumRatio;
3117      const momentumDistance = swiper.velocity * momentumDuration;
3118
3119      let newPosition = swiper.translate + momentumDistance;
3120      if (rtl) newPosition = -newPosition;
3121
3122      let doBounce = false;
3123      let afterBouncePosition;
3124      const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio;
3125      let needsLoopFix;
3126      if (newPosition < swiper.maxTranslate()) {
3127        if (params.freeModeMomentumBounce) {
3128          if (newPosition + swiper.maxTranslate() < -bounceAmount) {
3129            newPosition = swiper.maxTranslate() - bounceAmount;
3130          }
3131          afterBouncePosition = swiper.maxTranslate();
3132          doBounce = true;
3133          data.allowMomentumBounce = true;
3134        } else {
3135          newPosition = swiper.maxTranslate();
3136        }
3137        if (params.loop && params.centeredSlides) needsLoopFix = true;
3138      } else if (newPosition > swiper.minTranslate()) {
3139        if (params.freeModeMomentumBounce) {
3140          if (newPosition - swiper.minTranslate() > bounceAmount) {
3141            newPosition = swiper.minTranslate() + bounceAmount;
3142          }
3143          afterBouncePosition = swiper.minTranslate();
3144          doBounce = true;
3145          data.allowMomentumBounce = true;
3146        } else {
3147          newPosition = swiper.minTranslate();
3148        }
3149        if (params.loop && params.centeredSlides) needsLoopFix = true;
3150      } else if (params.freeModeSticky) {
3151        let nextSlide;
3152        for (let j = 0; j < snapGrid.length; j += 1) {
3153          if (snapGrid[j] > -newPosition) {
3154            nextSlide = j;
3155            break;
3156          }
3157        }
3158
3159        if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
3160          newPosition = snapGrid[nextSlide];
3161        } else {
3162          newPosition = snapGrid[nextSlide - 1];
3163        }
3164        newPosition = -newPosition;
3165      }
3166      if (needsLoopFix) {
3167        swiper.once('transitionEnd', () => {
3168          swiper.loopFix();
3169        });
3170      }
3171      // Fix duration
3172      if (swiper.velocity !== 0) {
3173        if (rtl) {
3174          momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
3175        } else {
3176          momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
3177        }
3178        if (params.freeModeSticky) {
3179          // If freeModeSticky is active and the user ends a swipe with a slow-velocity
3180          // event, then durations can be 20+ seconds to slide one (or zero!) slides.
3181          // It's easy to see this when simulating touch with mouse events. To fix this,
3182          // limit single-slide swipes to the default slide duration. This also has the
3183          // nice side effect of matching slide speed if the user stopped moving before
3184          // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
3185          // For faster swipes, also apply limits (albeit higher ones).
3186          const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
3187          const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
3188          if (moveDistance < currentSlideSize) {
3189            momentumDuration = params.speed;
3190          } else if (moveDistance < 2 * currentSlideSize) {
3191            momentumDuration = params.speed * 1.5;
3192          } else {
3193            momentumDuration = params.speed * 2.5;
3194          }
3195        }
3196      } else if (params.freeModeSticky) {
3197        swiper.slideToClosest();
3198        return;
3199      }
3200
3201      if (params.freeModeMomentumBounce && doBounce) {
3202        swiper.updateProgress(afterBouncePosition);
3203        swiper.setTransition(momentumDuration);
3204        swiper.setTranslate(newPosition);
3205        swiper.transitionStart(true, swiper.swipeDirection);
3206        swiper.animating = true;
3207        $wrapperEl.transitionEnd(() => {
3208          if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
3209          swiper.emit('momentumBounce');
3210          swiper.setTransition(params.speed);
3211          setTimeout(() => {
3212            swiper.setTranslate(afterBouncePosition);
3213            $wrapperEl.transitionEnd(() => {
3214              if (!swiper || swiper.destroyed) return;
3215              swiper.transitionEnd();
3216            });
3217          }, 0);
3218        });
3219      } else if (swiper.velocity) {
3220        swiper.updateProgress(newPosition);
3221        swiper.setTransition(momentumDuration);
3222        swiper.setTranslate(newPosition);
3223        swiper.transitionStart(true, swiper.swipeDirection);
3224        if (!swiper.animating) {
3225          swiper.animating = true;
3226          $wrapperEl.transitionEnd(() => {
3227            if (!swiper || swiper.destroyed) return;
3228            swiper.transitionEnd();
3229          });
3230        }
3231      } else {
3232        swiper.updateProgress(newPosition);
3233      }
3234
3235      swiper.updateActiveIndex();
3236      swiper.updateSlidesClasses();
3237    } else if (params.freeModeSticky) {
3238      swiper.slideToClosest();
3239      return;
3240    }
3241
3242    if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) {
3243      swiper.updateProgress();
3244      swiper.updateActiveIndex();
3245      swiper.updateSlidesClasses();
3246    }
3247    return;
3248  }
3249
3250  // Find current slide
3251  let stopIndex = 0;
3252  let groupSize = swiper.slidesSizesGrid[0];
3253  for (let i = 0; i < slidesGrid.length; i += (i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup)) {
3254    const increment = (i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup);
3255    if (typeof slidesGrid[i + increment] !== 'undefined') {
3256      if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
3257        stopIndex = i;
3258        groupSize = slidesGrid[i + increment] - slidesGrid[i];
3259      }
3260    } else if (currentPos >= slidesGrid[i]) {
3261      stopIndex = i;
3262      groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
3263    }
3264  }
3265
3266  // Find current slide size
3267  const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
3268  const increment = (stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup);
3269
3270  if (timeDiff > params.longSwipesMs) {
3271    // Long touches
3272    if (!params.longSwipes) {
3273      swiper.slideTo(swiper.activeIndex);
3274      return;
3275    }
3276    if (swiper.swipeDirection === 'next') {
3277      if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + increment);
3278      else swiper.slideTo(stopIndex);
3279    }
3280    if (swiper.swipeDirection === 'prev') {
3281      if (ratio > (1 - params.longSwipesRatio)) swiper.slideTo(stopIndex + increment);
3282      else swiper.slideTo(stopIndex);
3283    }
3284  } else {
3285    // Short swipes
3286    if (!params.shortSwipes) {
3287      swiper.slideTo(swiper.activeIndex);
3288      return;
3289    }
3290    const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
3291    if (!isNavButtonTarget) {
3292      if (swiper.swipeDirection === 'next') {
3293        swiper.slideTo(stopIndex + increment);
3294      }
3295      if (swiper.swipeDirection === 'prev') {
3296        swiper.slideTo(stopIndex);
3297      }
3298    } else if (e.target === swiper.navigation.nextEl) {
3299      swiper.slideTo(stopIndex + increment);
3300    } else {
3301      swiper.slideTo(stopIndex);
3302    }
3303  }
3304}
3305
3306function onResize () {
3307  const swiper = this;
3308
3309  const { params, el } = swiper;
3310
3311  if (el && el.offsetWidth === 0) return;
3312
vendor: 21,604 bytes, lines 3313-4050
3313  // Breakpoints
3314  if (params.breakpoints) {
3315    swiper.setBreakpoint();
3316  }
3317
3318  // Save locks
3319  const { allowSlideNext, allowSlidePrev, snapGrid } = swiper;
3320
3321  // Disable locks on resize
3322  swiper.allowSlideNext = true;
3323  swiper.allowSlidePrev = true;
3324
3325  swiper.updateSize();
3326  swiper.updateSlides();
3327
3328  swiper.updateSlidesClasses();
3329  if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
3330    swiper.slideTo(swiper.slides.length - 1, 0, false, true);
3331  } else {
3332    swiper.slideTo(swiper.activeIndex, 0, false, true);
3333  }
3334
3335  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3336    swiper.autoplay.run();
3337  }
3338  // Return locks after resize
3339  swiper.allowSlidePrev = allowSlidePrev;
3340  swiper.allowSlideNext = allowSlideNext;
3341
3342  if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
3343    swiper.checkOverflow();
3344  }
3345}
3346
3347function onClick (e) {
3348  const swiper = this;
3349  if (!swiper.allowClick) {
3350    if (swiper.params.preventClicks) e.preventDefault();
3351    if (swiper.params.preventClicksPropagation && swiper.animating) {
3352      e.stopPropagation();
3353      e.stopImmediatePropagation();
3354    }
3355  }
3356}
3357
3358function onScroll () {
3359  const swiper = this;
3360  const { wrapperEl, rtlTranslate } = swiper;
3361  swiper.previousTranslate = swiper.translate;
3362  if (swiper.isHorizontal()) {
3363    if (rtlTranslate) {
3364      swiper.translate = ((wrapperEl.scrollWidth - wrapperEl.offsetWidth) - wrapperEl.scrollLeft);
3365    } else {
3366      swiper.translate = -wrapperEl.scrollLeft;
3367    }
3368  } else {
3369    swiper.translate = -wrapperEl.scrollTop;
3370  }
3371  // eslint-disable-next-line
3372  if (swiper.translate === -0) swiper.translate = 0;
3373
3374  swiper.updateActiveIndex();
3375  swiper.updateSlidesClasses();
3376
3377  let newProgress;
3378  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
3379  if (translatesDiff === 0) {
3380    newProgress = 0;
3381  } else {
3382    newProgress = (swiper.translate - swiper.minTranslate()) / (translatesDiff);
3383  }
3384  if (newProgress !== swiper.progress) {
3385    swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
3386  }
3387
3388  swiper.emit('setTranslate', swiper.translate, false);
3389}
3390
3391let dummyEventAttached = false;
3392function dummyEventListener() {}
3393
3394function attachEvents() {
3395  const swiper = this;
3396  const {
3397    params, touchEvents, el, wrapperEl,
3398  } = swiper;
3399
3400  swiper.onTouchStart = onTouchStart.bind(swiper);
3401  swiper.onTouchMove = onTouchMove.bind(swiper);
3402  swiper.onTouchEnd = onTouchEnd.bind(swiper);
3403  if (params.cssMode) {
3404    swiper.onScroll = onScroll.bind(swiper);
3405  }
3406
3407  swiper.onClick = onClick.bind(swiper);
3408
3409  const capture = !!params.nested;
3410
3411  // Touch Events
3412  if (!Support.touch && Support.pointerEvents) {
3413    el.addEventListener(touchEvents.start, swiper.onTouchStart, false);
3414    doc.addEventListener(touchEvents.move, swiper.onTouchMove, capture);
3415    doc.addEventListener(touchEvents.end, swiper.onTouchEnd, false);
3416  } else {
3417    if (Support.touch) {
3418      const passiveListener = touchEvents.start === 'touchstart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;
3419      el.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);
3420      el.addEventListener(touchEvents.move, swiper.onTouchMove, Support.passiveListener ? { passive: false, capture } : capture);
3421      el.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);
3422      if (touchEvents.cancel) {
3423        el.addEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);
3424      }
3425      if (!dummyEventAttached) {
3426        doc.addEventListener('touchstart', dummyEventListener);
3427        dummyEventAttached = true;
3428      }
3429    }
3430    if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) {
3431      el.addEventListener('mousedown', swiper.onTouchStart, false);
3432      doc.addEventListener('mousemove', swiper.onTouchMove, capture);
3433      doc.addEventListener('mouseup', swiper.onTouchEnd, false);
3434    }
3435  }
3436  // Prevent Links Clicks
3437  if (params.preventClicks || params.preventClicksPropagation) {
3438    el.addEventListener('click', swiper.onClick, true);
3439  }
3440  if (params.cssMode) {
3441    wrapperEl.addEventListener('scroll', swiper.onScroll);
3442  }
3443
3444  // Resize handler
3445  if (params.updateOnWindowResize) {
3446    swiper.on((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize, true);
3447  } else {
3448    swiper.on('observerUpdate', onResize, true);
3449  }
3450}
3451
3452function detachEvents() {
3453  const swiper = this;
3454
3455  const {
3456    params, touchEvents, el, wrapperEl,
3457  } = swiper;
3458
3459  const capture = !!params.nested;
3460
3461  // Touch Events
3462  if (!Support.touch && Support.pointerEvents) {
3463    el.removeEventListener(touchEvents.start, swiper.onTouchStart, false);
3464    doc.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);
3465    doc.removeEventListener(touchEvents.end, swiper.onTouchEnd, false);
3466  } else {
3467    if (Support.touch) {
3468      const passiveListener = touchEvents.start === 'onTouchStart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;
3469      el.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);
3470      el.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);
3471      el.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);
3472      if (touchEvents.cancel) {
3473        el.removeEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);
3474      }
3475    }
3476    if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) {
3477      el.removeEventListener('mousedown', swiper.onTouchStart, false);
3478      doc.removeEventListener('mousemove', swiper.onTouchMove, capture);
3479      doc.removeEventListener('mouseup', swiper.onTouchEnd, false);
3480    }
3481  }
3482  // Prevent Links Clicks
3483  if (params.preventClicks || params.preventClicksPropagation) {
3484    el.removeEventListener('click', swiper.onClick, true);
3485  }
3486
3487  if (params.cssMode) {
3488    wrapperEl.removeEventListener('scroll', swiper.onScroll);
3489  }
3490
3491  // Resize handler
3492  swiper.off((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize);
3493}
3494
3495var events = {
3496  attachEvents,
3497  detachEvents,
3498};
3499
3500function setBreakpoint () {
3501  const swiper = this;
3502  const {
3503    activeIndex, initialized, loopedSlides = 0, params, $el,
3504  } = swiper;
3505  const breakpoints = params.breakpoints;
3506  if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) return;
3507
3508  // Get breakpoint for window width and update parameters
3509  const breakpoint = swiper.getBreakpoint(breakpoints);
3510
3511  if (breakpoint && swiper.currentBreakpoint !== breakpoint) {
3512    const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3513    if (breakpointOnlyParams) {
3514      ['slidesPerView', 'spaceBetween', 'slidesPerGroup', 'slidesPerGroupSkip', 'slidesPerColumn'].forEach((param) => {
3515        const paramValue = breakpointOnlyParams[param];
3516        if (typeof paramValue === 'undefined') return;
3517        if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) {
3518          breakpointOnlyParams[param] = 'auto';
3519        } else if (param === 'slidesPerView') {
3520          breakpointOnlyParams[param] = parseFloat(paramValue);
3521        } else {
3522          breakpointOnlyParams[param] = parseInt(paramValue, 10);
3523        }
3524      });
3525    }
3526
3527    const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3528    const wasMultiRow = params.slidesPerColumn > 1;
3529    const isMultiRow = breakpointParams.slidesPerColumn > 1;
3530    if (wasMultiRow && !isMultiRow) {
3531      $el.removeClass(`${params.containerModifierClass}multirow ${params.containerModifierClass}multirow-column`);
3532    } else if (!wasMultiRow && isMultiRow) {
3533      $el.addClass(`${params.containerModifierClass}multirow`);
3534      if (breakpointParams.slidesPerColumnFill === 'column') {
3535        $el.addClass(`${params.containerModifierClass}multirow-column`);
3536      }
3537    }
3538
3539    const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3540    const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
3541
3542    if (directionChanged && initialized) {
3543      swiper.changeDirection();
3544    }
3545
3546    Utils.extend(swiper.params, breakpointParams);
3547
3548    Utils.extend(swiper, {
3549      allowTouchMove: swiper.params.allowTouchMove,
3550      allowSlideNext: swiper.params.allowSlideNext,
3551      allowSlidePrev: swiper.params.allowSlidePrev,
3552    });
3553
3554    swiper.currentBreakpoint = breakpoint;
3555
3556    if (needsReLoop && initialized) {
3557      swiper.loopDestroy();
3558      swiper.loopCreate();
3559      swiper.updateSlides();
3560      swiper.slideTo((activeIndex - loopedSlides) + swiper.loopedSlides, 0, false);
3561    }
3562
3563    swiper.emit('breakpoint', breakpointParams);
3564  }
3565}
3566
3567function getBreakpoint (breakpoints) {
3568  // Get breakpoint for window width
3569  if (!breakpoints) return undefined;
3570  let breakpoint = false;
3571
3572  const points = Object.keys(breakpoints).map((point) => {
3573    if (typeof point === 'string' && point.indexOf('@') === 0) {
3574      const minRatio = parseFloat(point.substr(1));
3575      const value = win.innerHeight * minRatio;
3576      return { value, point };
3577    }
3578    return { value: point, point };
3579  });
3580
3581  points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
3582  for (let i = 0; i < points.length; i += 1) {
3583    const { point, value } = points[i];
3584    if (value <= win.innerWidth) {
3585      breakpoint = point;
3586    }
3587  }
3588  return breakpoint || 'max';
3589}
3590
3591var breakpoints = { setBreakpoint, getBreakpoint };
3592
3593function addClasses () {
3594  const swiper = this;
3595  const {
3596    classNames, params, rtl, $el,
3597  } = swiper;
3598  const suffixes = [];
3599
3600  suffixes.push('initialized');
3601  suffixes.push(params.direction);
3602
3603  if (params.freeMode) {
3604    suffixes.push('free-mode');
3605  }
3606  if (params.autoHeight) {
3607    suffixes.push('autoheight');
3608  }
3609  if (rtl) {
3610    suffixes.push('rtl');
3611  }
3612  if (params.slidesPerColumn > 1) {
3613    suffixes.push('multirow');
3614    if (params.slidesPerColumnFill === 'column') {
3615      suffixes.push('multirow-column');
3616    }
3617  }
3618  if (Device.android) {
3619    suffixes.push('android');
3620  }
3621  if (Device.ios) {
3622    suffixes.push('ios');
3623  }
3624
3625  if (params.cssMode) {
3626    suffixes.push('css-mode');
3627  }
3628
3629  suffixes.forEach((suffix) => {
3630    classNames.push(params.containerModifierClass + suffix);
3631  });
3632
3633  $el.addClass(classNames.join(' '));
3634}
3635
3636function removeClasses () {
3637  const swiper = this;
3638  const { $el, classNames } = swiper;
3639
3640  $el.removeClass(classNames.join(' '));
3641}
3642
3643var classes = { addClasses, removeClasses };
3644
3645function loadImage (imageEl, src, srcset, sizes, checkForComplete, callback) {
3646  let image;
3647  function onReady() {
3648    if (callback) callback();
3649  }
3650  const isPicture = $(imageEl).parent('picture')[0];
3651
3652  if (!isPicture && (!imageEl.complete || !checkForComplete)) {
3653    if (src) {
3654      image = new win.Image();
3655      image.onload = onReady;
3656      image.onerror = onReady;
3657      if (sizes) {
3658        image.sizes = sizes;
3659      }
3660      if (srcset) {
3661        image.srcset = srcset;
3662      }
3663      if (src) {
3664        image.src = src;
3665      }
3666    } else {
3667      onReady();
3668    }
3669  } else {
3670    // image already loaded...
3671    onReady();
3672  }
3673}
3674
3675function preloadImages () {
3676  const swiper = this;
3677  swiper.imagesToLoad = swiper.$el.find('img');
3678  function onReady() {
3679    if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return;
3680    if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1;
3681    if (swiper.imagesLoaded === swiper.imagesToLoad.length) {
3682      if (swiper.params.updateOnImagesReady) swiper.update();
3683      swiper.emit('imagesReady');
3684    }
3685  }
3686  for (let i = 0; i < swiper.imagesToLoad.length; i += 1) {
3687    const imageEl = swiper.imagesToLoad[i];
3688    swiper.loadImage(
3689      imageEl,
3690      imageEl.currentSrc || imageEl.getAttribute('src'),
3691      imageEl.srcset || imageEl.getAttribute('srcset'),
3692      imageEl.sizes || imageEl.getAttribute('sizes'),
3693      true,
3694      onReady
3695    );
3696  }
3697}
3698
3699var images = {
3700  loadImage,
3701  preloadImages,
3702};
3703
3704function checkOverflow() {
3705  const swiper = this;
3706  const params = swiper.params;
3707  const wasLocked = swiper.isLocked;
3708  const lastSlidePosition = swiper.slides.length > 0 && (params.slidesOffsetBefore + (params.spaceBetween * (swiper.slides.length - 1)) + ((swiper.slides[0]).offsetWidth) * swiper.slides.length);
3709
3710  if (params.slidesOffsetBefore && params.slidesOffsetAfter && lastSlidePosition) {
3711    swiper.isLocked = lastSlidePosition <= swiper.size;
3712  } else {
3713    swiper.isLocked = swiper.snapGrid.length === 1;
3714  }
3715
3716  swiper.allowSlideNext = !swiper.isLocked;
3717  swiper.allowSlidePrev = !swiper.isLocked;
3718
3719  // events
3720  if (wasLocked !== swiper.isLocked) swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
3721
3722  if (wasLocked && wasLocked !== swiper.isLocked) {
3723    swiper.isEnd = false;
3724    swiper.navigation.update();
3725  }
3726}
3727
3728var checkOverflow$1 = { checkOverflow };
3729
3730var defaults = {
3731  init: true,
3732  direction: 'horizontal',
3733  touchEventsTarget: 'container',
3734  initialSlide: 0,
3735  speed: 300,
3736  cssMode: false,
3737  updateOnWindowResize: true,
3738  //
3739  preventInteractionOnTransition: false,
3740
3741  // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
3742  edgeSwipeDetection: false,
3743  edgeSwipeThreshold: 20,
3744
3745  // Free mode
3746  freeMode: false,
3747  freeModeMomentum: true,
3748  freeModeMomentumRatio: 1,
3749  freeModeMomentumBounce: true,
3750  freeModeMomentumBounceRatio: 1,
3751  freeModeMomentumVelocityRatio: 1,
3752  freeModeSticky: false,
3753  freeModeMinimumVelocity: 0.02,
3754
3755  // Autoheight
3756  autoHeight: false,
3757
3758  // Set wrapper width
3759  setWrapperSize: false,
3760
3761  // Virtual Translate
3762  virtualTranslate: false,
3763
3764  // Effects
3765  effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3766
3767  // Breakpoints
3768  breakpoints: undefined,
3769
3770  // Slides grid
3771  spaceBetween: 0,
3772  slidesPerView: 1,
3773  slidesPerColumn: 1,
3774  slidesPerColumnFill: 'column',
3775  slidesPerGroup: 1,
3776  slidesPerGroupSkip: 0,
3777  centeredSlides: false,
3778  centeredSlidesBounds: false,
3779  slidesOffsetBefore: 0, // in px
3780  slidesOffsetAfter: 0, // in px
3781  normalizeSlideIndex: true,
3782  centerInsufficientSlides: false,
3783
3784  // Disable swiper and hide navigation when container not overflow
3785  watchOverflow: false,
3786
3787  // Round length
3788  roundLengths: false,
3789
3790  // Touches
3791  touchRatio: 1,
3792  touchAngle: 45,
3793  simulateTouch: true,
3794  shortSwipes: true,
3795  longSwipes: true,
3796  longSwipesRatio: 0.5,
3797  longSwipesMs: 300,
3798  followFinger: true,
3799  allowTouchMove: true,
3800  threshold: 0,
3801  touchMoveStopPropagation: false,
3802  touchStartPreventDefault: true,
3803  touchStartForcePreventDefault: false,
3804  touchReleaseOnEdges: false,
3805
3806  // Unique Navigation Elements
3807  uniqueNavElements: true,
3808
3809  // Resistance
3810  resistance: true,
3811  resistanceRatio: 0.85,
3812
3813  // Progress
3814  watchSlidesProgress: false,
3815  watchSlidesVisibility: false,
3816
3817  // Cursor
3818  grabCursor: false,
3819
3820  // Clicks
3821  preventClicks: true,
3822  preventClicksPropagation: true,
3823  slideToClickedSlide: false,
3824
3825  // Images
3826  preloadImages: true,
3827  updateOnImagesReady: true,
3828
3829  // loop
3830  loop: false,
3831  loopAdditionalSlides: 0,
3832  loopedSlides: null,
3833  loopFillGroupWithBlank: false,
3834
3835  // Swiping/no swiping
3836  allowSlidePrev: true,
3837  allowSlideNext: true,
3838  swipeHandler: null, // '.swipe-handler',
3839  noSwiping: true,
3840  noSwipingClass: 'swiper-no-swiping',
3841  noSwipingSelector: null,
3842
3843  // Passive Listeners
3844  passiveListeners: true,
3845
3846  // NS
3847  containerModifierClass: 'swiper-container-', // NEW
3848  slideClass: 'swiper-slide',
3849  slideBlankClass: 'swiper-slide-invisible-blank',
3850  slideActiveClass: 'swiper-slide-active',
3851  slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
3852  slideVisibleClass: 'swiper-slide-visible',
3853  slideDuplicateClass: 'swiper-slide-duplicate',
3854  slideNextClass: 'swiper-slide-next',
3855  slideDuplicateNextClass: 'swiper-slide-duplicate-next',
3856  slidePrevClass: 'swiper-slide-prev',
3857  slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
3858  wrapperClass: 'swiper-wrapper',
3859
3860  // Callbacks
3861  runCallbacksOnInit: true,
3862};
3863
3864/* eslint no-param-reassign: "off" */
3865
3866const prototypes = {
3867  update,
3868  translate,
3869  transition: transition$1,
3870  slide,
3871  loop,
3872  grabCursor,
3873  manipulation,
3874  events,
3875  breakpoints,
3876  checkOverflow: checkOverflow$1,
3877  classes,
3878  images,
3879};
3880
3881const extendedDefaults = {};
3882
3883class Swiper extends SwiperClass {
3884  constructor(...args) {
3885    let el;
3886    let params;
3887    if (args.length === 1 && args[0].constructor && args[0].constructor === Object) {
3888      params = args[0];
3889    } else {
3890      [el, params] = args;
3891    }
3892    if (!params) params = {};
3893
3894    params = Utils.extend({}, params);
3895    if (el && !params.el) params.el = el;
3896
3897    super(params);
3898
3899    Object.keys(prototypes).forEach((prototypeGroup) => {
3900      Object.keys(prototypes[prototypeGroup]).forEach((protoMethod) => {
3901        if (!Swiper.prototype[protoMethod]) {
3902          Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
3903        }
3904      });
3905    });
3906
3907    // Swiper Instance
3908    const swiper = this;
3909    if (typeof swiper.modules === 'undefined') {
3910      swiper.modules = {};
3911    }
3912    Object.keys(swiper.modules).forEach((moduleName) => {
3913      const module = swiper.modules[moduleName];
3914      if (module.params) {
3915        const moduleParamName = Object.keys(module.params)[0];
3916        const moduleParams = module.params[moduleParamName];
3917        if (typeof moduleParams !== 'object' || moduleParams === null) return;
3918        if (!(moduleParamName in params && 'enabled' in moduleParams)) return;
3919        if (params[moduleParamName] === true) {
3920          params[moduleParamName] = { enabled: true };
3921        }
3922        if (
3923          typeof params[moduleParamName] === 'object'
3924          && !('enabled' in params[moduleParamName])
3925        ) {
3926          params[moduleParamName].enabled = true;
3927        }
3928        if (!params[moduleParamName]) params[moduleParamName] = { enabled: false };
3929      }
3930    });
3931
3932    // Extend defaults with modules params
3933    const swiperParams = Utils.extend({}, defaults);
3934    swiper.useModulesParams(swiperParams);
3935
3936    // Extend defaults with passed params
3937    swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params);
3938    swiper.originalParams = Utils.extend({}, swiper.params);
3939    swiper.passedParams = Utils.extend({}, params);
3940
3941    // Save Dom lib
3942    swiper.$ = $;
3943
3944    // Find el
3945    const $el = $(swiper.params.el);
3946    el = $el[0];
3947
3948    if (!el) {
3949      return undefined;
3950    }
3951
3952    if ($el.length > 1) {
3953      const swipers = [];
3954      $el.each((index, containerEl) => {
3955        const newParams = Utils.extend({}, params, { el: containerEl });
3956        swipers.push(new Swiper(newParams));
3957      });
3958      return swipers;
3959    }
3960
3961    el.swiper = swiper;
3962    $el.data('swiper', swiper);
3963
3964    // Find Wrapper
3965    let $wrapperEl;
3966    if (el && el.shadowRoot && el.shadowRoot.querySelector) {
3967      $wrapperEl = $(el.shadowRoot.querySelector(`.${swiper.params.wrapperClass}`));
3968      // Children needs to return slot items
3969      $wrapperEl.children = (options) => $el.children(options);
3970    } else {
3971      $wrapperEl = $el.children(`.${swiper.params.wrapperClass}`);
3972    }
3973    // Extend Swiper
3974    Utils.extend(swiper, {
3975      $el,
3976      el,
3977      $wrapperEl,
3978      wrapperEl: $wrapperEl[0],
3979
3980      // Classes
3981      classNames: [],
3982
3983      // Slides
3984      slides: $(),
3985      slidesGrid: [],
3986      snapGrid: [],
3987      slidesSizesGrid: [],
3988
3989      // isDirection
3990      isHorizontal() {
3991        return swiper.params.direction === 'horizontal';
3992      },
3993      isVertical() {
3994        return swiper.params.direction === 'vertical';
3995      },
3996      // RTL
3997      rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
3998      rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
3999      wrongRTL: $wrapperEl.css('display') === '-webkit-box',
4000
4001      // Indexes
4002      activeIndex: 0,
4003      realIndex: 0,
4004
4005      //
4006      isBeginning: true,
4007      isEnd: false,
4008
4009      // Props
4010      translate: 0,
4011      previousTranslate: 0,
4012      progress: 0,
4013      velocity: 0,
4014      animating: false,
4015
4016      // Locks
4017      allowSlideNext: swiper.params.allowSlideNext,
4018      allowSlidePrev: swiper.params.allowSlidePrev,
4019
4020      // Touch Events
4021      touchEvents: (function touchEvents() {
4022        const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
4023        let desktop = ['mousedown', 'mousemove', 'mouseup'];
4024        if (Support.pointerEvents) {
4025          desktop = ['pointerdown', 'pointermove', 'pointerup'];
4026        }
4027        swiper.touchEventsTouch = {
4028          start: touch[0],
4029          move: touch[1],
4030          end: touch[2],
4031          cancel: touch[3],
4032        };
4033        swiper.touchEventsDesktop = {
4034          start: desktop[0],
4035          move: desktop[1],
4036          end: desktop[2],
4037        };
4038        return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;
4039      }()),
4040      touchEventsData: {
4041        isTouched: undefined,
4042        isMoved: undefined,
4043        allowTouchCallbacks: undefined,
4044        touchStartTime: undefined,
4045        isScrolling: undefined,
4046        currentTranslate: undefined,
4047        startTranslate: undefined,
4048        allowThresholdMove: undefined,
4049        // Form elements to match
4050        formElements: 'input, select, option, textarea, button, video, label
vendor: 10,881 bytes, lines 4050-4497
4050',
4051        // Last click time
4052        lastClickTime: Utils.now(),
4053        clickTimeout: undefined,
4054        // Velocities
4055        velocities: [],
4056        allowMomentumBounce: undefined,
4057        isTouchEvent: undefined,
4058        startMoving: undefined,
4059      },
4060
4061      // Clicks
4062      allowClick: true,
4063
4064      // Touches
4065      allowTouchMove: swiper.params.allowTouchMove,
4066
4067      touches: {
4068        startX: 0,
4069        startY: 0,
4070        currentX: 0,
4071        currentY: 0,
4072        diff: 0,
4073      },
4074
4075      // Images
4076      imagesToLoad: [],
4077      imagesLoaded: 0,
4078
4079    });
4080
4081    // Install Modules
4082    swiper.useModules();
4083
4084    // Init
4085    if (swiper.params.init) {
4086      swiper.init();
4087    }
4088
4089    // Return app instance
4090    return swiper;
4091  }
4092
4093  slidesPerViewDynamic() {
4094    const swiper = this;
4095    const {
4096      params, slides, slidesGrid, size: swiperSize, activeIndex,
4097    } = swiper;
4098    let spv = 1;
4099    if (params.centeredSlides) {
4100      let slideSize = slides[activeIndex].swiperSlideSize;
4101      let breakLoop;
4102      for (let i = activeIndex + 1; i < slides.length; i += 1) {
4103        if (slides[i] && !breakLoop) {
4104          slideSize += slides[i].swiperSlideSize;
4105          spv += 1;
4106          if (slideSize > swiperSize) breakLoop = true;
4107        }
4108      }
4109      for (let i = activeIndex - 1; i >= 0; i -= 1) {
4110        if (slides[i] && !breakLoop) {
4111          slideSize += slides[i].swiperSlideSize;
4112          spv += 1;
4113          if (slideSize > swiperSize) breakLoop = true;
4114        }
4115      }
4116    } else {
4117      for (let i = activeIndex + 1; i < slides.length; i += 1) {
4118        if (slidesGrid[i] - slidesGrid[activeIndex] < swiperSize) {
4119          spv += 1;
4120        }
4121      }
4122    }
4123    return spv;
4124  }
4125
4126  update() {
4127    const swiper = this;
4128    if (!swiper || swiper.destroyed) return;
4129    const { snapGrid, params } = swiper;
4130    // Breakpoints
4131    if (params.breakpoints) {
4132      swiper.setBreakpoint();
4133    }
4134    swiper.updateSize();
4135    swiper.updateSlides();
4136    swiper.updateProgress();
4137    swiper.updateSlidesClasses();
4138
4139    function setTranslate() {
4140      const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
4141      const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
4142      swiper.setTranslate(newTranslate);
4143      swiper.updateActiveIndex();
4144      swiper.updateSlidesClasses();
4145    }
4146    let translated;
4147    if (swiper.params.freeMode) {
4148      setTranslate();
4149      if (swiper.params.autoHeight) {
4150        swiper.updateAutoHeight();
4151      }
4152    } else {
4153      if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
4154        translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
4155      } else {
4156        translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4157      }
4158      if (!translated) {
4159        setTranslate();
4160      }
4161    }
4162    if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
4163      swiper.checkOverflow();
4164    }
4165    swiper.emit('update');
4166  }
4167
4168  changeDirection(newDirection, needUpdate = true) {
4169    const swiper = this;
4170    const currentDirection = swiper.params.direction;
4171    if (!newDirection) {
4172      // eslint-disable-next-line
4173      newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
4174    }
4175    if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) {
4176      return swiper;
4177    }
4178
4179    swiper.$el
4180      .removeClass(`${swiper.params.containerModifierClass}${currentDirection}`)
4181      .addClass(`${swiper.params.containerModifierClass}${newDirection}`);
4182
4183    swiper.params.direction = newDirection;
4184
4185    swiper.slides.each((slideIndex, slideEl) => {
4186      if (newDirection === 'vertical') {
4187        slideEl.style.width = '';
4188      } else {
4189        slideEl.style.height = '';
4190      }
4191    });
4192
4193    swiper.emit('changeDirection');
4194    if (needUpdate) swiper.update();
4195
4196    return swiper;
4197  }
4198
4199  init() {
4200    const swiper = this;
4201    if (swiper.initialized) return;
4202
4203    swiper.emit('beforeInit');
4204
4205    // Set breakpoint
4206    if (swiper.params.breakpoints) {
4207      swiper.setBreakpoint();
4208    }
4209
4210    // Add Classes
4211    swiper.addClasses();
4212
4213    // Create loop
4214    if (swiper.params.loop) {
4215      swiper.loopCreate();
4216    }
4217
4218    // Update size
4219    swiper.updateSize();
4220
4221    // Update slides
4222    swiper.updateSlides();
4223
4224    if (swiper.params.watchOverflow) {
4225      swiper.checkOverflow();
4226    }
4227
4228    // Set Grab Cursor
4229    if (swiper.params.grabCursor) {
4230      swiper.setGrabCursor();
4231    }
4232
4233    if (swiper.params.preloadImages) {
4234      swiper.preloadImages();
4235    }
4236
4237    // Slide To Initial Slide
4238    if (swiper.params.loop) {
4239      swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit);
4240    } else {
4241      swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit);
4242    }
4243
4244    // Attach events
4245    swiper.attachEvents();
4246
4247    // Init Flag
4248    swiper.initialized = true;
4249
4250    // Emit
4251    swiper.emit('init');
4252  }
4253
4254  destroy(deleteInstance = true, cleanStyles = true) {
4255    const swiper = this;
4256    const {
4257      params, $el, $wrapperEl, slides,
4258    } = swiper;
4259
4260    if (typeof swiper.params === 'undefined' || swiper.destroyed) {
4261      return null;
4262    }
4263
4264    swiper.emit('beforeDestroy');
4265
4266    // Init Flag
4267    swiper.initialized = false;
4268
4269    // Detach events
4270    swiper.detachEvents();
4271
4272    // Destroy loop
4273    if (params.loop) {
4274      swiper.loopDestroy();
4275    }
4276
4277    // Cleanup styles
4278    if (cleanStyles) {
4279      swiper.removeClasses();
4280      $el.removeAttr('style');
4281      $wrapperEl.removeAttr('style');
4282      if (slides && slides.length) {
4283        slides
4284          .removeClass([
4285            params.slideVisibleClass,
4286            params.slideActiveClass,
4287            params.slideNextClass,
4288            params.slidePrevClass,
4289          ].join(' '))
4290          .removeAttr('style')
4291          .removeAttr('data-swiper-slide-index');
4292      }
4293    }
4294
4295    swiper.emit('destroy');
4296
4297    // Detach emitter events
4298    Object.keys(swiper.eventsListeners).forEach((eventName) => {
4299      swiper.off(eventName);
4300    });
4301
4302    if (deleteInstance !== false) {
4303      swiper.$el[0].swiper = null;
4304      swiper.$el.data('swiper', null);
4305      Utils.deleteProps(swiper);
4306    }
4307    swiper.destroyed = true;
4308
4309    return null;
4310  }
4311
4312  static extendDefaults(newDefaults) {
4313    Utils.extend(extendedDefaults, newDefaults);
4314  }
4315
4316  static get extendedDefaults() {
4317    return extendedDefaults;
4318  }
4319
4320  static get defaults() {
4321    return defaults;
4322  }
4323
4324  static get Class() {
4325    return SwiperClass;
4326  }
4327
4328  static get $() {
4329    return $;
4330  }
4331}
4332
4333var Device$1 = {
4334  name: 'device',
4335  proto: {
4336    device: Device,
4337  },
4338  static: {
4339    device: Device,
4340  },
4341};
4342
4343var Support$1 = {
4344  name: 'support',
4345  proto: {
4346    support: Support,
4347  },
4348  static: {
4349    support: Support,
4350  },
4351};
4352
4353const Browser = (function Browser() {
4354  function isSafari() {
4355    const ua = win.navigator.userAgent.toLowerCase();
4356    return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
4357  }
4358  return {
4359    isEdge: !!win.navigator.userAgent.match(/Edge/g),
4360    isSafari: isSafari(),
4361    isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(win.navigator.userAgent),
4362  };
4363}());
4364
4365var Browser$1 = {
4366  name: 'browser',
4367  proto: {
4368    browser: Browser,
4369  },
4370  static: {
4371    browser: Browser,
4372  },
4373};
4374
4375var Resize = {
4376  name: 'resize',
4377  create() {
4378    const swiper = this;
4379    Utils.extend(swiper, {
4380      resize: {
4381        resizeHandler() {
4382          if (!swiper || swiper.destroyed || !swiper.initialized) return;
4383          swiper.emit('beforeResize');
4384          swiper.emit('resize');
4385        },
4386        orientationChangeHandler() {
4387          if (!swiper || swiper.destroyed || !swiper.initialized) return;
4388          swiper.emit('orientationchange');
4389        },
4390      },
4391    });
4392  },
4393  on: {
4394    init() {
4395      const swiper = this;
4396      // Emit resize
4397      win.addEventListener('resize', swiper.resize.resizeHandler);
4398
4399      // Emit orientationchange
4400      win.addEventListener('orientationchange', swiper.resize.orientationChangeHandler);
4401    },
4402    destroy() {
4403      const swiper = this;
4404      win.removeEventListener('resize', swiper.resize.resizeHandler);
4405      win.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler);
4406    },
4407  },
4408};
4409
4410const Observer = {
4411  func: win.MutationObserver || win.WebkitMutationObserver,
4412  attach(target, options = {}) {
4413    const swiper = this;
4414
4415    const ObserverFunc = Observer.func;
4416    const observer = new ObserverFunc((mutations) => {
4417      // The observerUpdate event should only be triggered
4418      // once despite the number of mutations.  Additional
4419      // triggers are redundant and are very costly
4420      if (mutations.length === 1) {
4421        swiper.emit('observerUpdate', mutations[0]);
4422        return;
4423      }
4424      const observerUpdate = function observerUpdate() {
4425        swiper.emit('observerUpdate', mutations[0]);
4426      };
4427
4428      if (win.requestAnimationFrame) {
4429        win.requestAnimationFrame(observerUpdate);
4430      } else {
4431        win.setTimeout(observerUpdate, 0);
4432      }
4433    });
4434
4435    observer.observe(target, {
4436      attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
4437      childList: typeof options.childList === 'undefined' ? true : options.childList,
4438      characterData: typeof options.characterData === 'undefined' ? true : options.characterData,
4439    });
4440
4441    swiper.observer.observers.push(observer);
4442  },
4443  init() {
4444    const swiper = this;
4445    if (!Support.observer || !swiper.params.observer) return;
4446    if (swiper.params.observeParents) {
4447      const containerParents = swiper.$el.parents();
4448      for (let i = 0; i < containerParents.length; i += 1) {
4449        swiper.observer.attach(containerParents[i]);
4450      }
4451    }
4452    // Observe container
4453    swiper.observer.attach(swiper.$el[0], { childList: swiper.params.observeSlideChildren });
4454
4455    // Observe wrapper
4456    swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false });
4457  },
4458  destroy() {
4459    const swiper = this;
4460    swiper.observer.observers.forEach((observer) => {
4461      observer.disconnect();
4462    });
4463    swiper.observer.observers = [];
4464  },
4465};
4466
4467var Observer$1 = {
4468  name: 'observer',
4469  params: {
4470    observer: false,
4471    observeParents: false,
4472    observeSlideChildren: false,
4473  },
4474  create() {
4475    const swiper = this;
4476    Utils.extend(swiper, {
4477      observer: {
4478        init: Observer.init.bind(swiper),
4479        attach: Observer.attach.bind(swiper),
4480        destroy: Observer.destroy.bind(swiper),
4481        observers: [],
4482      },
4483    });
4484  },
4485  on: {
4486    init() {
4487      const swiper = this;
4488      swiper.observer.init();
4489    },
4490    destroy() {
4491      const swiper = this;
4492      swiper.observer.destroy();
4493    },
4494  },
4495};
4496
4497const 
vendor: 6,403 bytes, lines 4497-4719
4497Keyboard = {
4498  handle(event) {
4499    const swiper = this;
4500    const { rtlTranslate: rtl } = swiper;
4501    let e = event;
4502    if (e.originalEvent) e = e.originalEvent; // jquery fix
4503    const kc = e.keyCode || e.charCode;
4504    // Directions locks
4505    if (!swiper.allowSlideNext && ((swiper.isHorizontal() && kc === 39) || (swiper.isVertical() && kc === 40) || kc === 34)) {
4506      return false;
4507    }
4508    if (!swiper.allowSlidePrev && ((swiper.isHorizontal() && kc === 37) || (swiper.isVertical() && kc === 38) || kc === 33)) {
4509      return false;
4510    }
4511    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
4512      return undefined;
4513    }
4514    if (doc.activeElement && doc.activeElement.nodeName && (doc.activeElement.nodeName.toLowerCase() === 'input' || doc.activeElement.nodeName.toLowerCase() === 'textarea')) {
4515      return undefined;
4516    }
4517    if (swiper.params.keyboard.onlyInViewport && (kc === 33 || kc === 34 || kc === 37 || kc === 39 || kc === 38 || kc === 40)) {
4518      let inView = false;
4519      // Check that swiper should be inside of visible area of window
4520      if (swiper.$el.parents(`.${swiper.params.slideClass}`).length > 0 && swiper.$el.parents(`.${swiper.params.slideActiveClass}`).length === 0) {
4521        return undefined;
4522      }
4523      const windowWidth = win.innerWidth;
4524      const windowHeight = win.innerHeight;
4525      const swiperOffset = swiper.$el.offset();
4526      if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;
4527      const swiperCoord = [
4528        [swiperOffset.left, swiperOffset.top],
4529        [swiperOffset.left + swiper.width, swiperOffset.top],
4530        [swiperOffset.left, swiperOffset.top + swiper.height],
4531        [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height],
4532      ];
4533      for (let i = 0; i < swiperCoord.length; i += 1) {
4534        const point = swiperCoord[i];
4535        if (
4536          point[0] >= 0 && point[0] <= windowWidth
4537          && point[1] >= 0 && point[1] <= windowHeight
4538        ) {
4539          inView = true;
4540        }
4541      }
4542      if (!inView) return undefined;
4543    }
4544    if (swiper.isHorizontal()) {
4545      if (kc === 33 || kc === 34 || kc === 37 || kc === 39) {
4546        if (e.preventDefault) e.preventDefault();
4547        else e.returnValue = false;
4548      }
4549      if (((kc === 34 || kc === 39) && !rtl) || ((kc === 33 || kc === 37) && rtl)) swiper.slideNext();
4550      if (((kc === 33 || kc === 37) && !rtl) || ((kc === 34 || kc === 39) && rtl)) swiper.slidePrev();
4551    } else {
4552      if (kc === 33 || kc === 34 || kc === 38 || kc === 40) {
4553        if (e.preventDefault) e.preventDefault();
4554        else e.returnValue = false;
4555      }
4556      if (kc === 34 || kc === 40) swiper.slideNext();
4557      if (kc === 33 || kc === 38) swiper.slidePrev();
4558    }
4559    swiper.emit('keyPress', kc);
4560    return undefined;
4561  },
4562  enable() {
4563    const swiper = this;
4564    if (swiper.keyboard.enabled) return;
4565    $(doc).on('keydown', swiper.keyboard.handle);
4566    swiper.keyboard.enabled = true;
4567  },
4568  disable() {
4569    const swiper = this;
4570    if (!swiper.keyboard.enabled) return;
4571    $(doc).off('keydown', swiper.keyboard.handle);
4572    swiper.keyboard.enabled = false;
4573  },
4574};
4575
4576var keyboard = {
4577  name: 'keyboard',
4578  params: {
4579    keyboard: {
4580      enabled: false,
4581      onlyInViewport: true,
4582    },
4583  },
4584  create() {
4585    const swiper = this;
4586    Utils.extend(swiper, {
4587      keyboard: {
4588        enabled: false,
4589        enable: Keyboard.enable.bind(swiper),
4590        disable: Keyboard.disable.bind(swiper),
4591        handle: Keyboard.handle.bind(swiper),
4592      },
4593    });
4594  },
4595  on: {
4596    init() {
4597      const swiper = this;
4598      if (swiper.params.keyboard.enabled) {
4599        swiper.keyboard.enable();
4600      }
4601    },
4602    destroy() {
4603      const swiper = this;
4604      if (swiper.keyboard.enabled) {
4605        swiper.keyboard.disable();
4606      }
4607    },
4608  },
4609};
4610
4611function isEventSupported() {
4612  const eventName = 'onwheel';
4613  let isSupported = eventName in doc;
4614
4615  if (!isSupported) {
4616    const element = doc.createElement('div');
4617    element.setAttribute(eventName, 'return;');
4618    isSupported = typeof element[eventName] === 'function';
4619  }
4620
4621  if (!isSupported
4622    && doc.implementation
4623    && doc.implementation.hasFeature
4624    // always returns true in newer browsers as per the standard.
4625    // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
4626    && doc.implementation.hasFeature('', '') !== true
4627  ) {
4628    // This is the only way to test support for the `wheel` event in IE9+.
4629    isSupported = doc.implementation.hasFeature('Events.wheel', '3.0');
4630  }
4631
4632  return isSupported;
4633}
4634const Mousewheel = {
4635  lastScrollTime: Utils.now(),
4636  lastEventBeforeSnap: undefined,
4637  recentWheelEvents: [],
4638  event() {
4639    if (win.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll';
4640    return isEventSupported() ? 'wheel' : 'mousewheel';
4641  },
4642  normalize(e) {
4643    // Reasonable defaults
4644    const PIXEL_STEP = 10;
4645    const LINE_HEIGHT = 40;
4646    const PAGE_HEIGHT = 800;
4647
4648    let sX = 0;
4649    let sY = 0; // spinX, spinY
4650    let pX = 0;
4651    let pY = 0; // pixelX, pixelY
4652
4653    // Legacy
4654    if ('detail' in e) {
4655      sY = e.detail;
4656    }
4657    if ('wheelDelta' in e) {
4658      sY = -e.wheelDelta / 120;
4659    }
4660    if ('wheelDeltaY' in e) {
4661      sY = -e.wheelDeltaY / 120;
4662    }
4663    if ('wheelDeltaX' in e) {
4664      sX = -e.wheelDeltaX / 120;
4665    }
4666
4667    // side scrolling on FF with DOMMouseScroll
4668    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
4669      sX = sY;
4670      sY = 0;
4671    }
4672
4673    pX = sX * PIXEL_STEP;
4674    pY = sY * PIXEL_STEP;
4675
4676    if ('deltaY' in e) {
4677      pY = e.deltaY;
4678    }
4679    if ('deltaX' in e) {
4680      pX = e.deltaX;
4681    }
4682
4683    if (e.shiftKey && !pX) { // if user scrolls with shift he wants horizontal scroll
4684      pX = pY;
4685      pY = 0;
4686    }
4687
4688    if ((pX || pY) && e.deltaMode) {
4689      if (e.deltaMode === 1) { // delta in LINE units
4690        pX *= LINE_HEIGHT;
4691        pY *= LINE_HEIGHT;
4692      } else { // delta in PAGE units
4693        pX *= PAGE_HEIGHT;
4694        pY *= PAGE_HEIGHT;
4695      }
4696    }
4697
4698    // Fall-back if spin cannot be determined
4699    if (pX && !sX) {
4700      sX = (pX < 1) ? -1 : 1;
4701    }
4702    if (pY && !sY) {
4703      sY = (pY < 1) ? -1 : 1;
4704    }
4705
4706    return {
4707      spinX: sX,
4708      spinY: sY,
4709      pixelX: pX,
4710      pixelY: pY,
4711    };
4712  },
4713  handleMouseEnter() {
4714    const swiper = this;
4715    swiper.mouseEntered = true;
4716  },
4717  handleMouseLeave() {
4718    const swiper = this;
4719    swiper.mouseEntered = false;
4720  },
4721  handle(event) {
4722    let e = event;
4723    const swiper = this;
4724    const params = swiper.params.mousewheel;
4725
4726    if (swiper.params.cssMode) {
4727      e.preventDefault();
4728    }
4729
4730    let target = swiper.$el;
4731    if (swiper.params.mousewheel.eventsTarged !== 'container') {
4732      target = $(swiper.params.mousewheel.eventsTarged);
4733    }
4734    if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;
4735
4736    if (e.originalEvent) e = e.originalEvent; // jquery fix
4737    let delta = 0;
4738    const rtlFactor = swiper.rtlTranslate ? -1 : 1;
4739
4740    const data = Mousewheel.normalize(e);
4741
4742    if (params.forceToAxis) {
4743      if (swiper.isHorizontal()) {
4744        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;
4745        else return true;
4746      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;
4747      else return true;
4748    } else {
4749      delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
4750    }
4751
4752    if (delta === 0) return true;
4753
4754    if (params.invert) delta = -delta;
4755
4756    if (!swiper.params.freeMode) {
4757      // Register the new event in a variable which stores the relevant data
4758      const newEvent = {
4759        time: Utils.now(),
4760        delta: Math.abs(delta),
4761        direction: Math.sign(delta),
4762        raw: event,
4763      };
4764
4765      // Keep the most recent events
4766      const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
4767      if (recentWheelEvents.length >= 2) {
4768        recentWheelEvents.shift(); // only store the last N events
4769      }
4770      const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4771      recentWheelEvents.push(newEvent);
4772
4773      // If there is at least one previous recorded event:
4774      //   If direction has changed or
4775      //   if the scroll is quicker than the previous one:
4776      //     Animate the slider.
4777      // Else (this is the first time the wheel is moved):
4778      //     Animate the slider.
4779      if (prevEvent) {
4780        if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
4781          swiper.mousewheel.animateSlider(newEvent);
4782        }
4783      } else {
4784        swiper.mousewheel.animateSlider(newEvent);
4785      }
4786
4787      // If it's time to release the scroll:
4788      //   Return now so you don't hit the preventDefault.
4789      if (swiper.mousewheel.releaseScroll(newEvent)) {
4790        return true;
4791      }
4792    } else {
4793      // Freemode or scrollContainer:
4794
4795      // If we recently snapped after a momentum scroll, then ignore wheel events
4796      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
4797      // or if it's a new scroll (larger delta or inverse sign as last event before
4798      // an end-of-momentum snap).
4799      const newEvent = { time: Utils.now(), delta: Math.abs(delta), direction: Math.sign(delta) };
4800      const { lastEventBeforeSnap } = swiper.mousewheel;
4801      const ignoreWheelEvents = lastEventBeforeSnap
4802        && newEvent.time < lastEventBeforeSnap.time + 500
4803        && newEvent.delta <= lastEventBeforeSnap.delta
4804        && newEvent.direction === lastEventBeforeSnap.direction;
4805      if (!ignoreWheelEvents) {
4806        swiper.mousewheel.lastEventBeforeSnap = undefined;
4807
4808        if (swiper.params.loop) {
4809          swiper.loopFix();
4810        }
4811        let position = swiper.getTranslate() + (delta * params.sensitivity);
4812        const wasBeginning = swiper.isBeginning;
4813        const wasEnd = swiper.isEnd;
4814
4815        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
4816        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
4817
4818        swiper.setTransition(0);
4819        swiper.setTranslate(position);
4820        swiper.updateProgress();
4821        swiper.updateActiveIndex();
4822        swiper.updateSlidesClasses();
4823
4824        if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) {
4825          swiper.updateSlidesClasses();
4826        }
4827
4828        if (swiper.params.freeModeSticky) {
4829          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
4830          // the end of a momentum scroll by storing recent (N=15?) wheel events.
4831          // 1. do all N events have decreasing or same (absolute value) delta?
4832          // 2. did all N events arrive in the last M (M=500?) msecs?
4833          // 3. does the earliest event have an (absolute value) delta that's
4834          //    at least P (P=1?) larger than the most recent event's delta?
4835          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
4836          // If 1-4 are "yes" then we're near the end of a momuntum scroll deceleration.
4837          // Snap immediately and ignore remaining wheel events in this scroll.
4838          // See comment above for "remaining wheel events in this scroll" determination.
4839          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
4840          clearTimeout(swiper.mousewheel.timeout);
4841          swiper.mousewheel.timeout = undefined;
4842          const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
4843          if (recentWheelEvents.length >= 15) {
4844            recentWheelEvents.shift(); // only store the last N events
4845          }
4846          const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4847          const firstEvent = recentWheelEvents[0];
4848          recentWheelEvents.push(newEvent);
4849          if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
4850            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
4851            recentWheelEvents.splice(0);
4852          } else if (recentWheelEvents.length >= 15
4853              && newEvent.time - firstEvent.time < 500
4854              && firstEvent.delta - newEvent.delta >= 1
4855              && newEvent.delta <= 6
4856          ) {
4857            // We're at the end of the deceleration of a momentum scroll, so there's no need
4858            // to wait for more events. Snap ASAP on the next tick.
4859            // Also, because there's some remaining momentum we'll bias the snap in the
4860            // direction of the ongoing scroll because it's better UX for the scroll to snap
4861            // in the same direction as the scroll instead of reversing to snap.  Therefore,
4862            // if it's already scrolled more than 20% in the current direction, keep going.
4863            const snapToThreshold = delta > 0 ? 0.8 : 0.2;
4864            swiper.mousewheel.lastEventBeforeSnap = newEvent;
4865            recentWheelEvents.splice(0);
4866            swiper.mousewheel.timeout = Utils.nextTick(() => {
4867              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4868            }, 0); // no delay; move on next tick
4869          }
4870          if (!swiper.mousewheel.timeout) {
4871            // if we get here, then we haven't detected the end of a momentum scroll, so
4872            // we'll consider a scroll "complete" when there haven't been any wheel events
4873            // for 500ms.
4874            swiper.mousewheel.timeout = Utils.nextTick(() => {
4875              const snapToThreshold = 0.5;
4876              swiper.mousewheel.lastEventBeforeSnap = newEvent;
4877              recentWheelEvents.splice(0);
4878              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4879            }, 500);
4880          }
4881        }
4882
4883        // Emit event
4884        if (!ignoreWheelEvents) swiper.emit('scroll', e);
4885
4886        // Stop autoplay
4887        if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
4888        // Return page scroll on edge positions
4889        if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
4890      }
4891    }
4892
4893    if (e.preventDefault) e.preventDefault();
4894    else e.returnValue = false;
4895    return false;
4896  },
4897  animateSlider(newEvent) {
4898    const swiper = this;
4899    // If the movement is NOT big enough and
4900    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
4901    //   Don't go any further (avoid insignificant scroll movement).
4902    if (newEvent.delta >= 6 && Utils.now() - swiper.mousewheel.lastScrollTime < 60) {
4903      // Return false as a default
4904      return true;
4905    }
4906    // If user is scrolling towards the end:
4907    //   If the slider hasn't hit the latest slide or
4908    //   if the slider is a loop and
4909    //   if the slider isn't moving right now:
4910    //     Go to next slide and
4911    //     emit a scroll event.
4912    // Else (the user is scrolling towards the beginning) and
4913    // if the slider hasn't hit the first slide or
4914    // if the slider is a loop and
4915    // if the slider isn't moving right now:
4916    //   Go to prev slide and
4917    //   emit a scroll event.
4918    if (newEvent.direction < 0) {
4919      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
4920        swiper.slideNext();
4921        swiper.emit('scroll', newEvent.raw);
4922      }
4923    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
4924      swiper.slidePrev();
4925      swiper.emit('scroll', newEvent.raw);
4926    }
4927    // If you got here is because an animation has been triggered so store the current time
4928    swiper.mousewheel.lastScrollTime = (new win.Date()).getTime();
4929    // Return false as a default
4930    return false;
vendor: 8,397 bytes, lines 4931-5125
4931  },
4932  releaseScroll(newEvent) {
4933    const swiper = this;
4934    const params = swiper.params.mousewheel;
4935    if (newEvent.direction < 0) {
4936      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
4937        // Return true to animate scroll on edges
4938        return true;
4939      }
4940    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
4941      // Return true to animate scroll on edges
4942      return true;
4943    }
4944    return false;
4945  },
4946  enable() {
4947    const swiper = this;
4948    const event = Mousewheel.event();
4949    if (swiper.params.cssMode) {
4950      swiper.wrapperEl.removeEventListener(event, swiper.mousewheel.handle);
4951      return true;
4952    }
4953    if (!event) return false;
4954    if (swiper.mousewheel.enabled) return false;
4955    let target = swiper.$el;
4956    if (swiper.params.mousewheel.eventsTarged !== 'container') {
4957      target = $(swiper.params.mousewheel.eventsTarged);
4958    }
4959    target.on('mouseenter', swiper.mousewheel.handleMouseEnter);
4960    target.on('mouseleave', swiper.mousewheel.handleMouseLeave);
4961    target.on(event, swiper.mousewheel.handle);
4962    swiper.mousewheel.enabled = true;
4963    return true;
4964  },
4965  disable() {
4966    const swiper = this;
4967    const event = Mousewheel.event();
4968    if (swiper.params.cssMode) {
4969      swiper.wrapperEl.addEventListener(event, swiper.mousewheel.handle);
4970      return true;
4971    }
4972    if (!event) return false;
4973    if (!swiper.mousewheel.enabled) return false;
4974    let target = swiper.$el;
4975    if (swiper.params.mousewheel.eventsTarged !== 'container') {
4976      target = $(swiper.params.mousewheel.eventsTarged);
4977    }
4978    target.off(event, swiper.mousewheel.handle);
4979    swiper.mousewheel.enabled = false;
4980    return true;
4981  },
4982};
4983
4984const Pagination = {
4985  update() {
4986    // Render || Update Pagination bullets/items
4987    const swiper = this;
4988    const rtl = swiper.rtl;
4989    const params = swiper.params.pagination;
4990    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
4991    const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
4992    const $el = swiper.pagination.$el;
4993    // Current/Total
4994    let current;
4995    const total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
4996    if (swiper.params.loop) {
4997      current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);
4998      if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) {
4999        current -= (slidesLength - (swiper.loopedSlides * 2));
5000      }
5001      if (current > total - 1) current -= total;
5002      if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
5003    } else if (typeof swiper.snapIndex !== 'undefined') {
5004      current = swiper.snapIndex;
5005    } else {
5006      current = swiper.activeIndex || 0;
5007    }
5008    // Types
5009    if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
5010      const bullets = swiper.pagination.bullets;
5011      let firstIndex;
5012      let lastIndex;
5013      let midIndex;
5014      if (params.dynamicBullets) {
5015        swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);
5016        $el.css(swiper.isHorizontal() ? 'width' : 'height', `${swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)}px`);
5017        if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
5018          swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex);
5019          if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) {
5020            swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1;
5021          } else if (swiper.pagination.dynamicBulletIndex < 0) {
5022            swiper.pagination.dynamicBulletIndex = 0;
5023          }
5024        }
5025        firstIndex = current - swiper.pagination.dynamicBulletIndex;
5026        lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
5027        midIndex = (lastIndex + firstIndex) / 2;
5028      }
5029      bullets.removeClass(`${params.bulletActiveClass} ${params.bulletActiveClass}-next ${params.bulletActiveClass}-next-next ${params.bulletActiveClass}-prev ${params.bulletActiveClass}-prev-prev ${params.bulletActiveClass}-main`);
5030      if ($el.length > 1) {
5031        bullets.each((index, bullet) => {
5032          const $bullet = $(bullet);
5033          const bulletIndex = $bullet.index();
5034          if (bulletIndex === current) {
5035            $bullet.addClass(params.bulletActiveClass);
5036          }
5037          if (params.dynamicBullets) {
5038            if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
5039              $bullet.addClass(`${params.bulletActiveClass}-main`);
5040            }
5041            if (bulletIndex === firstIndex) {
5042              $bullet
5043                .prev()
5044                .addClass(`${params.bulletActiveClass}-prev`)
5045                .prev()
5046                .addClass(`${params.bulletActiveClass}-prev-prev`);
5047            }
5048            if (bulletIndex === lastIndex) {
5049              $bullet
5050                .next()
5051                .addClass(`${params.bulletActiveClass}-next`)
5052                .next()
5053                .addClass(`${params.bulletActiveClass}-next-next`);
5054            }
5055          }
5056        });
5057      } else {
5058        const $bullet = bullets.eq(current);
5059        const bulletIndex = $bullet.index();
5060        $bullet.addClass(params.bulletActiveClass);
5061        if (params.dynamicBullets) {
5062          const $firstDisplayedBullet = bullets.eq(firstIndex);
5063          const $lastDisplayedBullet = bullets.eq(lastIndex);
5064          for (let i = firstIndex; i <= lastIndex; i += 1) {
5065            bullets.eq(i).addClass(`${params.bulletActiveClass}-main`);
5066          }
5067          if (swiper.params.loop) {
5068            if (bulletIndex >= bullets.length - params.dynamicMainBullets) {
5069              for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
5070                bullets.eq(bullets.length - i).addClass(`${params.bulletActiveClass}-main`);
5071              }
5072              bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(`${params.bulletActiveClass}-prev`);
5073            } else {
5074              $firstDisplayedBullet
5075                .prev()
5076                .addClass(`${params.bulletActiveClass}-prev`)
5077                .prev()
5078                .addClass(`${params.bulletActiveClass}-prev-prev`);
5079              $lastDisplayedBullet
5080                .next()
5081                .addClass(`${params.bulletActiveClass}-next`)
5082                .next()
5083                .addClass(`${params.bulletActiveClass}-next-next`);
5084            }
5085          } else {
5086            $firstDisplayedBullet
5087              .prev()
5088              .addClass(`${params.bulletActiveClass}-prev`)
5089              .prev()
5090              .addClass(`${params.bulletActiveClass}-prev-prev`);
5091            $lastDisplayedBullet
5092              .next()
5093              .addClass(`${params.bulletActiveClass}-next`)
5094              .next()
5095              .addClass(`${params.bulletActiveClass}-next-next`);
5096          }
5097        }
5098      }
5099      if (params.dynamicBullets) {
5100        const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
5101        const bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize);
5102        const offsetProp = rtl ? 'right' : 'left';
5103        bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
5104      }
5105    }
5106    if (params.type === 'fraction') {
5107      $el.find(`.${params.currentClass}`).text(params.formatFractionCurrent(current + 1));
5108      $el.find(`.${params.totalClass}`).text(params.formatFractionTotal(total));
5109    }
5110    if (params.type === 'progressbar') {
5111      let progressbarDirection;
5112      if (params.progressbarOpposite) {
5113        progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
5114      } else {
5115        progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
5116      }
5117      const scale = (current + 1) / total;
5118      let scaleX = 1;
5119      let scaleY = 1;
5120      if (progressbarDirection === 'horizontal') {
5121        scaleX = scale;
5122      } else {
5123        scaleY = scale;
5124      }
5125      $el.find(`.${params.progressbarFillClass}
5125`).transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed);
5126    }
5127    if (params.type === 'custom' && params.renderCustom) {
5128      $el.html(params.renderCustom(swiper, current + 1, total));
5129      swiper.emit('paginationRender', swiper, $el[0]);
5130    } else {
5131      swiper.emit('paginationUpdate', swiper, $el[0]);
5132    }
5133    $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
5134  },
5135  render() {
5136    // Render Container
5137    const swiper = this;
5138    const params = swiper.params.pagination;
5139    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
5140    const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5141
5142    const $el = swiper.pagination.$el;
5143    let paginationHTML = '';
5144    if (params.type === 'bullets') {
5145      const numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5146      for (let i = 0; i < numberOfBullets; i += 1) {
5147        if (params.renderBullet) {
5148          paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
5149        } else {
5150          paginationHTML += `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
5151        }
5152      }
5153      $el.html(paginationHTML);
5154      swiper.pagination.bullets = $el.find(`.${params.bulletClass}`);
5155    }
5156    if (params.type === 'fraction') {
5157      if (params.renderFraction) {
5158        paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
5159      } else {
5160        paginationHTML = `<span class="${params.currentClass}"></span>`
5161        + ' / '
5162        + `<span class="${params.totalClass}"></span>`;
5163      }
5164      $el.html(paginationHTML);
5165    }
5166    if (params.type === 'progressbar') {
5167      if (params.renderProgressbar) {
5168        paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
5169      } else {
5170        paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
5171      }
5172      $el.html(paginationHTML);
5173    }
5174    if (params.type !== 'custom') {
5175      swiper.emit('paginationRender', swiper.pagination.$el[0]);
5176    }
5177  },
5178  init() {
5179    const swiper = this;
5180    const params = swiper.params.pagination;
5181    if (!params.el) return;
5182
5183    let $el = $(params.el);
5184    if ($el.length === 0) return;
5185
5186    if (
5187      swiper.params.uniqueNavElements
5188      && typeof params.el === 'string'
5189      && $el.length > 1
5190      && swiper.$el.find(params.el).length === 1
5191    ) {
5192      $el = swiper.$el.find(params.el);
5193    }
5194
5195    if (params.type === 'bullets' && params.clickable) {
5196      $el.addClass(params.clickableClass);
5197    }
5198
5199    $el.addClass(params.modifierClass + params.type);
5200
5201    if (params.type === 'bullets' && params.dynamicBullets) {
5202      $el.addClass(`${params.modifierClass}${params.type}-dynamic`);
5203      swiper.pagination.dynamicBulletIndex = 0;
5204      if (params.dynamicMainBullets < 1) {
5205        params.dynamicMainBullets = 1;
5206      }
5207    }
5208    if (params.type === 'progressbar' && params.progressbarOpposite) {
5209      $el.addClass(params.progressbarOppositeClass);
5210    }
5211
5212    if (params.clickable) {
5213      $el.on('click', `.${params.bulletClass}`, function onClick(e) {
5214        e.preventDefault();
5215        let index = $(this).index() * swiper.params.slidesPerGroup;
5216        if (swiper.params.loop) index += swiper.loopedSlides;
5217        swiper.slideTo(index);
5218      });
5219    }
5220
5221    Utils.extend(swiper.pagination, {
5222      $el,
5223      el: $el[0],
5224    });
5225  },
5226  destroy() {
5227    const swiper = this;
5228    const params = swiper.params.pagination;
5229    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
5230    const $el = swiper.pagination.$el;
5231
5232    $el.removeClass(params.hiddenClass);
5233    $el.removeClass(params.modifierClass + params.type);
5234    if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass);
5235    if (params.clickable) {
5236      $el.off('click', `.${params.bulletClass}`);
5237    }
5238  },
5239};
5240
5241var pagination = {
5242  name: 'pagination',
5243  params: {
5244    pagination: {
5245      el: null,
5246      bulletElement: 'span',
5247      clickable: false,
5248      hideOnClick: false,
5249      renderBullet: null,
5250      renderProgressbar: null,
5251      renderFraction: null,
5252      renderCustom: null,
5253      progressbarOpposite: false,
5254      type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'
5255      dynamicBullets: false,
5256      dynamicMainBullets: 1,
5257      formatFractionCurrent: (number) => number,
5258      formatFractionTotal: (number) => number,
5259      bulletClass: 'swiper-pagination-bullet',
5260      bulletActiveClass: 'swiper-pagination-bullet-active',
5261      modifierClass: 'swiper-pagination-', // NEW
5262      currentClass: 'swiper-pagination-current',
5263      totalClass: 'swiper-pagination-total',
5264      hiddenClass: 'swiper-pagination-hidden',
5265      progressbarFillClass: 'swiper-pagination-progressbar-fill',
5266      progressbarOppositeClass: 'swiper-pagination-progressbar-opposite',
5267      clickableClass: 'swiper-pagination-clickable', // NEW
5268      lockClass: 'swiper-pagination-lock',
5269    },
5270  },
5271  create() {
5272    const swiper = this;
5273    Utils.extend(swiper, {
5274      pagination: {
5275        init: Pagination.init.bind(swiper),
5276        render: Pagination.render.bind(swiper),
5277        update: Pagination.update.bind(swiper),
5278        destroy: Pagination.destroy.bind(swiper),
5279        dynamicBulletIndex: 0,
5280      },
5281    });
5282  },
5283  on: {
5284    init() {
5285      const swiper = this;
5286      swiper.pagination.init();
5287      swiper.pagination.render();
5288      swiper.pagination.update();
5289    },
5290    activeIndexChange() {
5291      const swiper = this;
5292      if (swiper.params.loop) {
5293        swiper.pagination.update();
5294      } else if (typeof swiper.snapIndex === 'undefined') {
5295        swiper.pagination.update();
5296      }
5297    },
5298    snapIndexChange() {
5299      const swiper = this;
5300      if (!swiper.params.loop) {
5301        swiper.pagination.update();
5302      }
5303    },
5304    slidesLengthChange() {
5305      const swiper = this;
5306      if (swiper.params.loop) {
5307        swiper.pagination.render();
5308        swiper.pagination.update();
5309      }
5310    },
5311    snapGridLengthChange() {
5312      const swiper = this;
5313      if (!swiper.params.loop) {
5314        swiper.pagination.render();
5315        swiper.pagination.update();
5316      }
5317    },
5318    destroy() {
5319      const swiper = this;
5320      swiper.pagination.destroy();
5321    },
5322    click(e) {
5323      const swiper = this;
5324      if (
5325        swiper.params.pagination.el
5326        && swiper.params.pagination.hideOnClick
5327        && swiper.pagination.$el.length > 0
5328        && !$(e.target).hasClass(swiper.params.pagination.bulletClass)
5329      ) {
5330        const isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass);
5331        if (isHidden === true) {
5332          swiper.emit('paginationShow', swiper);
5333        } else {
5334          swiper.emit('paginationHide', swiper);
5335        }
5336        swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass);
5337      }
5338    },
5339  },
5340};
5341
5342const Scrollbar = {
5343  setTranslate() {
5344    const swiper = this;
5345    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5346    const { scrollbar, rtlTranslate: rtl, progress } = swiper;
5347    const {
5348      dragSize, trackSize, $dragEl, $el,
5349    } = scrollbar;
5350    const params = swiper.params.scrollbar;
5351
5352    let newSize = dragSize;
5353    let newPos = (trackSize - dragSize) * progress;
5354    if (rtl) {
5355      newPos = -newPos;
5356      if (newPos > 0) {
5357        newSize = dragSize - newPos;
5358        newPos = 0;
5359      } else if (-newPos + dragSize > trackSize) {
5360        newSize = trackSize + newPos;
5361      }
5362    } else if (newPos < 0) {
5363      newSize = dragSize + newPos;
5364      newPos = 0;
5365    } else if (newPos + dragSize > trackSize) {
5366      newSize = trackSize - newPos;
5367    }
5368    if (swiper.isHorizontal()) {
5369      $dragEl.transform(`translate3d(${newPos}px, 0, 0)`);
5370      $dragEl[0].style.width = `${newSize}px`;
5371    } else {
5372      $dragEl.transform(`translate3d(0px, ${newPos}px, 0)`);
5373      $dragEl[0].style.height = `${newSize}px`;
5374    }
5375    if (params.hide) {
5376      clearTimeout(swiper.scrollbar.timeout);
5377      $el[0].style.opacity = 1;
5378      swiper.scrollbar.timeout = setTimeout(() => {
5379        $el[0].style.opacity = 0;
5380        $el.transition(400);
5381      }, 1000);
5382    }
5383  },
5384  setTransition(duration) {
5385    const swiper = this;
5386    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5387    swiper.scrollbar.$dragEl.transition(duration);
5388  },
5389  updateSize() {
5390    const swiper = this;
5391    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5392
5393    const { scrollbar } = swiper;
5394    const { $dragEl, $el } = scrollbar;
5395
5396    $dragEl[0].style.width = '';
5397    $dragEl[0].style.height = '';
5398    const trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight;
5399
5400    const divider = swiper.size / swiper.virtualSize;
5401    const moveDivider = divider * (trackSize / swiper.size);
5402    let dragSize;
5403    if (swiper.params.scrollbar.dragSize === 'auto') {
5404      dragSize = trackSize * divider;
5405    } else {
5406      dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
5407    }
5408
5409    if (swiper.isHorizontal()) {
5410      $dragEl[0].style.width = `${dragSize}px`;
5411    } else {
5412      $dragEl[0].style.height = `${dragSize}px`;
5413    }
5414
5415    if (divider >= 1) {
5416      $el[0].style.display = 'none';
5417    } else {
5418      $el[0].style.display = '';
5419    }
5420    if (swiper.params.scrollbar.hide) {
5421      $el[0].style.opacity = 0;
5422    }
5423    Utils.extend(scrollbar, {
5424      trackSize,
5425      divider,
5426      moveDivider,
5427      dragSize,
5428    });
5429    scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass);
5430  },
5431  getPointerPosition(e) {
5432    const swiper = this;
5433    if (swiper.isHorizontal()) {
5434      return ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].clientX : e.clientX);
5435    }
5436    return ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].clientY : e.clientY);
5437  },
5438  setDragPosition(e) {
5439    const swiper = this;
5440    const { scrollbar, rtlTranslate: rtl } = swiper;
5441    const {
5442      $el,
5443      dragSize,
5444      trackSize,
5445      dragStartPos,
5446    } = scrollbar;
5447
5448    let positionRatio;
5449    positionRatio = ((scrollbar.getPointerPosition(e)) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top']
5450      - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
5451    positionRatio = Math.max(Math.min(positionRatio, 1), 0);
5452    if (rtl) {
5453      positionRatio = 1 - positionRatio;
5454    }
5455
5456    const position = swiper.minTranslate() + ((swiper.maxTranslate() - swiper.minTranslate()) * positionRatio);
5457
5458    swiper.updateProgress(position);
5459    swiper.setTranslate(position);
5460    swiper.updateActiveIndex();
5461    swiper.updateSlidesClasses();
5462  },
5463  onDragStart(e) {
5464    const swiper = this;
5465    const params = swiper.params.scrollbar;
5466    const { scrollbar, $wrapperEl } = swiper;
5467    const { $el, $dragEl } = scrollbar;
5468    swiper.scrollbar.isTouched = true;
5469    swiper.scrollbar.dragStartPos = (e.target === $dragEl[0] || e.target === $dragEl)
5470      ? scrollbar.getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
5471    e.preventDefault();
5472    e.stopPropagation();
5473
5474    $wrapperEl.transition(100);
5475    $dragEl.transition(100);
5476    scrollbar.setDragPosition(e);
5477
5478    clearTimeout(swiper.scrollbar.dragTimeout);
5479
5480    $el.transition(0);
5481    if (params.hide) {
5482      $el.css('opacity', 1);
5483    }
5484    if (swiper.params.cssMode) {
5485      swiper.$wrapperEl.css('scroll-snap-type', 'none');
5486    }
5487    swiper.emit('scrollbarDragStart', e);
5488  },
5489  onDragMove(e) {
5490    const swiper = this;
5491    const { scrollbar, $wrapperEl } = swiper;
5492    const { $el, $dragEl } = scrollbar;
5493
5494    if (!swiper.scrollbar.isTouched) return;
5495    if (e.preventDefault) e.preventDefault();
5496    else e.returnValue = false;
vendor: 28,914 bytes, lines 5497-6299
5497    scrollbar.setDragPosition(e);
5498    $wrapperEl.transition(0);
5499    $el.transition(0);
5500    $dragEl.transition(0);
5501    swiper.emit('scrollbarDragMove', e);
5502  },
5503  onDragEnd(e) {
5504    const swiper = this;
5505
5506    const params = swiper.params.scrollbar;
5507    const { scrollbar, $wrapperEl } = swiper;
5508    const { $el } = scrollbar;
5509
5510    if (!swiper.scrollbar.isTouched) return;
5511    swiper.scrollbar.isTouched = false;
5512    if (swiper.params.cssMode) {
5513      swiper.$wrapperEl.css('scroll-snap-type', '');
5514      $wrapperEl.transition('');
5515    }
5516    if (params.hide) {
5517      clearTimeout(swiper.scrollbar.dragTimeout);
5518      swiper.scrollbar.dragTimeout = Utils.nextTick(() => {
5519        $el.css('opacity', 0);
5520        $el.transition(400);
5521      }, 1000);
5522    }
5523    swiper.emit('scrollbarDragEnd', e);
5524    if (params.snapOnRelease) {
5525      swiper.slideToClosest();
5526    }
5527  },
5528  enableDraggable() {
5529    const swiper = this;
5530    if (!swiper.params.scrollbar.el) return;
5531    const {
5532      scrollbar, touchEventsTouch, touchEventsDesktop, params,
5533    } = swiper;
5534    const $el = scrollbar.$el;
5535    const target = $el[0];
5536    const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false;
5537    const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;
5538    if (!Support.touch) {
5539      target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);
5540      doc.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);
5541      doc.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);
5542    } else {
5543      target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);
5544      target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);
5545      target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);
5546    }
5547  },
5548  disableDraggable() {
5549    const swiper = this;
5550    if (!swiper.params.scrollbar.el) return;
5551    const {
5552      scrollbar, touchEventsTouch, touchEventsDesktop, params,
5553    } = swiper;
5554    const $el = scrollbar.$el;
5555    const target = $el[0];
5556    const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false;
5557    const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;
5558    if (!Support.touch) {
5559      target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);
5560      doc.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);
5561      doc.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);
5562    } else {
5563      target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);
5564      target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);
5565      target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);
5566    }
5567  },
5568  init() {
5569    const swiper = this;
5570    if (!swiper.params.scrollbar.el) return;
5571    const { scrollbar, $el: $swiperEl } = swiper;
5572    const params = swiper.params.scrollbar;
5573
5574    let $el = $(params.el);
5575    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) {
5576      $el = $swiperEl.find(params.el);
5577    }
5578
5579    let $dragEl = $el.find(`.${swiper.params.scrollbar.dragClass}`);
5580    if ($dragEl.length === 0) {
5581      $dragEl = $(`<div class="${swiper.params.scrollbar.dragClass}"></div>`);
5582      $el.append($dragEl);
5583    }
5584
5585    Utils.extend(scrollbar, {
5586      $el,
5587      el: $el[0],
5588      $dragEl,
5589      dragEl: $dragEl[0],
5590    });
5591
5592    if (params.draggable) {
5593      scrollbar.enableDraggable();
5594    }
5595  },
5596  destroy() {
5597    const swiper = this;
5598    swiper.scrollbar.disableDraggable();
5599  },
5600};
5601
5602var scrollbar = {
5603  name: 'scrollbar',
5604  params: {
5605    scrollbar: {
5606      el: null,
5607      dragSize: 'auto',
5608      hide: false,
5609      draggable: false,
5610      snapOnRelease: true,
5611      lockClass: 'swiper-scrollbar-lock',
5612      dragClass: 'swiper-scrollbar-drag',
5613    },
5614  },
5615  create() {
5616    const swiper = this;
5617    Utils.extend(swiper, {
5618      scrollbar: {
5619        init: Scrollbar.init.bind(swiper),
5620        destroy: Scrollbar.destroy.bind(swiper),
5621        updateSize: Scrollbar.updateSize.bind(swiper),
5622        setTranslate: Scrollbar.setTranslate.bind(swiper),
5623        setTransition: Scrollbar.setTransition.bind(swiper),
5624        enableDraggable: Scrollbar.enableDraggable.bind(swiper),
5625        disableDraggable: Scrollbar.disableDraggable.bind(swiper),
5626        setDragPosition: Scrollbar.setDragPosition.bind(swiper),
5627        getPointerPosition: Scrollbar.getPointerPosition.bind(swiper),
5628        onDragStart: Scrollbar.onDragStart.bind(swiper),
5629        onDragMove: Scrollbar.onDragMove.bind(swiper),
5630        onDragEnd: Scrollbar.onDragEnd.bind(swiper),
5631        isTouched: false,
5632        timeout: null,
5633        dragTimeout: null,
5634      },
5635    });
5636  },
5637  on: {
5638    init() {
5639      const swiper = this;
5640      swiper.scrollbar.init();
5641      swiper.scrollbar.updateSize();
5642      swiper.scrollbar.setTranslate();
5643    },
5644    update() {
5645      const swiper = this;
5646      swiper.scrollbar.updateSize();
5647    },
5648    resize() {
5649      const swiper = this;
5650      swiper.scrollbar.updateSize();
5651    },
5652    observerUpdate() {
5653      const swiper = this;
5654      swiper.scrollbar.updateSize();
5655    },
5656    setTranslate() {
5657      const swiper = this;
5658      swiper.scrollbar.setTranslate();
5659    },
5660    setTransition(duration) {
5661      const swiper = this;
5662      swiper.scrollbar.setTransition(duration);
5663    },
5664    destroy() {
5665      const swiper = this;
5666      swiper.scrollbar.destroy();
5667    },
5668  },
5669};
5670
5671const Zoom = {
5672  // Calc Scale From Multi-touches
5673  getDistanceBetweenTouches(e) {
5674    if (e.targetTouches.length < 2) return 1;
5675    const x1 = e.targetTouches[0].pageX;
5676    const y1 = e.targetTouches[0].pageY;
5677    const x2 = e.targetTouches[1].pageX;
5678    const y2 = e.targetTouches[1].pageY;
5679    const distance = Math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2));
5680    return distance;
5681  },
5682  // Events
5683  onGestureStart(e) {
5684    const swiper = this;
5685    const params = swiper.params.zoom;
5686    const zoom = swiper.zoom;
5687    const { gesture } = zoom;
5688    zoom.fakeGestureTouched = false;
5689    zoom.fakeGestureMoved = false;
5690    if (!Support.gestures) {
5691      if (e.type !== 'touchstart' || (e.type === 'touchstart' && e.targetTouches.length < 2)) {
5692        return;
5693      }
5694      zoom.fakeGestureTouched = true;
5695      gesture.scaleStart = Zoom.getDistanceBetweenTouches(e);
5696    }
5697    if (!gesture.$slideEl || !gesture.$slideEl.length) {
5698      gesture.$slideEl = $(e.target).closest(`.${swiper.params.slideClass}`);
5699      if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
5700      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
5701      gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);
5702      gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
5703      if (gesture.$imageWrapEl.length === 0) {
5704        gesture.$imageEl = undefined;
5705        return;
5706      }
5707    }
5708    if (gesture.$imageEl) {
5709      gesture.$imageEl.transition(0);
5710    }
5711    swiper.zoom.isScaling = true;
5712  },
5713  onGestureChange(e) {
5714    const swiper = this;
5715    const params = swiper.params.zoom;
5716    const zoom = swiper.zoom;
5717    const { gesture } = zoom;
5718    if (!Support.gestures) {
5719      if (e.type !== 'touchmove' || (e.type === 'touchmove' && e.targetTouches.length < 2)) {
5720        return;
5721      }
5722      zoom.fakeGestureMoved = true;
5723      gesture.scaleMove = Zoom.getDistanceBetweenTouches(e);
5724    }
5725    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5726    if (Support.gestures) {
5727      zoom.scale = e.scale * zoom.currentScale;
5728    } else {
5729      zoom.scale = (gesture.scaleMove / gesture.scaleStart) * zoom.currentScale;
5730    }
5731    if (zoom.scale > gesture.maxRatio) {
5732      zoom.scale = (gesture.maxRatio - 1) + (((zoom.scale - gesture.maxRatio) + 1) ** 0.5);
5733    }
5734    if (zoom.scale < params.minRatio) {
5735      zoom.scale = (params.minRatio + 1) - (((params.minRatio - zoom.scale) + 1) ** 0.5);
5736    }
5737    gesture.$imageEl.transform(`translate3d(0,0,0) scale(${zoom.scale})`);
5738  },
5739  onGestureEnd(e) {
5740    const swiper = this;
5741    const params = swiper.params.zoom;
5742    const zoom = swiper.zoom;
5743    const { gesture } = zoom;
5744    if (!Support.gestures) {
5745      if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) {
5746        return;
5747      }
5748      if (e.type !== 'touchend' || (e.type === 'touchend' && e.changedTouches.length < 2 && !Device.android)) {
5749        return;
5750      }
5751      zoom.fakeGestureTouched = false;
5752      zoom.fakeGestureMoved = false;
5753    }
5754    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5755    zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
5756    gesture.$imageEl.transition(swiper.params.speed).transform(`translate3d(0,0,0) scale(${zoom.scale})`);
5757    zoom.currentScale = zoom.scale;
5758    zoom.isScaling = false;
5759    if (zoom.scale === 1) gesture.$slideEl = undefined;
5760  },
5761  onTouchStart(e) {
5762    const swiper = this;
5763    const zoom = swiper.zoom;
5764    const { gesture, image } = zoom;
5765    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5766    if (image.isTouched) return;
5767    if (Device.android && e.cancelable) e.preventDefault();
5768    image.isTouched = true;
5769    image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
5770    image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
5771  },
5772  onTouchMove(e) {
5773    const swiper = this;
5774    const zoom = swiper.zoom;
5775    const { gesture, image, velocity } = zoom;
5776    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5777    swiper.allowClick = false;
5778    if (!image.isTouched || !gesture.$slideEl) return;
5779
5780    if (!image.isMoved) {
5781      image.width = gesture.$imageEl[0].offsetWidth;
5782      image.height = gesture.$imageEl[0].offsetHeight;
5783      image.startX = Utils.getTranslate(gesture.$imageWrapEl[0], 'x') || 0;
5784      image.startY = Utils.getTranslate(gesture.$imageWrapEl[0], 'y') || 0;
5785      gesture.slideWidth = gesture.$slideEl[0].offsetWidth;
5786      gesture.slideHeight = gesture.$slideEl[0].offsetHeight;
5787      gesture.$imageWrapEl.transition(0);
5788      if (swiper.rtl) {
5789        image.startX = -image.startX;
5790        image.startY = -image.startY;
5791      }
5792    }
5793    // Define if we need image drag
5794    const scaledWidth = image.width * zoom.scale;
5795    const scaledHeight = image.height * zoom.scale;
5796
5797    if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;
5798
5799    image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0);
5800    image.maxX = -image.minX;
5801    image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0);
5802    image.maxY = -image.minY;
5803
5804    image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
5805    image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
5806
5807    if (!image.isMoved && !zoom.isScaling) {
5808      if (
5809        swiper.isHorizontal()
5810        && (
5811          (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x)
5812          || (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)
5813        )
5814      ) {
5815        image.isTouched = false;
5816        return;
5817      } if (
5818        !swiper.isHorizontal()
5819        && (
5820          (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y)
5821          || (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)
5822        )
5823      ) {
5824        image.isTouched = false;
5825        return;
5826      }
5827    }
5828    if (e.cancelable) {
5829      e.preventDefault();
5830    }
5831    e.stopPropagation();
5832
5833    image.isMoved = true;
5834    image.currentX = (image.touchesCurrent.x - image.touchesStart.x) + image.startX;
5835    image.currentY = (image.touchesCurrent.y - image.touchesStart.y) + image.startY;
5836
5837    if (image.currentX < image.minX) {
5838      image.currentX = (image.minX + 1) - (((image.minX - image.currentX) + 1) ** 0.8);
5839    }
5840    if (image.currentX > image.maxX) {
5841      image.currentX = (image.maxX - 1) + (((image.currentX - image.maxX) + 1) ** 0.8);
5842    }
5843
5844    if (image.currentY < image.minY) {
5845      image.currentY = (image.minY + 1) - (((image.minY - image.currentY) + 1) ** 0.8);
5846    }
5847    if (image.currentY > image.maxY) {
5848      image.currentY = (image.maxY - 1) + (((image.currentY - image.maxY) + 1) ** 0.8);
5849    }
5850
5851    // Velocity
5852    if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
5853    if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
5854    if (!velocity.prevTime) velocity.prevTime = Date.now();
5855    velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
5856    velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
5857    if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
5858    if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
5859    velocity.prevPositionX = image.touchesCurrent.x;
5860    velocity.prevPositionY = image.touchesCurrent.y;
5861    velocity.prevTime = Date.now();
5862
5863    gesture.$imageWrapEl.transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`);
5864  },
5865  onTouchEnd() {
5866    const swiper = this;
5867    const zoom = swiper.zoom;
5868    const { gesture, image, velocity } = zoom;
5869    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5870    if (!image.isTouched || !image.isMoved) {
5871      image.isTouched = false;
5872      image.isMoved = false;
5873      return;
5874    }
5875    image.isTouched = false;
5876    image.isMoved = false;
5877    let momentumDurationX = 300;
5878    let momentumDurationY = 300;
5879    const momentumDistanceX = velocity.x * momentumDurationX;
5880    const newPositionX = image.currentX + momentumDistanceX;
5881    const momentumDistanceY = velocity.y * momentumDurationY;
5882    const newPositionY = image.currentY + momentumDistanceY;
5883
5884    // Fix duration
5885    if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
5886    if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
5887    const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
5888
5889    image.currentX = newPositionX;
5890    image.currentY = newPositionY;
5891
5892    // Define if we need image drag
5893    const scaledWidth = image.width * zoom.scale;
5894    const scaledHeight = image.height * zoom.scale;
5895    image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0);
5896    image.maxX = -image.minX;
5897    image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0);
5898    image.maxY = -image.minY;
5899    image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
5900    image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
5901
5902    gesture.$imageWrapEl.transition(momentumDuration).transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`);
5903  },
5904  onTransitionEnd() {
5905    const swiper = this;
5906    const zoom = swiper.zoom;
5907    const { gesture } = zoom;
5908    if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) {
5909      if (gesture.$imageEl) {
5910        gesture.$imageEl.transform('translate3d(0,0,0) scale(1)');
5911      }
5912      if (gesture.$imageWrapEl) {
5913        gesture.$imageWrapEl.transform('translate3d(0,0,0)');
5914      }
5915
5916      zoom.scale = 1;
5917      zoom.currentScale = 1;
5918
5919      gesture.$slideEl = undefined;
5920      gesture.$imageEl = undefined;
5921      gesture.$imageWrapEl = undefined;
5922    }
5923  },
5924  // Toggle Zoom
5925  toggle(e) {
5926    const swiper = this;
5927    const zoom = swiper.zoom;
5928
5929    if (zoom.scale && zoom.scale !== 1) {
5930      // Zoom Out
5931      zoom.out();
5932    } else {
5933      // Zoom In
5934      zoom.in(e);
5935    }
5936  },
5937  in(e) {
5938    const swiper = this;
5939
5940    const zoom = swiper.zoom;
5941    const params = swiper.params.zoom;
5942    const { gesture, image } = zoom;
5943
5944    if (!gesture.$slideEl) {
5945      if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
5946        gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`);
5947      } else {
5948        gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
5949      }
5950      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
5951      gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);
5952    }
5953    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
5954
5955    gesture.$slideEl.addClass(`${params.zoomedSlideClass}`);
5956
5957    let touchX;
5958    let touchY;
5959    let offsetX;
5960    let offsetY;
5961    let diffX;
5962    let diffY;
5963    let translateX;
5964    let translateY;
5965    let imageWidth;
5966    let imageHeight;
5967    let scaledWidth;
5968    let scaledHeight;
5969    let translateMinX;
5970    let translateMinY;
5971    let translateMaxX;
5972    let translateMaxY;
5973    let slideWidth;
5974    let slideHeight;
5975
5976    if (typeof image.touchesStart.x === 'undefined' && e) {
5977      touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
5978      touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
5979    } else {
5980      touchX = image.touchesStart.x;
5981      touchY = image.touchesStart.y;
5982    }
5983
5984    zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
5985    zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
5986    if (e) {
5987      slideWidth = gesture.$slideEl[0].offsetWidth;
5988      slideHeight = gesture.$slideEl[0].offsetHeight;
5989      offsetX = gesture.$slideEl.offset().left;
5990      offsetY = gesture.$slideEl.offset().top;
5991      diffX = (offsetX + (slideWidth / 2)) - touchX;
5992      diffY = (offsetY + (slideHeight / 2)) - touchY;
5993
5994      imageWidth = gesture.$imageEl[0].offsetWidth;
5995      imageHeight = gesture.$imageEl[0].offsetHeight;
5996      scaledWidth = imageWidth * zoom.scale;
5997      scaledHeight = imageHeight * zoom.scale;
5998
5999      translateMinX = Math.min(((slideWidth / 2) - (scaledWidth / 2)), 0);
6000      translateMinY = Math.min(((slideHeight / 2) - (scaledHeight / 2)), 0);
6001      translateMaxX = -translateMinX;
6002      translateMaxY = -translateMinY;
6003
6004      translateX = diffX * zoom.scale;
6005      translateY = diffY * zoom.scale;
6006
6007      if (translateX < translateMinX) {
6008        translateX = translateMinX;
6009      }
6010      if (translateX > translateMaxX) {
6011        translateX = translateMaxX;
6012      }
6013
6014      if (translateY < translateMinY) {
6015        translateY = translateMinY;
6016      }
6017      if (translateY > translateMaxY) {
6018        translateY = translateMaxY;
6019      }
6020    } else {
6021      translateX = 0;
6022      translateY = 0;
6023    }
6024    gesture.$imageWrapEl.transition(300).transform(`translate3d(${translateX}px, ${translateY}px,0)`);
6025    gesture.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${zoom.scale})`);
6026  },
6027  out() {
6028    const swiper = this;
6029
6030    const zoom = swiper.zoom;
6031    const params = swiper.params.zoom;
6032    const { gesture } = zoom;
6033
6034    if (!gesture.$slideEl) {
6035      if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6036        gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`);
6037      } else {
6038        gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
6039      }
6040      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
6041      gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);
6042    }
6043    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
6044
6045    zoom.scale = 1;
6046    zoom.currentScale = 1;
6047    gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)');
6048    gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)');
6049    gesture.$slideEl.removeClass(`${params.zoomedSlideClass}`);
6050    gesture.$slideEl = undefined;
6051  },
6052  // Attach/Detach Events
6053  enable() {
6054    const swiper = this;
6055    const zoom = swiper.zoom;
6056    if (zoom.enabled) return;
6057    zoom.enabled = true;
6058
6059    const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false;
6060    const activeListenerWithCapture = Support.passiveListener ? { passive: false, capture: true } : true;
6061
6062    const slideSelector = `.${swiper.params.slideClass}`;
6063
6064    // Scale image
6065    if (Support.gestures) {
6066      swiper.$wrapperEl.on('gesturestart', slideSelector, zoom.onGestureStart, passiveListener);
6067      swiper.$wrapperEl.on('gesturechange', slideSelector, zoom.onGestureChange, passiveListener);
6068      swiper.$wrapperEl.on('gestureend', slideSelector, zoom.onGestureEnd, passiveListener);
6069    } else if (swiper.touchEvents.start === 'touchstart') {
6070      swiper.$wrapperEl.on(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);
6071      swiper.$wrapperEl.on(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);
6072      swiper.$wrapperEl.on(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);
6073      if (swiper.touchEvents.cancel) {
6074        swiper.$wrapperEl.on(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);
6075      }
6076    }
6077
6078    // Move image
6079    swiper.$wrapperEl.on(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove, activeListenerWithCapture);
6080  },
6081  disable() {
6082    const swiper = this;
6083    const zoom = swiper.zoom;
6084    if (!zoom.enabled) return;
6085
6086    swiper.zoom.enabled = false;
6087
6088    const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false;
6089    const activeListenerWithCapture = Support.passiveListener ? { passive: false, capture: true } : true;
6090
6091    const slideSelector = `.${swiper.params.slideClass}`;
6092
6093    // Scale image
6094    if (Support.gestures) {
6095      swiper.$wrapperEl.off('gesturestart', slideSelector, zoom.onGestureStart, passiveListener);
6096      swiper.$wrapperEl.off('gesturechange', slideSelector, zoom.onGestureChange, passiveListener);
6097      swiper.$wrapperEl.off('gestureend', slideSelector, zoom.onGestureEnd, passiveListener);
6098    } else if (swiper.touchEvents.start === 'touchstart') {
6099      swiper.$wrapperEl.off(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);
6100      swiper.$wrapperEl.off(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);
6101      swiper.$wrapperEl.off(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);
6102      if (swiper.touchEvents.cancel) {
6103        swiper.$wrapperEl.off(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);
6104      }
6105    }
6106
6107    // Move image
6108    swiper.$wrapperEl.off(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove, activeListenerWithCapture);
6109  },
6110};
6111
6112var zoom = {
6113  name: 'zoom',
6114  params: {
6115    zoom: {
6116      enabled: false,
6117      maxRatio: 3,
6118      minRatio: 1,
6119      toggle: true,
6120      containerClass: 'swiper-zoom-container',
6121      zoomedSlideClass: 'swiper-slide-zoomed',
6122    },
6123  },
6124  create() {
6125    const swiper = this;
6126    const zoom = {
6127      enabled: false,
6128      scale: 1,
6129      currentScale: 1,
6130      isScaling: false,
6131      gesture: {
6132        $slideEl: undefined,
6133        slideWidth: undefined,
6134        slideHeight: undefined,
6135        $imageEl: undefined,
6136        $imageWrapEl: undefined,
6137        maxRatio: 3,
6138      },
6139      image: {
6140        isTouched: undefined,
6141        isMoved: undefined,
6142        currentX: undefined,
6143        currentY: undefined,
6144        minX: undefined,
6145        minY: undefined,
6146        maxX: undefined,
6147        maxY: undefined,
6148        width: undefined,
6149        height: undefined,
6150        startX: undefined,
6151        startY: undefined,
6152        touchesStart: {},
6153        touchesCurrent: {},
6154      },
6155      velocity: {
6156        x: undefined,
6157        y: undefined,
6158        prevPositionX: undefined,
6159        prevPositionY: undefined,
6160        prevTime: undefined,
6161      },
6162    };
6163
6164    ('onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out').split(' ').forEach((methodName) => {
6165      zoom[methodName] = Zoom[methodName].bind(swiper);
6166    });
6167    Utils.extend(swiper, {
6168      zoom,
6169    });
6170
6171    let scale = 1;
6172    Object.defineProperty(swiper.zoom, 'scale', {
6173      get() {
6174        return scale;
6175      },
6176      set(value) {
6177        if (scale !== value) {
6178          const imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined;
6179          const slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined;
6180          swiper.emit('zoomChange', value, imageEl, slideEl);
6181        }
6182        scale = value;
6183      },
6184    });
6185  },
6186  on: {
6187    init() {
6188      const swiper = this;
6189      if (swiper.params.zoom.enabled) {
6190        swiper.zoom.enable();
6191      }
6192    },
6193    destroy() {
6194      const swiper = this;
6195      swiper.zoom.disable();
6196    },
6197    touchStart(e) {
6198      const swiper = this;
6199      if (!swiper.zoom.enabled) return;
6200      swiper.zoom.onTouchStart(e);
6201    },
6202    touchEnd(e) {
6203      const swiper = this;
6204      if (!swiper.zoom.enabled) return;
6205      swiper.zoom.onTouchEnd(e);
6206    },
6207    doubleTap(e) {
6208      const swiper = this;
6209      if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
6210        swiper.zoom.toggle(e);
6211      }
6212    },
6213    transitionEnd() {
6214      const swiper = this;
6215      if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
6216        swiper.zoom.onTransitionEnd();
6217      }
6218    },
6219    slideChange() {
6220      const swiper = this;
6221      if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
6222        swiper.zoom.onTransitionEnd();
6223      }
6224    },
6225  },
6226};
6227
6228/* eslint no-underscore-dangle: "off" */
6229
6230const Autoplay = {
6231  run() {
6232    const swiper = this;
6233    const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
6234    let delay = swiper.params.autoplay.delay;
6235    if ($activeSlideEl.attr('data-swiper-autoplay')) {
6236      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
6237    }
6238    clearTimeout(swiper.autoplay.timeout);
6239    swiper.autoplay.timeout = Utils.nextTick(() => {
6240      if (swiper.params.autoplay.reverseDirection) {
6241        if (swiper.params.loop) {
6242          swiper.loopFix();
6243          swiper.slidePrev(swiper.params.speed, true, true);
6244          swiper.emit('autoplay');
6245        } else if (!swiper.isBeginning) {
6246          swiper.slidePrev(swiper.params.speed, true, true);
6247          swiper.emit('autoplay');
6248        } else if (!swiper.params.autoplay.stopOnLastSlide) {
6249          swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
6250          swiper.emit('autoplay');
6251        } else {
6252          swiper.autoplay.stop();
6253        }
6254      } else if (swiper.params.loop) {
6255        swiper.loopFix();
6256        swiper.slideNext(swiper.params.speed, true, true);
6257        swiper.emit('autoplay');
6258      } else if (!swiper.isEnd) {
6259        swiper.slideNext(swiper.params.speed, true, true);
6260        swiper.emit('autoplay');
6261      } else if (!swiper.params.autoplay.stopOnLastSlide) {
6262        swiper.slideTo(0, swiper.params.speed, true, true);
6263        swiper.emit('autoplay');
6264      } else {
6265        swiper.autoplay.stop();
6266      }
6267      if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();
6268    }, delay);
6269  },
6270  start() {
6271    const swiper = this;
6272    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
6273    if (swiper.autoplay.running) return false;
6274    swiper.autoplay.running = true;
6275    swiper.emit('autoplayStart');
6276    swiper.autoplay.run();
6277    return true;
6278  },
6279  stop() {
6280    const swiper = this;
6281    if (!swiper.autoplay.running) return false;
6282    if (typeof swiper.autoplay.timeout === 'undefined') return false;
6283
6284    if (swiper.autoplay.timeout) {
6285      clearTimeout(swiper.autoplay.timeout);
6286      swiper.autoplay.timeout = undefined;
6287    }
6288    swiper.autoplay.running = false;
6289    swiper.emit('autoplayStop');
6290    return true;
6291  },
6292  pause(speed) {
6293    const swiper = this;
6294    if (!swiper.autoplay.running) return;
6295    if (swiper.autoplay.paused) return;
6296    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
6297    swiper.autoplay.paused = true;
6298    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
6299      swiper.autoplay.paused = false;
vendor: 3,273 bytes, lines 6300-6418
6300      swiper.autoplay.run();
6301    } else {
6302      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd);
6303      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
6304    }
6305  },
6306};
6307
6308var autoplay = {
6309  name: 'autoplay',
6310  params: {
6311    autoplay: {
6312      enabled: false,
6313      delay: 3000,
6314      waitForTransition: true,
6315      disableOnInteraction: true,
6316      stopOnLastSlide: false,
6317      reverseDirection: false,
6318    },
6319  },
6320  create() {
6321    const swiper = this;
6322    Utils.extend(swiper, {
6323      autoplay: {
6324        running: false,
6325        paused: false,
6326        run: Autoplay.run.bind(swiper),
6327        start: Autoplay.start.bind(swiper),
6328        stop: Autoplay.stop.bind(swiper),
6329        pause: Autoplay.pause.bind(swiper),
6330        onVisibilityChange() {
6331          if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
6332            swiper.autoplay.pause();
6333          }
6334          if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
6335            swiper.autoplay.run();
6336            swiper.autoplay.paused = false;
6337          }
6338        },
6339        onTransitionEnd(e) {
6340          if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
6341          if (e.target !== this) return;
6342          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd);
6343          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
6344          swiper.autoplay.paused = false;
6345          if (!swiper.autoplay.running) {
6346            swiper.autoplay.stop();
6347          } else {
6348            swiper.autoplay.run();
6349          }
6350        },
6351      },
6352    });
6353  },
6354  on: {
6355    init() {
6356      const swiper = this;
6357      if (swiper.params.autoplay.enabled) {
6358        swiper.autoplay.start();
6359        document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
6360      }
6361    },
6362    beforeTransitionStart(speed, internal) {
6363      const swiper = this;
6364      if (swiper.autoplay.running) {
6365        if (internal || !swiper.params.autoplay.disableOnInteraction) {
6366          swiper.autoplay.pause(speed);
6367        } else {
6368          swiper.autoplay.stop();
6369        }
6370      }
6371    },
6372    sliderFirstMove() {
6373      const swiper = this;
6374      if (swiper.autoplay.running) {
6375        if (swiper.params.autoplay.disableOnInteraction) {
6376          swiper.autoplay.stop();
6377        } else {
6378          swiper.autoplay.pause();
6379        }
6380      }
6381    },
6382    touchEnd() {
6383      const swiper = this;
6384      if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
6385        swiper.autoplay.run();
6386      }
6387    },
6388    destroy() {
6389      const swiper = this;
6390      if (swiper.autoplay.running) {
6391        swiper.autoplay.stop();
6392      }
6393      document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
6394    },
6395  },
6396};
6397
6398// Swiper Class
6399
6400const components = [
6401  Device$1,
6402  Support$1,
6403  Browser$1,
6404  Resize,
6405  Observer$1,
6406  
6407];
6408
6409if (typeof Swiper.use === 'undefined') {
6410  Swiper.use = Swiper.Class.use;
6411  Swiper.installModule = Swiper.Class.installModule;
6412}
6413
6414Swiper.use(components);
6415
6416Swiper.use([pagination, scrollbar, autoplay, keyboard, zoom]);
6417
6418export { Swiper };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.