PageSourceSearch

https://www.sfrcaraibe.fr/wp-content/themes/sfrtheme/build/js/functions.min.js

js sfrcaraibe.fr collected 2026-09-24 21:40:01 UTC 772,325 bytes, 25,101 lines download raw bytes

1var SpinFunctions;
2/******/ (() => { // webpackBootstrap
3/******/ 	var __webpack_modules__ = ({
4
5/***/ 58:
6/***/ (() => {
7
8/**
9 * Closest
10 */
11if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
12if (!Element.prototype.closest) Element.prototype.closest = function (s) {
13  var el = this;
14  if (!document.documentElement.contains(el)) return null;
15  do {
16    if (el.matches(s)) return el;
17    el = el.parentElement || el.parentNode;
18  } while (el !== null && el.nodeType == 1);
19  return null;
20};
21
22/***/ }),
23
24/***/ 127:
25/***/ (() => {
26
27/**
28 * Copyright 2016 Google Inc. All Rights Reserved.
29 *
30 * Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
31 *
32 *  https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
33 *
34 */
35(function() {
36'use strict';
37
38// Exit early if we're not running in a browser.
39if (typeof window !== 'object') {
40  return;
41}
42
43// Exit early if all IntersectionObserver and IntersectionObserverEntry
44// features are natively supported.
45if ('IntersectionObserver' in window &&
46    'IntersectionObserverEntry' in window &&
47    'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
48
49  // Minimal polyfill for Edge 15's lack of `isIntersecting`
50  // See: https://github.com/w3c/IntersectionObserver/issues/211
51  if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) {
52    Object.defineProperty(window.IntersectionObserverEntry.prototype,
53      'isIntersecting', {
54      get: function () {
55        return this.intersectionRatio > 0;
56      }
57    });
58  }
59  return;
60}
61
62
63/**
64 * A local reference to the document.
65 */
66var document = window.document;
67
68
69/**
70 * An IntersectionObserver registry. This registry exists to hold a strong
71 * reference to IntersectionObserver instances currently observing a target
72 * element. Without this registry, instances without another reference may be
73 * garbage collected.
74 */
75var registry = [];
76
77
78/**
79 * Creates the global IntersectionObserverEntry constructor.
80 * https://w3c.github.io/IntersectionObserver/#intersection-observer-entry
81 * @param {Object} entry A dictionary of instance properties.
82 * @constructor
83 */
84function IntersectionObserverEntry(entry) {
85  this.time = entry.time;
86  this.target = entry.target;
87  this.rootBounds = entry.rootBounds;
88  this.boundingClientRect = entry.boundingClientRect;
89  this.intersectionRect = entry.intersectionRect || getEmptyRect();
90  this.isIntersecting = !!entry.intersectionRect;
91
92  // Calculates the intersection ratio.
93  var targetRect = this.boundingClientRect;
94  var targetArea = targetRect.width * targetRect.height;
95  var intersectionRect = this.intersectionRect;
96  var intersectionArea = intersectionRect.width * intersectionRect.height;
97
98  // Sets intersection ratio.
99  if (targetArea) {
100    // Round the intersection ratio to avoid floating point math issues:
101    // https://github.com/w3c/IntersectionObserver/issues/324
102    this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4));
103  } else {
104    // If area is zero and is intersecting, sets to 1, otherwise to 0
105    this.intersectionRatio = this.isIntersecting ? 1 : 0;
106  }
107}
108
109
110/**
111 * Creates the global IntersectionObserver constructor.
112 * https://w3c.github.io/IntersectionObserver/#intersection-observer-interface
113 * @param {Function} callback The function to be invoked after intersection
114 *     changes have queued. The function is not invoked if the queue has
115 *     been emptied by calling the `takeRecords` method.
116 * @param {Object=} opt_options Optional configuration options.
117 * @constructor
118 */
119function IntersectionObserver(callback, opt_options) {
120
121  var options = opt_options || {};
122
123  if (typeof callback != 'function') {
124    throw new Error('callback must be a function');
125  }
126
127  if (options.root && options.root.nodeType != 1) {
128    throw new Error('root must be an Element');
129  }
130
131  // Binds and throttles `this._checkForIntersections`.
132  this._checkForIntersections = throttle(
133      this._checkForIntersections.bind(this), this.THROTTLE_TIMEOUT);
134
135  // Private properties.
136  this._callback = callback;
137  this._observationTargets = [];
138  this._queuedEntries = [];
139  this._rootMarginValues = this._parseRootMargin(options.rootMargin);
140
141  // Public properties.
142  this.thresholds = this._initThresholds(options.threshold);
143  this.root = options.root || null;
144  this.rootMargin = this._rootMarginValues.map(function(margin) {
145    return margin.value + margin.unit;
146  }).join(' ');
147}
148
149
150/**
151 * The minimum interval within which the document will be checked for
152 * intersection changes.
153 */
154IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100;
155
156
157/**
158 * The frequency in which the polyfill polls for intersection changes.
159 * this can be updated on a per instance basis and must be set prior to
160 * calling `observe` on the first target.
161 */
162IntersectionObserver.prototype.POLL_INTERVAL = null;
163
164/**
165 * Use a mutation observer on the root element
166 * to detect intersection changes.
167 */
168IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true;
169
170
171/**
172 * Starts observing a target element for intersection changes based on
173 * the thresholds values.
174 * @param {Element} target The DOM element to observe.
175 */
176IntersectionObserver.prototype.observe = function(target) {
177  var isTargetAlreadyObserved = this._observationTargets.some(function(item) {
178    return item.element == target;
179  });
180
181  if (isTargetAlreadyObserved) {
182    return;
183  }
184
vendor: 2,303 bytes, lines 185-260
185  if (!(target && target.nodeType == 1)) {
186    throw new Error('target must be an Element');
187  }
188
189  this._registerInstance();
190  this._observationTargets.push({element: target, entry: null});
191  this._monitorIntersections();
192  this._checkForIntersections();
193};
194
195
196/**
197 * Stops observing a target element for intersection changes.
198 * @param {Element} target The DOM element to observe.
199 */
200IntersectionObserver.prototype.unobserve = function(target) {
201  this._observationTargets =
202      this._observationTargets.filter(function(item) {
203
204    return item.element != target;
205  });
206  if (!this._observationTargets.length) {
207    this._unmonitorIntersections();
208    this._unregisterInstance();
209  }
210};
211
212
213/**
214 * Stops observing all target elements for intersection changes.
215 */
216IntersectionObserver.prototype.disconnect = function() {
217  this._observationTargets = [];
218  this._unmonitorIntersections();
219  this._unregisterInstance();
220};
221
222
223/**
224 * Returns any queue entries that have not yet been reported to the
225 * callback and clears the queue. This can be used in conjunction with the
226 * callback to obtain the absolute most up-to-date intersection information.
227 * @return {Array} The currently queued entries.
228 */
229IntersectionObserver.prototype.takeRecords = function() {
230  var records = this._queuedEntries.slice();
231  this._queuedEntries = [];
232  return records;
233};
234
235
236/**
237 * Accepts the threshold value from the user configuration object and
238 * returns a sorted array of unique threshold values. If a value is not
239 * between 0 and 1 and error is thrown.
240 * @private
241 * @param {Array|number=} opt_threshold An optional threshold value or
242 *     a list of threshold values, defaulting to [0].
243 * @return {Array} A sorted list of unique and valid threshold values.
244 */
245IntersectionObserver.prototype._initThresholds = function(opt_threshold) {
246  var threshold = opt_threshold || [0];
247  if (!Array.isArray(threshold)) threshold = [threshold];
248
249  return threshold.sort().filter(function(t, i, a) {
250    if (typeof t != 'number' || isNaN(t) || t < 0 || t > 1) {
251      throw new Error('threshold must be a number between 0 and 1 inclusively');
252    }
253    return t !== a[i - 1];
254  });
255};
256
257
258/**
259 * Accepts the rootMargin value from the user configuration object
260 * and returns an array of the four margin values as an object c
260ontaining
261 * the value and unit properties. If any of the values are not properly
262 * formatted or use a unit other than px or %, and error is thrown.
263 * @private
264 * @param {string=} opt_rootMargin An optional rootMargin value,
265 *     defaulting to '0px'.
266 * @return {Array<Object>} An array of margin objects with the keys
267 *     value and unit.
268 */
269IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) {
270  var marginString = opt_rootMargin || '0px';
271  var margins = marginString.split(/\s+/).map(function(margin) {
272    var parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin);
273    if (!parts) {
274      throw new Error('rootMargin must be specified in pixels or percent');
275    }
276    return {value: parseFloat(parts[1]), unit: parts[2]};
277  });
278
279  // Handles shorthand.
280  margins[1] = margins[1] || margins[0];
281  margins[2] = margins[2] || margins[0];
282  margins[3] = margins[3] || margins[1];
283
284  return margins;
285};
286
287
288/**
289 * Starts polling for intersection changes if the polling is not already
290 * happening, and if the page's visibility state is visible.
291 * @private
292 */
293IntersectionObserver.prototype._monitorIntersections = function() {
294  if (!this._monitoringIntersections) {
295    this._monitoringIntersections = true;
296
297    // If a poll interval is set, use polling instead of listening to
298    // resize and scroll events or DOM mutations.
299    if (this.POLL_INTERVAL) {
300      this._monitoringInterval = setInterval(
301          this._checkForIntersections, this.POLL_INTERVAL);
302    }
303    else {
304      addEvent(window, 'resize', this._checkForIntersections, true);
305      addEvent(document, 'scroll', this._checkForIntersections, true);
306
307      if (this.USE_MUTATION_OBSERVER && 'MutationObserver' in window) {
308        this._domObserver = new MutationObserver(this._checkForIntersections);
309        this._domObserver.observe(document, {
310          attributes: true,
311          childList: true,
312          characterData: true,
313          subtree: true
314        });
315      }
316    }
317  }
318};
319
320
321/**
322 * Stops polling for intersection changes.
323 * @private
324 */
325IntersectionObserver.prototype._unmonitorIntersections = function() {
326  if (this._monitoringIntersections) {
327    this._monitoringIntersections = false;
328
329    clearInterval(this._monitoringInterval);
330    this._monitoringInterval = null;
331
332    removeEvent(window, 'resize', this._checkForIntersections, true);
333    removeEvent(document, 'scroll', this._checkForIntersections, true);
334
335    if (this._domObserver) {
336      this._domObserver.disconnect();
337      this._domObserver = null;
338    }
339  }
340};
341
342
343/**
344 * Scans each observation target for intersection changes and adds them
345 * to the internal entries queue. If new entries are found, it
346 * schedules the callback to be invoked.
347 * @private
348 */
349IntersectionObserver.prototype._checkForIntersections = function() {
350  var rootIsInDom = this._rootIsInDom();
351  var rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect();
352
353  this._observationTargets.forEach(function(item) {
354    var target = item.element;
355    var targetRect = getBoundingClientRect(target);
356    var rootContainsTarget = this._rootContainsTarget(target);
357    var oldEntry = item.entry;
358    var intersectionRect = rootIsInDom && rootContainsTarget &&
359        this._computeTargetAndRootIntersection(target, rootRect);
360
361    var newEntry = item.entry = new IntersectionObserverEntry({
362      time: now(),
363      target: target,
364      boundingClientRect: targetRect,
365      rootBounds: rootRect,
366      intersectionRect: intersectionRect
367    });
368
369    if (!oldEntry) {
370      this._queuedEntries.push(newEntry);
371    } else if (rootIsInDom && rootContainsTarget) {
372      // If the new entry intersection ratio has crossed any of the
373      // thresholds, add a new entry.
374      if (this._hasCrossedThreshold(oldEntry, newEntry)) {
375        this._queuedEntries.push(newEntry);
376      }
377    } else {
378      // If the root is not in the DOM or target is not contained within
379      // root but the previous entry for this target had an intersection,
380      // add a new record indicating removal.
381      if (oldEntry && oldEntry.isIntersecting) {
382        this._queuedEntries.push(newEntry);
383      }
384    }
385  }, this);
386
387  if (this._queuedEntries.length) {
388    this._callback(this.takeRecords(), this);
389  }
390};
391
392
393/**
394 * Accepts a target and root rect computes the intersection between then
395 * following the algorithm in the spec.
396 * TODO(philipwalton): at this time clip-path is not considered.
397 * https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo
398 * @param {Element} target The target DOM element
399 * @param {Object} rootRect The bounding rect of the root after being
400 *     expanded by the rootMargin value.
401 * @return {?Object} The final intersection rect object or undefined if no
402 *     intersection is found.
403 * @private
404 */
405IntersectionObserver.prototype._computeTargetAndRootIntersection =
406    function(target, rootRect) {
407
408  // If the element isn't displayed, an intersection can't happen.
409  if (window.getComputedStyle(target).display == 'none') return;
410
411  var targetRect = getBoundingClientRect(target);
412  var intersectionRect = targetRect;
413  var parent = getParentNode(target);
414  var atRoot = false;
vendor: 8,268 bytes, lines 415-685
415
416  while (!atRoot) {
417    var parentRect = null;
418    var parentComputedStyle = parent.nodeType == 1 ?
419        window.getComputedStyle(parent) : {};
420
421    // If the parent isn't displayed, an intersection can't happen.
422    if (parentComputedStyle.display == 'none') return;
423
424    if (parent == this.root || parent == document) {
425      atRoot = true;
426      parentRect = rootRect;
427    } else {
428      // If the element has a non-visible overflow, and it's not the <body>
429      // or <html> element, update the intersection rect.
430      // Note: <body> and <html> cannot be clipped to a rect that's not also
431      // the document rect, so no need to compute a new intersection.
432      if (parent != document.body &&
433          parent != document.documentElement &&
434          parentComputedStyle.overflow != 'visible') {
435        parentRect = getBoundingClientRect(parent);
436      }
437    }
438
439    // If either of the above conditionals set a new parentRect,
440    // calculate new intersection data.
441    if (parentRect) {
442      intersectionRect = computeRectIntersection(parentRect, intersectionRect);
443
444      if (!intersectionRect) break;
445    }
446    parent = getParentNode(parent);
447  }
448  return intersectionRect;
449};
450
451
452/**
453 * Returns the root rect after being expanded by the rootMargin value.
454 * @return {Object} The expanded root rect.
455 * @private
456 */
457IntersectionObserver.prototype._getRootRect = function() {
458  var rootRect;
459  if (this.root) {
460    rootRect = getBoundingClientRect(this.root);
461  } else {
462    // Use <html>/<body> instead of window since scroll bars affect size.
463    var html = document.documentElement;
464    var body = document.body;
465    rootRect = {
466      top: 0,
467      left: 0,
468      right: html.clientWidth || body.clientWidth,
469      width: html.clientWidth || body.clientWidth,
470      bottom: html.clientHeight || body.clientHeight,
471      height: html.clientHeight || body.clientHeight
472    };
473  }
474  return this._expandRectByRootMargin(rootRect);
475};
476
477
478/**
479 * Accepts a rect and expands it by the rootMargin value.
480 * @param {Object} rect The rect object to expand.
481 * @return {Object} The expanded rect.
482 * @private
483 */
484IntersectionObserver.prototype._expandRectByRootMargin = function(rect) {
485  var margins = this._rootMarginValues.map(function(margin, i) {
486    return margin.unit == 'px' ? margin.value :
487        margin.value * (i % 2 ? rect.width : rect.height) / 100;
488  });
489  var newRect = {
490    top: rect.top - margins[0],
491    right: rect.right + margins[1],
492    bottom: rect.bottom + margins[2],
493    left: rect.left - margins[3]
494  };
495  newRect.width = newRect.right - newRect.left;
496  newRect.height = newRect.bottom - newRect.top;
497
498  return newRect;
499};
500
501
502/**
503 * Accepts an old and new entry and returns true if at least one of the
504 * threshold values has been crossed.
505 * @param {?IntersectionObserverEntry} oldEntry The previous entry for a
506 *    particular target element or null if no previous entry exists.
507 * @param {IntersectionObserverEntry} newEntry The current entry for a
508 *    particular target element.
509 * @return {boolean} Returns true if a any threshold has been crossed.
510 * @private
511 */
512IntersectionObserver.prototype._hasCrossedThreshold =
513    function(oldEntry, newEntry) {
514
515  // To make comparing easier, an entry that has a ratio of 0
516  // but does not actually intersect is given a value of -1
517  var oldRatio = oldEntry && oldEntry.isIntersecting ?
518      oldEntry.intersectionRatio || 0 : -1;
519  var newRatio = newEntry.isIntersecting ?
520      newEntry.intersectionRatio || 0 : -1;
521
522  // Ignore unchanged ratios
523  if (oldRatio === newRatio) return;
524
525  for (var i = 0; i < this.thresholds.length; i++) {
526    var threshold = this.thresholds[i];
527
528    // Return true if an entry matches a threshold or if the new ratio
529    // and the old ratio are on the opposite sides of a threshold.
530    if (threshold == oldRatio || threshold == newRatio ||
531        threshold < oldRatio !== threshold < newRatio) {
532      return true;
533    }
534  }
535};
536
537
538/**
539 * Returns whether or not the root element is an element and is in the DOM.
540 * @return {boolean} True if the root element is an element and is in the DOM.
541 * @private
542 */
543IntersectionObserver.prototype._rootIsInDom = function() {
544  return !this.root || containsDeep(document, this.root);
545};
546
547
548/**
549 * Returns whether or not the target element is a child of root.
550 * @param {Element} target The target element to check.
551 * @return {boolean} True if the target element is a child of root.
552 * @private
553 */
554IntersectionObserver.prototype._rootContainsTarget = function(target) {
555  return containsDeep(this.root || document, target);
556};
557
558
559/**
560 * Adds the instance to the global IntersectionObserver registry if it isn't
561 * already present.
562 * @private
563 */
564IntersectionObserver.prototype._registerInstance = function() {
565  if (registry.indexOf(this) < 0) {
566    registry.push(this);
567  }
568};
569
570
571/**
572 * Removes the instance from the global IntersectionObserver registry.
573 * @private
574 */
575IntersectionObserver.prototype._unregisterInstance = function() {
576  var index = registry.indexOf(this);
577  if (index != -1) registry.splice(index, 1);
578};
579
580
581/**
582 * Returns the result of the performance.now() method or null in browsers
583 * that don't support the API.
584 * @return {number} The elapsed time since the page was requested.
585 */
586function now() {
587  return window.performance && performance.now && performance.now();
588}
589
590
591/**
592 * Throttles a function and delays its execution, so it's only called at most
593 * once within a given time period.
594 * @param {Function} fn The function to throttle.
595 * @param {number} timeout The amount of time that must pass before the
596 *     function can be called again.
597 * @return {Function} The throttled function.
598 */
599function throttle(fn, timeout) {
600  var timer = null;
601  return function () {
602    if (!timer) {
603      timer = setTimeout(function() {
604        fn();
605        timer = null;
606      }, timeout);
607    }
608  };
609}
610
611
612/**
613 * Adds an event handler to a DOM node ensuring cross-browser compatibility.
614 * @param {Node} node The DOM node to add the event handler to.
615 * @param {string} event The event name.
616 * @param {Function} fn The event handler to add.
617 * @param {boolean} opt_useCapture Optionally adds the even to the capture
618 *     phase. Note: this only works in modern browsers.
619 */
620function addEvent(node, event, fn, opt_useCapture) {
621  if (typeof node.addEventListener == 'function') {
622    node.addEventListener(event, fn, opt_useCapture || false);
623  }
624  else if (typeof node.attachEvent == 'function') {
625    node.attachEvent('on' + event, fn);
626  }
627}
628
629
630/**
631 * Removes a previously added event handler from a DOM node.
632 * @param {Node} node The DOM node to remove the event handler from.
633 * @param {string} event The event name.
634 * @param {Function} fn The event handler to remove.
635 * @param {boolean} opt_useCapture If the event handler was added with this
636 *     flag set to true, it should be set to true here in order to remove it.
637 */
638function removeEvent(node, event, fn, opt_useCapture) {
639  if (typeof node.removeEventListener == 'function') {
640    node.removeEventListener(event, fn, opt_useCapture || false);
641  }
642  else if (typeof node.detatchEvent == 'function') {
643    node.detatchEvent('on' + event, fn);
644  }
645}
646
647
648/**
649 * Returns the intersection between two rect objects.
650 * @param {Object} rect1 The first rect.
651 * @param {Object} rect2 The second rect.
652 * @return {?Object} The intersection rect or undefined if no intersection
653 *     is found.
654 */
655function computeRectIntersection(rect1, rect2) {
656  var top = Math.max(rect1.top, rect2.top);
657  var bottom = Math.min(rect1.bottom, rect2.bottom);
658  var left = Math.max(rect1.left, rect2.left);
659  var right = Math.min(rect1.right, rect2.right);
660  var width = right - left;
661  var height = bottom - top;
662
663  return (width >= 0 && height >= 0) && {
664    top: top,
665    bottom: bottom,
666    left: left,
667    right: right,
668    width: width,
669    height: height
670  };
671}
672
673
674/**
675 * Shims the native getBoundingClientRect for compatibility with older IE.
676 * @param {Element} el The element whose bounding rect to get.
677 * @return {Object} The (possibly shimmed) rect of the element.
678 */
679function getBoundingClientRect(el) {
680  var rect;
681
682  try {
683    rect = el.getBoundingClientRect();
684  } catch (err) {
685    // Ignore Windows 7 IE11 "Unspecified error"
686    // https://github.com/w3c/IntersectionObserver/pull/205
687  }
688
689  if (!rect) return getEmptyRect();
690
691  // Older IE
692  if (!(rect.width && rect.height)) {
693    rect = {
694      top: rect.top,
695      right: rect.right,
696      bottom: rect.bottom,
697      left: rect.left,
698      width: rect.right - rect.left,
699      height: rect.bottom - rect.top
700    };
701  }
702  return rect;
703}
704
705
706/**
707 * Returns an empty rect object. An empty rect is returned when an element
708 * is not in the DOM.
709 * @return {Object} The empty rect.
710 */
711function getEmptyRect() {
712  return {
713    top: 0,
714    bottom: 0,
715    left: 0,
716    right: 0,
717    width: 0,
718    height: 0
719  };
720}
721
722/**
723 * Checks to see if a parent element contains a child element (including inside
724 * shadow DOM).
725 * @param {Node} parent The parent element.
726 * @param {Node} child The child element.
727 * @return {boolean} True if the parent node contains the child node.
728 */
729function containsDeep(parent, child) {
730  var node = child;
731  while (node) {
732    if (node == parent) return true;
733
734    node = getParentNode(node);
735  }
736  return false;
737}
738
739
740/**
741 * Gets the parent node of an element or its host element if the parent node
742 * is a shadow root.
743 * @param {Node} node The node whose parent to get.
744 * @return {Node|null} The parent node or null if no parent exists.
745 */
746function getParentNode(node) {
747  var parent = node.parentNode;
748
749  if (parent && parent.nodeType == 11 && parent.host) {
750    // If the parent is a shadow root, return the host element.
751    return parent.host;
752  }
753
754  if (parent && parent.assignedSlot) {
755    // If the parent is distributed in a <slot>, return the parent of a slot.
756    return parent.assignedSlot.parentNode;
757  }
758
759  return parent;
760}
761
762
763// Exposes the constructors globally.
764window.IntersectionObserver = IntersectionObserver;
765window.IntersectionObserverEntry = IntersectionObserverEntry;
766
767}());
768
769
770/***/ }),
771
772/***/ 360:
773/***/ (() => {
774
775/*
776CSS Browser Selector js v0.5.3 (July 2, 2013)
777
778-- original --
779Rafael Lima (http://rafael.adm.br)
780http://rafael.adm.br/css_browser_selector
781License: http://creativecommons.org/licenses/by/2.5/
782Contributors: http://rafael.adm.br/css_browser_selector#contributors
783-- /original --
784
785Fork project: http://code.google.com/p/css-browser-selector/
786Song Hyo-Jin (shj at xenosi.de)
787*/
788function css_browser_selector(n) {
789  var b = n.toLowerCase(),
790    f = function (c) {
791      return b.indexOf(c) > -1;
792    },
793    h = "gecko",
794    k = "webkit",
795    p = "safari",
796    j = "chrome",
797    d = "opera",
798    e = "mobile",
799    l = 0,
800    a = window.devicePixelRatio ? (window.devicePixelRatio + "").replace(".", "_") : "1",
801    re = '';
802  var i = [!/opera|webtv/.test(b) && /msie\s(\d+)/.test(b) && (l = RegExp.$1 * 1) ? "ie ie" + l + (l == 6 || l == 7 ? " ie67 ie678 ie6789" : l == 8 ? " ie678 ie6789" : l == 9 ? " ie6789 ie9m" : l > 9 ? " ie9m" : "") : /firefox\/(\d+)\.(\d+)/.test(b) && (re = RegExp) ? h + " ff ff" + re.$1 + " ff" + re.$1 + "_" + re.$2 : f("gecko/") ? h : f(d) ? d + (/version\/(\d+)/.test(b) ? " " + d + RegExp.$1 : /opera(\s|\/)(\d+)/.test(b) ? " " + d + RegExp.$2 : "") : f("konqueror") ? "konqueror" : f("blackberry") ? e + " blackberry" : f(j) || f("crios") ? k + " " + j : f("iron") ? k + " iron" : !f("cpu os") && f("applewebkit/") ? k + " " + p : f("mozilla/") ? h : "", f("android") ? e + " android" : "", f("tablet") ? "tablet" : "", f("j2me") ? e + " j2me" : f("ipad; u; cpu os") ? e + " chrome android tablet" : f("ipad;u;cpu os") ? e + " chromedef android tablet" : f("iphone") ? e + " ios iphone" : f("ipod") ? e + " ios ipod" : f("ipad") ? e + " ios ipad tablet" : f("mac") ? "mac" : f("darwin") ? "mac" : f("webtv") ? "webtv" : f("win") ? "win" + (f("windows nt 6.0") ? " vista" : "") : f("freebsd") ? "freebsd" : f("x11") || f("linux") ? "linux" : "", a != "1" ? " retina ratio" + a : "", "js portrait"].join(" ");
803  if (window.jQuery && !window.jQuery.browser) {
804    window.jQuery.browser = l ? {
805      msie: 1,
806      version: l
807    } : {};
808  }
809  return i;
810}
811(function (j, b) {
812  var c = css_browser_selector(navigator.userAgent);
813  var g = j.documentElement;
814  g.className += " " + c;
815  var a = c.replace(/^\s*|\s*$/g, "").split(/ +/);
816  b.CSSBS = 1;
817  for (var f = 0; f < a.length; f++) {
818    b["CSSBS_" + a[f]] = 1;
819  }
820  var e = function (d) {
821    return j.documentElement[d] || j.body[d];
822  };
823  if (b.jQuery) {
824    (function (q) {
825      var h = "portrait",
826        k = "landscape";
827      var i = "smartnarrow",
828        u = "smartwide",
829        x = "tabletnarrow",
830        r = "tabletwide",
831        w = i + " " + u + " " + x + " " + r + " pc";
832      var v = q(g);
833      var s = 0,
834        o = 0;
835      function d() {
836        if (s != 0) {
837          return;
838        }
839        try {
840          var l = e("clientWidth"),
841            p = e("clientHeight");
842          if (l > p) {
843            v.removeClass(h).addClass(k);
844          } else {
845            v.removeClass(k).addClass(h);
846          }
847          if (l == o) {
848            return;
849          }
850          o = l;
851        } catch (m) {}
852        s = setTimeout(n, 100);
853      }
854      function n() {
855        try {
856          v.removeClass(w);
857          v.addClass(o <= 360 ? i : o <= 640 ? u : o <= 768 ? x : o <= 1024 ? r : "pc");
858        } catch (l) {}
859        s = 0;
860      }
861      if (b.CSSBS_ie) {
862        setInterval(d, 1000);
863      } else {
864        q(b).on("resize orientationchange", d).trigger("resize");
865      }
866    })(b.jQuery);
867  }
868})(document, window);
869if (navigator.userAgent.indexOf("Windows") > -1 && navigator.userAgent.indexOf("rv:11.0") > -1) {
870  $('html').addClass('ie11 ie');
871}
872
873/***/ }),
874
875/***/ 692:
876/***/ (function(module, exports) {
877
878var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
879 * jQuery JavaScript Library v3.7.1
880 * https://jquery.com/
881 *
882 * Copyright OpenJS Foundation and other contributors
883 * Released under the MIT license
884 * https://jquery.org/license
885 *
886 * Date: 2023-08-28T13:37Z
887 */
888( function( global, factory ) {
889
890	"use strict";
891
892	if (  true
vendor: 284,319 bytes, lines 892-11553
892 && typeof module.exports === "object" ) {
893
894		// For CommonJS and CommonJS-like environments where a proper `window`
895		// is present, execute the factory and get jQuery.
896		// For environments that do not have a `window` with a `document`
897		// (such as Node.js), expose a factory as module.exports.
898		// This accentuates the need for the creation of a real `window`.
899		// e.g. var jQuery = require("jquery")(window);
900		// See ticket trac-14549 for more info.
901		module.exports = global.document ?
902			factory( global, true ) :
903			function( w ) {
904				if ( !w.document ) {
905					throw new Error( "jQuery requires a window with a document" );
906				}
907				return factory( w );
908			};
909	} else {
910		factory( global );
911	}
912
913// Pass this if window is not defined yet
914} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
915
916// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
917// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
918// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
919// enough that all such attempts are guarded in a try block.
920"use strict";
921
922var arr = [];
923
924var getProto = Object.getPrototypeOf;
925
926var slice = arr.slice;
927
928var flat = arr.flat ? function( array ) {
929	return arr.flat.call( array );
930} : function( array ) {
931	return arr.concat.apply( [], array );
932};
933
934
935var push = arr.push;
936
937var indexOf = arr.indexOf;
938
939var class2type = {};
940
941var toString = class2type.toString;
942
943var hasOwn = class2type.hasOwnProperty;
944
945var fnToString = hasOwn.toString;
946
947var ObjectFunctionString = fnToString.call( Object );
948
949var support = {};
950
951var isFunction = function isFunction( obj ) {
952
953		// Support: Chrome <=57, Firefox <=52
954		// In some browsers, typeof returns "function" for HTML <object> elements
955		// (i.e., `typeof document.createElement( "object" ) === "function"`).
956		// We don't want to classify *any* DOM node as a function.
957		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
958		// Plus for old WebKit, typeof returns "function" for HTML collections
959		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
960		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
961			typeof obj.item !== "function";
962	};
963
964
965var isWindow = function isWindow( obj ) {
966		return obj != null && obj === obj.window;
967	};
968
969
970var document = window.document;
971
972
973
974	var preservedScriptAttributes = {
975		type: true,
976		src: true,
977		nonce: true,
978		noModule: true
979	};
980
981	function DOMEval( code, node, doc ) {
982		doc = doc || document;
983
984		var i, val,
985			script = doc.createElement( "script" );
986
987		script.text = code;
988		if ( node ) {
989			for ( i in preservedScriptAttributes ) {
990
991				// Support: Firefox 64+, Edge 18+
992				// Some browsers don't support the "nonce" property on scripts.
993				// On the other hand, just using `getAttribute` is not enough as
994				// the `nonce` attribute is reset to an empty string whenever it
995				// becomes browsing-context connected.
996				// See https://github.com/whatwg/html/issues/2369
997				// See https://html.spec.whatwg.org/#nonce-attributes
998				// The `node.getAttribute` check was added for the sake of
999				// `jQuery.globalEval` so that it can fake a nonce-containing node
1000				// via an object.
1001				val = node[ i ] || node.getAttribute && node.getAttribute( i );
1002				if ( val ) {
1003					script.setAttribute( i, val );
1004				}
1005			}
1006		}
1007		doc.head.appendChild( script ).parentNode.removeChild( script );
1008	}
1009
1010
1011function toType( obj ) {
1012	if ( obj == null ) {
1013		return obj + "";
1014	}
1015
1016	// Support: Android <=2.3 only (functionish RegExp)
1017	return typeof obj === "object" || typeof obj === "function" ?
1018		class2type[ toString.call( obj ) ] || "object" :
1019		typeof obj;
1020}
1021/* global Symbol */
1022// Defining this global in .eslintrc.json would create a danger of using the global
1023// unguarded in another place, it seems safer to define global only for this module
1024
1025
1026
1027var version = "3.7.1",
1028
1029	rhtmlSuffix = /HTML$/i,
1030
1031	// Define a local copy of jQuery
1032	jQuery = function( selector, context ) {
1033
1034		// The jQuery object is actually just the init constructor 'enhanced'
1035		// Need init if jQuery is called (just allow error to be thrown if not included)
1036		return new jQuery.fn.init( selector, context );
1037	};
1038
1039jQuery.fn = jQuery.prototype = {
1040
1041	// The current version of jQuery being used
1042	jquery: version,
1043
1044	constructor: jQuery,
1045
1046	// The default length of a jQuery object is 0
1047	length: 0,
1048
1049	toArray: function() {
1050		return slice.call( this );
1051	},
1052
1053	// Get the Nth element in the matched element set OR
1054	// Get the whole matched element set as a clean array
1055	get: function( num ) {
1056
1057		// Return all the elements in a clean array
1058		if ( num == null ) {
1059			return slice.call( this );
1060		}
1061
1062		// Return just the one element from the set
1063		return num < 0 ? this[ num + this.length ] : this[ num ];
1064	},
1065
1066	// Take an array of elements and push it onto the stack
1067	// (returning the new matched element set)
1068	pushStack: function( elems ) {
1069
1070		// Build a new jQuery matched element set
1071		var ret = jQuery.merge( this.constructor(), elems );
1072
1073		// Add the old object onto the stack (as a reference)
1074		ret.prevObject = this;
1075
1076		// Return the newly-formed element set
1077		return ret;
1078	},
1079
1080	// Execute a callback for every element in the matched set.
1081	each: function( callback ) {
1082		return jQuery.each( this, callback );
1083	},
1084
1085	map: function( callback ) {
1086		return this.pushStack( jQuery.map( this, function( elem, i ) {
1087			return callback.call( elem, i, elem );
1088		} ) );
1089	},
1090
1091	slice: function() {
1092		return this.pushStack( slice.apply( this, arguments ) );
1093	},
1094
1095	first: function() {
1096		return this.eq( 0 );
1097	},
1098
1099	last: function() {
1100		return this.eq( -1 );
1101	},
1102
1103	even: function() {
1104		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
1105			return ( i + 1 ) % 2;
1106		} ) );
1107	},
1108
1109	odd: function() {
1110		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
1111			return i % 2;
1112		} ) );
1113	},
1114
1115	eq: function( i ) {
1116		var len = this.length,
1117			j = +i + ( i < 0 ? len : 0 );
1118		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
1119	},
1120
1121	end: function() {
1122		return this.prevObject || this.constructor();
1123	},
1124
1125	// For internal use only.
1126	// Behaves like an Array's method, not like a jQuery method.
1127	push: push,
1128	sort: arr.sort,
1129	splice: arr.splice
1130};
1131
1132jQuery.extend = jQuery.fn.extend = function() {
1133	var options, name, src, copy, copyIsArray, clone,
1134		target = arguments[ 0 ] || {},
1135		i = 1,
1136		length = arguments.length,
1137		deep = false;
1138
1139	// Handle a deep copy situation
1140	if ( typeof target === "boolean" ) {
1141		deep = target;
1142
1143		// Skip the boolean and the target
1144		target = arguments[ i ] || {};
1145		i++;
1146	}
1147
1148	// Handle case when target is a string or something (possible in deep copy)
1149	if ( typeof target !== "object" && !isFunction( target ) ) {
1150		target = {};
1151	}
1152
1153	// Extend jQuery itself if only one argument is passed
1154	if ( i === length ) {
1155		target = this;
1156		i--;
1157	}
1158
1159	for ( ; i < length; i++ ) {
1160
1161		// Only deal with non-null/undefined values
1162		if ( ( options = arguments[ i ] ) != null ) {
1163
1164			// Extend the base object
1165			for ( name in options ) {
1166				copy = options[ name ];
1167
1168				// Prevent Object.prototype pollution
1169				// Prevent never-ending loop
1170				if ( name === "__proto__" || target === copy ) {
1171					continue;
1172				}
1173
1174				// Recurse if we're merging plain objects or arrays
1175				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
1176					( copyIsArray = Array.isArray( copy ) ) ) ) {
1177					src = target[ name ];
1178
1179					// Ensure proper type for the source value
1180					if ( copyIsArray && !Array.isArray( src ) ) {
1181						clone = [];
1182					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
1183						clone = {};
1184					} else {
1185						clone = src;
1186					}
1187					copyIsArray = false;
1188
1189					// Never move original objects, clone them
1190					target[ name ] = jQuery.extend( deep, clone, copy );
1191
1192				// Don't bring in undefined values
1193				} else if ( copy !== undefined ) {
1194					target[ name ] = copy;
1195				}
1196			}
1197		}
1198	}
1199
1200	// Return the modified object
1201	return target;
1202};
1203
1204jQuery.extend( {
1205
1206	// Unique for each copy of jQuery on the page
1207	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
1208
1209	// Assume jQuery is ready without the ready module
1210	isReady: true,
1211
1212	error: function( msg ) {
1213		throw new Error( msg );
1214	},
1215
1216	noop: function() {},
1217
1218	isPlainObject: function( obj ) {
1219		var proto, Ctor;
1220
1221		// Detect obvious negatives
1222		// Use toString instead of jQuery.type to catch host objects
1223		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
1224			return false;
1225		}
1226
1227		proto = getProto( obj );
1228
1229		// Objects with no prototype (e.g., `Object.create( null )`) are plain
1230		if ( !proto ) {
1231			return true;
1232		}
1233
1234		// Objects with prototype are plain iff they were constructed by a global Object function
1235		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
1236		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
1237	},
1238
1239	isEmptyObject: function( obj ) {
1240		var name;
1241
1242		for ( name in obj ) {
1243			return false;
1244		}
1245		return true;
1246	},
1247
1248	// Evaluates a script in a provided context; falls back to the global one
1249	// if not specified.
1250	globalEval: function( code, options, doc ) {
1251		DOMEval( code, { nonce: options && options.nonce }, doc );
1252	},
1253
1254	each: function( obj, callback ) {
1255		var length, i = 0;
1256
1257		if ( isArrayLike( obj ) ) {
1258			length = obj.length;
1259			for ( ; i < length; i++ ) {
1260				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
1261					break;
1262				}
1263			}
1264		} else {
1265			for ( i in obj ) {
1266				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
1267					break;
1268				}
1269			}
1270		}
1271
1272		return obj;
1273	},
1274
1275
1276	// Retrieve the text value of an array of DOM nodes
1277	text: function( elem ) {
1278		var node,
1279			ret = "",
1280			i = 0,
1281			nodeType = elem.nodeType;
1282
1283		if ( !nodeType ) {
1284
1285			// If no nodeType, this is expected to be an array
1286			while ( ( node = elem[ i++ ] ) ) {
1287
1288				// Do not traverse comment nodes
1289				ret += jQuery.text( node );
1290			}
1291		}
1292		if ( nodeType === 1 || nodeType === 11 ) {
1293			return elem.textContent;
1294		}
1295		if ( nodeType === 9 ) {
1296			return elem.documentElement.textContent;
1297		}
1298		if ( nodeType === 3 || nodeType === 4 ) {
1299			return elem.nodeValue;
1300		}
1301
1302		// Do not include comment or processing instruction nodes
1303
1304		return ret;
1305	},
1306
1307	// results is for internal usage only
1308	makeArray: function( arr, results ) {
1309		var ret = results || [];
1310
1311		if ( arr != null ) {
1312			if ( isArrayLike( Object( arr ) ) ) {
1313				jQuery.merge( ret,
1314					typeof arr === "string" ?
1315						[ arr ] : arr
1316				);
1317			} else {
1318				push.call( ret, arr );
1319			}
1320		}
1321
1322		return ret;
1323	},
1324
1325	inArray: function( elem, arr, i ) {
1326		return arr == null ? -1 : indexOf.call( arr, elem, i );
1327	},
1328
1329	isXMLDoc: function( elem ) {
1330		var namespace = elem && elem.namespaceURI,
1331			docElem = elem && ( elem.ownerDocument || elem ).documentElement;
1332
1333		// Assume HTML when documentElement doesn't yet exist, such as inside
1334		// document fragments.
1335		return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );
1336	},
1337
1338	// Support: Android <=4.0 only, PhantomJS 1 only
1339	// push.apply(_, arraylike) throws on ancient WebKit
1340	merge: function( first, second ) {
1341		var len = +second.length,
1342			j = 0,
1343			i = first.length;
1344
1345		for ( ; j < len; j++ ) {
1346			first[ i++ ] = second[ j ];
1347		}
1348
1349		first.length = i;
1350
1351		return first;
1352	},
1353
1354	grep: function( elems, callback, invert ) {
1355		var callbackInverse,
1356			matches = [],
1357			i = 0,
1358			length = elems.length,
1359			callbackExpect = !invert;
1360
1361		// Go through the array, only saving the items
1362		// that pass the validator function
1363		for ( ; i < length; i++ ) {
1364			callbackInverse = !callback( elems[ i ], i );
1365			if ( callbackInverse !== callbackExpect ) {
1366				matches.push( elems[ i ] );
1367			}
1368		}
1369
1370		return matches;
1371	},
1372
1373	// arg is for internal usage only
1374	map: function( elems, callback, arg ) {
1375		var length, value,
1376			i = 0,
1377			ret = [];
1378
1379		// Go through the array, translating each of the items to their new values
1380		if ( isArrayLike( elems ) ) {
1381			length = elems.length;
1382			for ( ; i < length; i++ ) {
1383				value = callback( elems[ i ], i, arg );
1384
1385				if ( value != null ) {
1386					ret.push( value );
1387				}
1388			}
1389
1390		// Go through every key on the object,
1391		} else {
1392			for ( i in elems ) {
1393				value = callback( elems[ i ], i, arg );
1394
1395				if ( value != null ) {
1396					ret.push( value );
1397				}
1398			}
1399		}
1400
1401		// Flatten any nested arrays
1402		return flat( ret );
1403	},
1404
1405	// A global GUID counter for objects
1406	guid: 1,
1407
1408	// jQuery.support is not used in Core but other projects attach their
1409	// properties to it so it needs to exist.
1410	support: support
1411} );
1412
1413if ( typeof Symbol === "function" ) {
1414	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
1415}
1416
1417// Populate the class2type map
1418jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
1419	function( _i, name ) {
1420		class2type[ "[object " + name + "]" ] = name.toLowerCase();
1421	} );
1422
1423function isArrayLike( obj ) {
1424
1425	// Support: real iOS 8.2 only (not reproducible in simulator)
1426	// `in` check used to prevent JIT error (gh-2145)
1427	// hasOwn isn't used here due to false negatives
1428	// regarding Nodelist length in IE
1429	var length = !!obj && "length" in obj && obj.length,
1430		type = toType( obj );
1431
1432	if ( isFunction( obj ) || isWindow( obj ) ) {
1433		return false;
1434	}
1435
1436	return type === "array" || length === 0 ||
1437		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
1438}
1439
1440
1441function nodeName( elem, name ) {
1442
1443	return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
1444
1445}
1446var pop = arr.pop;
1447
1448
1449var sort = arr.sort;
1450
1451
1452var splice = arr.splice;
1453
1454
1455var whitespace = "[\\x20\\t\\r\\n\\f]";
1456
1457
1458var rtrimCSS = new RegExp(
1459	"^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
1460	"g"
1461);
1462
1463
1464
1465
1466// Note: an element does not contain itself
1467jQuery.contains = function( a, b ) {
1468	var bup = b && b.parentNode;
1469
1470	return a === bup || !!( bup && bup.nodeType === 1 && (
1471
1472		// Support: IE 9 - 11+
1473		// IE doesn't have `contains` on SVG.
1474		a.contains ?
1475			a.contains( bup ) :
1476			a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1477	) );
1478};
1479
1480
1481
1482
1483// CSS string/identifier serialization
1484// https://drafts.csswg.org/cssom/#common-serializing-idioms
1485var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
1486
1487function fcssescape( ch, asCodePoint ) {
1488	if ( asCodePoint ) {
1489
1490		// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
1491		if ( ch === "\0" ) {
1492			return "\uFFFD";
1493		}
1494
1495		// Control characters and (dependent upon position) numbers get escaped as code points
1496		return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
1497	}
1498
1499	// Other potentially-special ASCII characters get backslash-escaped
1500	return "\\" + ch;
1501}
1502
1503jQuery.escapeSelector = function( sel ) {
1504	return ( sel + "" ).replace( rcssescape, fcssescape );
1505};
1506
1507
1508
1509
1510var preferredDoc = document,
1511	pushNative = push;
1512
1513( function() {
1514
1515var i,
1516	Expr,
1517	outermostContext,
1518	sortInput,
1519	hasDuplicate,
1520	push = pushNative,
1521
1522	// Local document vars
1523	document,
1524	documentElement,
1525	documentIsHTML,
1526	rbuggyQSA,
1527	matches,
1528
1529	// Instance-specific data
1530	expando = jQuery.expando,
1531	dirruns = 0,
1532	done = 0,
1533	classCache = createCache(),
1534	tokenCache = createCache(),
1535	compilerCache = createCache(),
1536	nonnativeSelectorCache = createCache(),
1537	sortOrder = function( a, b ) {
1538		if ( a === b ) {
1539			hasDuplicate = true;
1540		}
1541		return 0;
1542	},
1543
1544	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
1545		"loop|multiple|open|readonly|required|scoped",
1546
1547	// Regular expressions
1548
1549	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
1550	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
1551		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
1552
1553	// Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
1554	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
1555
1556		// Operator (capture 2)
1557		"*([*^$|!~]?=)" + whitespace +
1558
1559		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
1560		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
1561		whitespace + "*\\]",
1562
1563	pseudos = ":(" + identifier + ")(?:\\((" +
1564
1565		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
1566		// 1. quoted (capture 3; capture 4 or capture 5)
1567		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
1568
1569		// 2. simple (capture 6)
1570		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
1571
1572		// 3. anything else (capture 2)
1573		".*" +
1574		")\\)|)",
1575
1576	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
1577	rwhitespace = new RegExp( whitespace + "+", "g" ),
1578
1579	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
1580	rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" +
1581		whitespace + "*" ),
1582	rdescend = new RegExp( whitespace + "|>" ),
1583
1584	rpseudo = new RegExp( pseudos ),
1585	ridentifier = new RegExp( "^" + identifier + "$" ),
1586
1587	matchExpr = {
1588		ID: new RegExp( "^#(" + identifier + ")" ),
1589		CLASS: new RegExp( "^\\.(" + identifier + ")" ),
1590		TAG: new RegExp( "^(" + identifier + "|[*])" ),
1591		ATTR: new RegExp( "^" + attributes ),
1592		PSEUDO: new RegExp( "^" + pseudos ),
1593		CHILD: new RegExp(
1594			"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
1595				whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
1596				whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
1597		bool: new RegExp( "^(?:" + booleans + ")$", "i" ),
1598
1599		// For use in libraries implementing .is()
1600		// We use this for POS matching in `select`
1601		needsContext: new RegExp( "^" + whitespace +
1602			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
1603			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
1604	},
1605
1606	rinputs = /^(?:input|select|textarea|button)$/i,
1607	rheader = /^h\d$/i,
1608
1609	// Easily-parseable/retrievable ID or TAG or CLASS selectors
1610	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
1611
1612	rsibling = /[+~]/,
1613
1614	// CSS escapes
1615	// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1616	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace +
1617		"?|\\\\([^\\r\\n\\f])", "g" ),
1618	funescape = function( escape, nonHex ) {
1619		var high = "0x" + escape.slice( 1 ) - 0x10000;
1620
1621		if ( nonHex ) {
1622
1623			// Strip the backslash prefix from a non-hex escape sequence
1624			return nonHex;
1625		}
1626
1627		// Replace a hexadecimal escape sequence with the encoded Unicode code point
1628		// Support: IE <=11+
1629		// For values outside the Basic Multilingual Plane (BMP), manually construct a
1630		// surrogate pair
1631		return high < 0 ?
1632			String.fromCharCode( high + 0x10000 ) :
1633			String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1634	},
1635
1636	// Used for iframes; see `setDocument`.
1637	// Support: IE 9 - 11+, Edge 12 - 18+
1638	// Removing the function wrapper causes a "Permission Denied"
1639	// error in IE/Edge.
1640	unloadHandler = function() {
1641		setDocument();
1642	},
1643
1644	inDisabledFieldset = addCombinator(
1645		function( elem ) {
1646			return elem.disabled === true && nodeName( elem, "fieldset" );
1647		},
1648		{ dir: "parentNode", next: "legend" }
1649	);
1650
1651// Support: IE <=9 only
1652// Accessing document.activeElement can throw unexpectedly
1653// https://bugs.jquery.com/ticket/13393
1654function safeActiveElement() {
1655	try {
1656		return document.activeElement;
1657	} catch ( err ) { }
1658}
1659
1660// Optimize for push.apply( _, NodeList )
1661try {
1662	push.apply(
1663		( arr = slice.call( preferredDoc.childNodes ) ),
1664		preferredDoc.childNodes
1665	);
1666
1667	// Support: Android <=4.0
1668	// Detect silently failing push.apply
1669	// eslint-disable-next-line no-unused-expressions
1670	arr[ preferredDoc.childNodes.length ].nodeType;
1671} catch ( e ) {
1672	push = {
1673		apply: function( target, els ) {
1674			pushNative.apply( target, slice.call( els ) );
1675		},
1676		call: function( target ) {
1677			pushNative.apply( target, slice.call( arguments, 1 ) );
1678		}
1679	};
1680}
1681
1682function find( selector, context, results, seed ) {
1683	var m, i, elem, nid, match, groups, newSelector,
1684		newContext = context && context.ownerDocument,
1685
1686		// nodeType defaults to 9, since context defaults to document
1687		nodeType = context ? context.nodeType : 9;
1688
1689	results = results || [];
1690
1691	// Return early from calls with invalid selector or context
1692	if ( typeof selector !== "string" || !selector ||
1693		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
1694
1695		return results;
1696	}
1697
1698	// Try to shortcut find operations (as opposed to filters) in HTML documents
1699	if ( !seed ) {
1700		setDocument( context );
1701		context = context || document;
1702
1703		if ( documentIsHTML ) {
1704
1705			// If the selector is sufficiently simple, try using a "get*By*" DOM method
1706			// (excepting DocumentFragment context, where the methods don't exist)
1707			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
1708
1709				// ID selector
1710				if ( ( m = match[ 1 ] ) ) {
1711
1712					// Document context
1713					if ( nodeType === 9 ) {
1714						if ( ( elem = context.getElementById( m ) ) ) {
1715
1716							// Support: IE 9 only
1717							// getElementById can match elements by name instead of ID
1718							if ( elem.id === m ) {
1719								push.call( results, elem );
1720								return results;
1721							}
1722						} else {
1723							return results;
1724						}
1725
1726					// Element context
1727					} else {
1728
1729						// Support: IE 9 only
1730						// getElementById can match elements by name instead of ID
1731						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
1732							find.contains( context, elem ) &&
1733							elem.id === m ) {
1734
1735							push.call( results, elem );
1736							return results;
1737						}
1738					}
1739
1740				// Type selector
1741				} else if ( match[ 2 ] ) {
1742					push.apply( results, context.getElementsByTagName( selector ) );
1743					return results;
1744
1745				// Class selector
1746				} else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
1747					push.apply( results, context.getElementsByClassName( m ) );
1748					return results;
1749				}
1750			}
1751
1752			// Take advantage of querySelectorAll
1753			if ( !nonnativeSelectorCache[ selector + " " ] &&
1754				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {
1755
1756				newSelector = selector;
1757				newContext = context;
1758
1759				// qSA considers elements outside a scoping root when evaluating child or
1760				// descendant combinators, which is not what we want.
1761				// In such cases, we work around the behavior by prefixing every selector in the
1762				// list with an ID selector referencing the scope context.
1763				// The technique has to be used as well when a leading combinator is used
1764				// as such selectors are not recognized by querySelectorAll.
1765				// Thanks to Andrew Dupont for this technique.
1766				if ( nodeType === 1 &&
1767					( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
1768
1769					// Expand context for sibling selectors
1770					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
1771						context;
1772
1773					// We can use :scope instead of the ID hack if the browser
1774					// supports it & if we're not changing the context.
1775					// Support: IE 11+, Edge 17 - 18+
1776					// IE/Edge sometimes throw a "Permission denied" error when
1777					// strict-comparing two documents; shallow comparisons work.
1778					// eslint-disable-next-line eqeqeq
1779					if ( newContext != context || !support.scope ) {
1780
1781						// Capture the context ID, setting it first if necessary
1782						if ( ( nid = context.getAttribute( "id" ) ) ) {
1783							nid = jQuery.escapeSelector( nid );
1784						} else {
1785							context.setAttribute( "id", ( nid = expando ) );
1786						}
1787					}
1788
1789					// Prefix every selector in the list
1790					groups = tokenize( selector );
1791					i = groups.length;
1792					while ( i-- ) {
1793						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
1794							toSelector( groups[ i ] );
1795					}
1796					newSelector = groups.join( "," );
1797				}
1798
1799				try {
1800					push.apply( results,
1801						newContext.querySelectorAll( newSelector )
1802					);
1803					return results;
1804				} catch ( qsaError ) {
1805					nonnativeSelectorCache( selector, true );
1806				} finally {
1807					if ( nid === expando ) {
1808						context.removeAttribute( "id" );
1809					}
1810				}
1811			}
1812		}
1813	}
1814
1815	// All others
1816	return select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
1817}
1818
1819/**
1820 * Create key-value caches of limited size
1821 * @returns {function(string, object)} Returns the Object data after storing it on itself with
1822 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1823 *	deleting the oldest entry
1824 */
1825function createCache() {
1826	var keys = [];
1827
1828	function cache( key, value ) {
1829
1830		// Use (key + " ") to avoid collision with native prototype properties
1831		// (see https://github.com/jquery/sizzle/issues/157)
1832		if ( keys.push( key + " " ) > Expr.cacheLength ) {
1833
1834			// Only keep the most recent entries
1835			delete cache[ keys.shift() ];
1836		}
1837		return ( cache[ key + " " ] = value );
1838	}
1839	return cache;
1840}
1841
1842/**
1843 * Mark a function for special use by jQuery selector module
1844 * @param {Function} fn The function to mark
1845 */
1846function markFunction( fn ) {
1847	fn[ expando ] = true;
1848	return fn;
1849}
1850
1851/**
1852 * Support testing using an element
1853 * @param {Function} fn Passed the created element and returns a boolean result
1854 */
1855function assert( fn ) {
1856	var el = document.createElement( "fieldset" );
1857
1858	try {
1859		return !!fn( el );
1860	} catch ( e ) {
1861		return false;
1862	} finally {
1863
1864		// Remove from its parent by default
1865		if ( el.parentNode ) {
1866			el.parentNode.removeChild( el );
1867		}
1868
1869		// release memory in IE
1870		el = null;
1871	}
1872}
1873
1874/**
1875 * Returns a function to use in pseudos for input types
1876 * @param {String} type
1877 */
1878function createInputPseudo( type ) {
1879	return function( elem ) {
1880		return nodeName( elem, "input" ) && elem.type === type;
1881	};
1882}
1883
1884/**
1885 * Returns a function to use in pseudos for buttons
1886 * @param {String} type
1887 */
1888function createButtonPseudo( type ) {
1889	return function( elem ) {
1890		return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&
1891			elem.type === type;
1892	};
1893}
1894
1895/**
1896 * Returns a function to use in pseudos for :enabled/:disabled
1897 * @param {Boolean} disabled true for :disabled; false for :enabled
1898 */
1899function createDisabledPseudo( disabled ) {
1900
1901	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1902	return function( elem ) {
1903
1904		// Only certain elements can match :enabled or :disabled
1905		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1906		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1907		if ( "form" in elem ) {
1908
1909			// Check for inherited disabledness on relevant non-disabled elements:
1910			// * listed form-associated elements in a disabled fieldset
1911			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1912			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1913			// * option elements in a disabled optgroup
1914			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1915			// All such elements have a "form" property.
1916			if ( elem.parentNode && elem.disabled === false ) {
1917
1918				// Option elements defer to a parent optgroup if present
1919				if ( "label" in elem ) {
1920					if ( "label" in elem.parentNode ) {
1921						return elem.parentNode.disabled === disabled;
1922					} else {
1923						return elem.disabled === disabled;
1924					}
1925				}
1926
1927				// Support: IE 6 - 11+
1928				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
1929				return elem.isDisabled === disabled ||
1930
1931					// Where there is no isDisabled, check manually
1932					elem.isDisabled !== !disabled &&
1933						inDisabledFieldset( elem ) === disabled;
1934			}
1935
1936			return elem.disabled === disabled;
1937
1938		// Try to winnow out elements that can't be disabled before trusting the disabled property.
1939		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1940		// even exist on them, let alone have a boolean value.
1941		} else if ( "label" in elem ) {
1942			return elem.disabled === disabled;
1943		}
1944
1945		// Remaining elements are neither :enabled nor :disabled
1946		return false;
1947	};
1948}
1949
1950/**
1951 * Returns a function to use in pseudos for positionals
1952 * @param {Function} fn
1953 */
1954function createPositionalPseudo( fn ) {
1955	return markFunction( function( argument ) {
1956		argument = +argument;
1957		return markFunction( function( seed, matches ) {
1958			var j,
1959				matchIndexes = fn( [], seed.length, argument ),
1960				i = matchIndexes.length;
1961
1962			// Match elements found at the specified indexes
1963			while ( i-- ) {
1964				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1965					seed[ j ] = !( matches[ j ] = seed[ j ] );
1966				}
1967			}
1968		} );
1969	} );
1970}
1971
1972/**
1973 * Checks a node for validity as a jQuery selector context
1974 * @param {Element|Object=} context
1975 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1976 */
1977function testContext( context ) {
1978	return context && typeof context.getElementsByTagName !== "undefined" && context;
1979}
1980
1981/**
1982 * Sets document-related variables once based on the current document
1983 * @param {Element|Object} [node] An element or document object to use to set the document
1984 * @returns {Object} Returns the current document
1985 */
1986function setDocument( node ) {
1987	var subWindow,
1988		doc = node ? node.ownerDocument || node : preferredDoc;
1989
1990	// Return early if doc is invalid or already selected
1991	// Support: IE 11+, Edge 17 - 18+
1992	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1993	// two documents; shallow comparisons work.
1994	// eslint-disable-next-line eqeqeq
1995	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1996		return document;
1997	}
1998
1999	// Update global variables
2000	document = doc;
2001	documentElement = document.documentElement;
2002	documentIsHTML = !jQuery.isXMLDoc( document );
2003
2004	// Support: iOS 7 only, IE 9 - 11+
2005	// Older browsers didn't support unprefixed `matches`.
2006	matches = documentElement.matches ||
2007		documentElement.webkitMatchesSelector ||
2008		documentElement.msMatchesSelector;
2009
2010	// Support: IE 9 - 11+, Edge 12 - 18+
2011	// Accessing iframe documents after unload throws "permission denied" errors
2012	// (see trac-13936).
2013	// Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
2014	// all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
2015	if ( documentElement.msMatchesSelector &&
2016
2017		// Support: IE 11+, Edge 17 - 18+
2018		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2019		// two documents; shallow comparisons work.
2020		// eslint-disable-next-line eqeqeq
2021		preferredDoc != document &&
2022		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
2023
2024		// Support: IE 9 - 11+, Edge 12 - 18+
2025		subWindow.addEventListener( "unload", unloadHandler );
2026	}
2027
2028	// Support: IE <10
2029	// Check if getElementById returns elements by name
2030	// The broken getElementById methods don't pick up programmatically-set names,
2031	// so use a roundabout getElementsByName test
2032	support.getById = assert( function( el ) {
2033		documentElement.appendChild( el ).id = jQuery.expando;
2034		return !document.getElementsByName ||
2035			!document.getElementsByName( jQuery.expando ).length;
2036	} );
2037
2038	// Support: IE 9 only
2039	// Check to see if it's possible to do matchesSelector
2040	// on a disconnected node.
2041	support.disconnectedMatch = assert( function( el ) {
2042		return matches.call( el, "*" );
2043	} );
2044
2045	// Support: IE 9 - 11+, Edge 12 - 18+
2046	// IE/Edge don't support the :scope pseudo-class.
2047	support.scope = assert( function() {
2048		return document.querySelectorAll( ":scope" );
2049	} );
2050
2051	// Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
2052	// Make sure the `:has()` argument is parsed unforgivingly.
2053	// We include `*` in the test to detect buggy implementations that are
2054	// _selectively_ forgiving (specifically when the list includes at least
2055	// one valid selector).
2056	// Note that we treat complete lack of support for `:has()` as if it were
2057	// spec-compliant support, which is fine because use of `:has()` in such
2058	// environments will fail in the qSA path and fall back to jQuery traversal
2059	// anyway.
2060	support.cssHas = assert( function() {
2061		try {
2062			document.querySelector( ":has(*,:jqfake)" );
2063			return false;
2064		} catch ( e ) {
2065			return true;
2066		}
2067	} );
2068
2069	// ID filter and find
2070	if ( support.getById ) {
2071		Expr.filter.ID = function( id ) {
2072			var attrId = id.replace( runescape, funescape );
2073			return function( elem ) {
2074				return elem.getAttribute( "id" ) === attrId;
2075			};
2076		};
2077		Expr.find.ID = function( id, context ) {
2078			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
2079				var elem = context.getElementById( id );
2080				return elem ? [ elem ] : [];
2081			}
2082		};
2083	} else {
2084		Expr.filter.ID =  function( id ) {
2085			var attrId = id.replace( runescape, funescape );
2086			return function( elem ) {
2087				var node = typeof elem.getAttributeNode !== "undefined" &&
2088					elem.getAttributeNode( "id" );
2089				return node && node.value === attrId;
2090			};
2091		};
2092
2093		// Support: IE 6 - 7 only
2094		// getElementById is not reliable as a find shortcut
2095		Expr.find.ID = function( id, context ) {
2096			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
2097				var node, i, elems,
2098					elem = context.getElementById( id );
2099
2100				if ( elem ) {
2101
2102					// Verify the id attribute
2103					node = elem.getAttributeNode( "id" );
2104					if ( node && node.value === id ) {
2105						return [ elem ];
2106					}
2107
2108					// Fall back on getElementsByName
2109					elems = context.getElementsByName( id );
2110					i = 0;
2111					while ( ( elem = elems[ i++ ] ) ) {
2112						node = elem.getAttributeNode( "id" );
2113						if ( node && node.value === id ) {
2114							return [ elem ];
2115						}
2116					}
2117				}
2118
2119				return [];
2120			}
2121		};
2122	}
2123
2124	// Tag
2125	Expr.find.TAG = function( tag, context ) {
2126		if ( typeof context.getElementsByTagName !== "undefined" ) {
2127			return context.getElementsByTagName( tag );
2128
2129		// DocumentFragment nodes don't have gEBTN
2130		} else {
2131			return context.querySelectorAll( tag );
2132		}
2133	};
2134
2135	// Class
2136	Expr.find.CLASS = function( className, context ) {
2137		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
2138			return context.getElementsByClassName( className );
2139		}
2140	};
2141
2142	/* QSA/matchesSelector
2143	---------------------------------------------------------------------- */
2144
2145	// QSA and matchesSelector support
2146
2147	rbuggyQSA = [];
2148
2149	// Build QSA regex
2150	// Regex strategy adopted from Diego Perini
2151	assert( function( el ) {
2152
2153		var input;
2154
2155		documentElement.appendChild( el ).innerHTML =
2156			"<a id='" + expando + "' href='' disabled='disabled'></a>" +
2157			"<select id='" + expando + "-\r\\' disabled='disabled'>" +
2158			"<option selected=''></option></select>";
2159
2160		// Support: iOS <=7 - 8 only
2161		// Boolean attributes and "value" are not treated correctly in some XML documents
2162		if ( !el.querySelectorAll( "[selected]" ).length ) {
2163			rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
2164		}
2165
2166		// Support: iOS <=7 - 8 only
2167		if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
2168			rbuggyQSA.push( "~=" );
2169		}
2170
2171		// Support: iOS 8 only
2172		// https://bugs.webkit.org/show_bug.cgi?id=136851
2173		// In-page `selector#id sibling-combinator selector` fails
2174		if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
2175			rbuggyQSA.push( ".#.+[+~]" );
2176		}
2177
2178		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
2179		// In some of the document kinds, these selectors wouldn't work natively.
2180		// This is probably OK but for backwards compatibility we want to maintain
2181		// handling them through jQuery traversal in jQuery 3.x.
2182		if ( !el.querySelectorAll( ":checked" ).length ) {
2183			rbuggyQSA.push( ":checked" );
2184		}
2185
2186		// Support: Windows 8 Native Apps
2187		// The type and name attributes are restricted during .innerHTML assignment
2188		input = document.createElement( "input" );
2189		input.setAttribute( "type", "hidden" );
2190		el.appendChild( input ).setAttribute( "name", "D" );
2191
2192		// Support: IE 9 - 11+
2193		// IE's :disabled selector does not pick up the children of disabled fieldsets
2194		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
2195		// In some of the document kinds, these selectors wouldn't work natively.
2196		// This is probably OK but for backwards compatibility we want to maintain
2197		// handling them through jQuery traversal in jQuery 3.x.
2198		documentElement.appendChild( el ).disabled = true;
2199		if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
2200			rbuggyQSA.push( ":enabled", ":disabled" );
2201		}
2202
2203		// Support: IE 11+, Edge 15 - 18+
2204		// IE 11/Edge don't find elements on a `[name='']` query in some cases.
2205		// Adding a temporary attribute to the document before the selection works
2206		// around the issue.
2207		// Interestingly, IE 10 & older don't seem to have the issue.
2208		input = document.createElement( "input" );
2209		input.setAttribute( "name", "" );
2210		el.appendChild( input );
2211		if ( !el.querySelectorAll( "[name='']" ).length ) {
2212			rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
2213				whitespace + "*(?:''|\"\")" );
2214		}
2215	} );
2216
2217	if ( !support.cssHas ) {
2218
2219		// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
2220		// Our regular `try-catch` mechanism fails to detect natively-unsupported
2221		// pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
2222		// in browsers that parse the `:has()` argument as a forgiving selector list.
2223		// https://drafts.csswg.org/selectors/#relational now requires the argument
2224		// to be parsed unforgivingly, but browsers have not yet fully adjusted.
2225		rbuggyQSA.push( ":has" );
2226	}
2227
2228	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
2229
2230	/* Sorting
2231	---------------------------------------------------------------------- */
2232
2233	// Document order sorting
2234	sortOrder = function( a, b ) {
2235
2236		// Flag for duplicate removal
2237		if ( a === b ) {
2238			hasDuplicate = true;
2239			return 0;
2240		}
2241
2242		// Sort on method existence if only one input has compareDocumentPosition
2243		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
2244		if ( compare ) {
2245			return compare;
2246		}
2247
2248		// Calculate position if both inputs belong to the same document
2249		// Support: IE 11+, Edge 17 - 18+
2250		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2251		// two documents; shallow comparisons work.
2252		// eslint-disable-next-line eqeqeq
2253		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
2254			a.compareDocumentPosition( b ) :
2255
2256			// Otherwise we know they are disconnected
2257			1;
2258
2259		// Disconnected nodes
2260		if ( compare & 1 ||
2261			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
2262
2263			// Choose the first element that is related to our preferred document
2264			// Support: IE 11+, Edge 17 - 18+
2265			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2266			// two documents; shallow comparisons work.
2267			// eslint-disable-next-line eqeqeq
2268			if ( a === document || a.ownerDocument == preferredDoc &&
2269				find.contains( preferredDoc, a ) ) {
2270				return -1;
2271			}
2272
2273			// Support: IE 11+, Edge 17 - 18+
2274			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2275			// two documents; shallow comparisons work.
2276			// eslint-disable-next-line eqeqeq
2277			if ( b === document || b.ownerDocument == preferredDoc &&
2278				find.contains( preferredDoc, b ) ) {
2279				return 1;
2280			}
2281
2282			// Maintain original order
2283			return sortInput ?
2284				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
2285				0;
2286		}
2287
2288		return compare & 4 ? -1 : 1;
2289	};
2290
2291	return document;
2292}
2293
2294find.matches = function( expr, elements ) {
2295	return find( expr, null, null, elements );
2296};
2297
2298find.matchesSelector = function( elem, expr ) {
2299	setDocument( elem );
2300
2301	if ( documentIsHTML &&
2302		!nonnativeSelectorCache[ expr + " " ] &&
2303		( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
2304
2305		try {
2306			var ret = matches.call( elem, expr );
2307
2308			// IE 9's matchesSelector returns false on disconnected nodes
2309			if ( ret || support.disconnectedMatch ||
2310
2311					// As well, disconnected nodes are said to be in a document
2312					// fragment in IE 9
2313					elem.document && elem.document.nodeType !== 11 ) {
2314				return ret;
2315			}
2316		} catch ( e ) {
2317			nonnativeSelectorCache( expr, true );
2318		}
2319	}
2320
2321	return find( expr, document, null, [ elem ] ).length > 0;
2322};
2323
2324find.contains = function( context, elem ) {
2325
2326	// Set document vars if needed
2327	// Support: IE 11+, Edge 17 - 18+
2328	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2329	// two documents; shallow comparisons work.
2330	// eslint-disable-next-line eqeqeq
2331	if ( ( context.ownerDocument || context ) != document ) {
2332		setDocument( context );
2333	}
2334	return jQuery.contains( context, elem );
2335};
2336
2337
2338find.attr = function( elem, name ) {
2339
2340	// Set document vars if needed
2341	// Support: IE 11+, Edge 17 - 18+
2342	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2343	// two documents; shallow comparisons work.
2344	// eslint-disable-next-line eqeqeq
2345	if ( ( elem.ownerDocument || elem ) != document ) {
2346		setDocument( elem );
2347	}
2348
2349	var fn = Expr.attrHandle[ name.toLowerCase() ],
2350
2351		// Don't get fooled by Object.prototype properties (see trac-13807)
2352		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
2353			fn( elem, name, !documentIsHTML ) :
2354			undefined;
2355
2356	if ( val !== undefined ) {
2357		return val;
2358	}
2359
2360	return elem.getAttribute( name );
2361};
2362
2363find.error = function( msg ) {
2364	throw new Error( "Syntax error, unrecognized expression: " + msg );
2365};
2366
2367/**
2368 * Document sorting and removing duplicates
2369 * @param {ArrayLike} results
2370 */
2371jQuery.uniqueSort = function( results ) {
2372	var elem,
2373		duplicates = [],
2374		j = 0,
2375		i = 0;
2376
2377	// Unless we *know* we can detect duplicates, assume their presence
2378	//
2379	// Support: Android <=4.0+
2380	// Testing for detecting duplicates is unpredictable so instead assume we can't
2381	// depend on duplicate detection in all browsers without a stable sort.
2382	hasDuplicate = !support.sortStable;
2383	sortInput = !support.sortStable && slice.call( results, 0 );
2384	sort.call( results, sortOrder );
2385
2386	if ( hasDuplicate ) {
2387		while ( ( elem = results[ i++ ] ) ) {
2388			if ( elem === results[ i ] ) {
2389				j = duplicates.push( i );
2390			}
2391		}
2392		while ( j-- ) {
2393			splice.call( results, duplicates[ j ], 1 );
2394		}
2395	}
2396
2397	// Clear input after sorting to release objects
2398	// See https://github.com/jquery/sizzle/pull/225
2399	sortInput = null;
2400
2401	return results;
2402};
2403
2404jQuery.fn.uniqueSort = function() {
2405	return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) );
2406};
2407
2408Expr = jQuery.expr = {
2409
2410	// Can be adjusted by the user
2411	cacheLength: 50,
2412
2413	createPseudo: markFunction,
2414
2415	match: matchExpr,
2416
2417	attrHandle: {},
2418
2419	find: {},
2420
2421	relative: {
2422		">": { dir: "parentNode", first: true },
2423		" ": { dir: "parentNode" },
2424		"+": { dir: "previousSibling", first: true },
2425		"~": { dir: "previousSibling" }
2426	},
2427
2428	preFilter: {
2429		ATTR: function( match ) {
2430			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
2431
2432			// Move the given value to match[3] whether quoted or unquoted
2433			match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" )
2434				.replace( runescape, funescape );
2435
2436			if ( match[ 2 ] === "~=" ) {
2437				match[ 3 ] = " " + match[ 3 ] + " ";
2438			}
2439
2440			return match.slice( 0, 4 );
2441		},
2442
2443		CHILD: function( match ) {
2444
2445			/* matches from matchExpr["CHILD"]
2446				1 type (only|nth|...)
2447				2 what (child|of-type)
2448				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
2449				4 xn-component of xn+y argument ([+-]?\d*n|)
2450				5 sign of xn-component
2451				6 x of xn-component
2452				7 sign of y-component
2453				8 y of y-component
2454			*/
2455			match[ 1 ] = match[ 1 ].toLowerCase();
2456
2457			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
2458
2459				// nth-* requires argument
2460				if ( !match[ 3 ] ) {
2461					find.error( match[ 0 ] );
2462				}
2463
2464				// numeric x and y parameters for Expr.filter.CHILD
2465				// remember that false/true cast respectively to 0/1
2466				match[ 4 ] = +( match[ 4 ] ?
2467					match[ 5 ] + ( match[ 6 ] || 1 ) :
2468					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )
2469				);
2470				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
2471
2472			// other types prohibit arguments
2473			} else if ( match[ 3 ] ) {
2474				find.error( match[ 0 ] );
2475			}
2476
2477			return match;
2478		},
2479
2480		PSEUDO: function( match ) {
2481			var excess,
2482				unquoted = !match[ 6 ] && match[ 2 ];
2483
2484			if ( matchExpr.CHILD.test( match[ 0 ] ) ) {
2485				return null;
2486			}
2487
2488			// Accept quoted arguments as-is
2489			if ( match[ 3 ] ) {
2490				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
2491
2492			// Strip excess characters from unquoted arguments
2493			} else if ( unquoted && rpseudo.test( unquoted ) &&
2494
2495				// Get excess from tokenize (recursively)
2496				( excess = tokenize( unquoted, true ) ) &&
2497
2498				// advance to the next closing parenthesis
2499				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
2500
2501				// excess is a negative index
2502				match[ 0 ] = match[ 0 ].slice( 0, excess );
2503				match[ 2 ] = unquoted.slice( 0, excess );
2504			}
2505
2506			// Return only captures needed by the pseudo filter method (type and argument)
2507			return match.slice( 0, 3 );
2508		}
2509	},
2510
2511	filter: {
2512
2513		TAG: function( nodeNameSelector ) {
2514			var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
2515			return nodeNameSelector === "*" ?
2516				function() {
2517					return true;
2518				} :
2519				function( elem ) {
2520					return nodeName( elem, expectedNodeName );
2521				};
2522		},
2523
2524		CLASS: function( className ) {
2525			var pattern = classCache[ className + " " ];
2526
2527			return pattern ||
2528				( pattern = new RegExp( "(^|" + whitespace + ")" + className +
2529					"(" + whitespace + "|$)" ) ) &&
2530				classCache( className, function( elem ) {
2531					return pattern.test(
2532						typeof elem.className === "string" && elem.className ||
2533							typeof elem.getAttribute !== "undefined" &&
2534								elem.getAttribute( "class" ) ||
2535							""
2536					);
2537				} );
2538		},
2539
2540		ATTR: function( name, operator, check ) {
2541			return function( elem ) {
2542				var result = find.attr( elem, name );
2543
2544				if ( result == null ) {
2545					return operator === "!=";
2546				}
2547				if ( !operator ) {
2548					return true;
2549				}
2550
2551				result += "";
2552
2553				if ( operator === "=" ) {
2554					return result === check;
2555				}
2556				if ( operator === "!=" ) {
2557					return result !== check;
2558				}
2559				if ( operator === "^=" ) {
2560					return check && result.indexOf( check ) === 0;
2561				}
2562				if ( operator === "*=" ) {
2563					return check && result.indexOf( check ) > -1;
2564				}
2565				if ( operator === "$=" ) {
2566					return check && result.slice( -check.length ) === check;
2567				}
2568				if ( operator === "~=" ) {
2569					return ( " " + result.replace( rwhitespace, " " ) + " " )
2570						.indexOf( check ) > -1;
2571				}
2572				if ( operator === "|=" ) {
2573					return result === check || result.slice( 0, check.length + 1 ) === check + "-";
2574				}
2575
2576				return false;
2577			};
2578		},
2579
2580		CHILD: function( type, what, _argument, first, last ) {
2581			var simple = type.slice( 0, 3 ) !== "nth",
2582				forward = type.slice( -4 ) !== "last",
2583				ofType = what === "of-type";
2584
2585			return first === 1 && last === 0 ?
2586
2587				// Shortcut for :nth-*(n)
2588				function( elem ) {
2589					return !!elem.parentNode;
2590				} :
2591
2592				function( elem, _context, xml ) {
2593					var cache, outerCache, node, nodeIndex, start,
2594						dir = simple !== forward ? "nextSibling" : "previousSibling",
2595						parent = elem.parentNode,
2596						name = ofType && elem.nodeName.toLowerCase(),
2597						useCache = !xml && !ofType,
2598						diff = false;
2599
2600					if ( parent ) {
2601
2602						// :(first|last|only)-(child|of-type)
2603						if ( simple ) {
2604							while ( dir ) {
2605								node = elem;
2606								while ( ( node = node[ dir ] ) ) {
2607									if ( ofType ?
2608										nodeName( node, name ) :
2609										node.nodeType === 1 ) {
2610
2611										return false;
2612									}
2613								}
2614
2615								// Reverse direction for :only-* (if we haven't yet done so)
2616								start = dir = type === "only" && !start && "nextSibling";
2617							}
2618							return true;
2619						}
2620
2621						start = [ forward ? parent.firstChild : parent.lastChild ];
2622
2623						// non-xml :nth-child(...) stores cache data on `parent`
2624						if ( forward && useCache ) {
2625
2626							// Seek `elem` from a previously-cached index
2627							outerCache = parent[ expando ] || ( parent[ expando ] = {} );
2628							cache = outerCache[ type ] || [];
2629							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2630							diff = nodeIndex && cache[ 2 ];
2631							node = nodeIndex && parent.childNodes[ nodeIndex ];
2632
2633							while ( ( node = ++nodeIndex && node && node[ dir ] ||
2634
2635								// Fallback to seeking `elem` from the start
2636								( diff = nodeIndex = 0 ) || start.pop() ) ) {
2637
2638								// When found, cache indexes on `parent` and break
2639								if ( node.nodeType === 1 && ++diff && node === elem ) {
2640									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
2641									break;
2642								}
2643							}
2644
2645						} else {
2646
2647							// Use previously-cached element index if available
2648							if ( useCache ) {
2649								outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2650								cache = outerCache[ type ] || [];
2651								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2652								diff = nodeIndex;
2653							}
2654
2655							// xml :nth-child(...)
2656							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
2657							if ( diff === false ) {
2658
2659								// Use the same loop as above to seek `elem` from the start
2660								while ( ( node = ++nodeIndex && node && node[ dir ] ||
2661									( diff = nodeIndex = 0 ) || start.pop() ) ) {
2662
2663									if ( ( ofType ?
2664										nodeName( node, name ) :
2665										node.nodeType === 1 ) &&
2666										++diff ) {
2667
2668										// Cache the index of each encountered element
2669										if ( useCache ) {
2670											outerCache = node[ expando ] ||
2671												( node[ expando ] = {} );
2672											outerCache[ type ] = [ dirruns, diff ];
2673										}
2674
2675										if ( node === elem ) {
2676											break;
2677										}
2678									}
2679								}
2680							}
2681						}
2682
2683						// Incorporate the offset, then check against cycle size
2684						diff -= last;
2685						return diff === first || ( diff % first === 0 && diff / first >= 0 );
2686					}
2687				};
2688		},
2689
2690		PSEUDO: function( pseudo, argument ) {
2691
2692			// pseudo-class names are case-insensitive
2693			// https://www.w3.org/TR/selectors/#pseudo-classes
2694			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2695			// Remember that setFilters inherits from pseudos
2696			var args,
2697				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2698					find.error( "unsupported pseudo: " + pseudo );
2699
2700			// The user may use createPseudo to indicate that
2701			// arguments are needed to create the filter function
2702			// just as jQuery does
2703			if ( fn[ expando ] ) {
2704				return fn( argument );
2705			}
2706
2707			// But maintain support for old signatures
2708			if ( fn.length > 1 ) {
2709				args = [ pseudo, pseudo, "", argument ];
2710				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2711					markFunction( function( seed, matches ) {
2712						var idx,
2713							matched = fn( seed, argument ),
2714							i = matched.length;
2715						while ( i-- ) {
2716							idx = indexOf.call( seed, matched[ i ] );
2717							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2718						}
2719					} ) :
2720					function( elem ) {
2721						return fn( elem, 0, args );
2722					};
2723			}
2724
2725			return fn;
2726		}
2727	},
2728
2729	pseudos: {
2730
2731		// Potentially complex pseudos
2732		not: markFunction( function( selector ) {
2733
2734			// Trim the selector passed to compile
2735			// to avoid treating leading and trailing
2736			// spaces as combinators
2737			var input = [],
2738				results = [],
2739				matcher = compile( selector.replace( rtrimCSS, "$1" ) );
2740
2741			return matcher[ expando ] ?
2742				markFunction( function( seed, matches, _context, xml ) {
2743					var elem,
2744						unmatched = matcher( seed, null, xml, [] ),
2745						i = seed.length;
2746
2747					// Match elements unmatched by `matcher`
2748					while ( i-- ) {
2749						if ( ( elem = unmatched[ i ] ) ) {
2750							seed[ i ] = !( matches[ i ] = elem );
2751						}
2752					}
2753				} ) :
2754				function( elem, _context, xml ) {
2755					input[ 0 ] = elem;
2756					matcher( input, null, xml, results );
2757
2758					// Don't keep the element
2759					// (see https://github.com/jquery/sizzle/issues/299)
2760					input[ 0 ] = null;
2761					return !results.pop();
2762				};
2763		} ),
2764
2765		has: markFunction( function( selector ) {
2766			return function( elem ) {
2767				return find( selector, elem ).length > 0;
2768			};
2769		} ),
2770
2771		contains: markFunction( function( text ) {
2772			text = text.replace( runescape, funescape );
2773			return function( elem ) {
2774				return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
2775			};
2776		} ),
2777
2778		// "Whether an element is represented by a :lang() selector
2779		// is based solely on the element's language value
2780		// being equal to the identifier C,
2781		// or beginning with the identifier C immediately followed by "-".
2782		// The matching of C against the element's language value is performed case-insensitively.
2783		// The identifier C does not have to be a valid language name."
2784		// https://www.w3.org/TR/selectors/#lang-pseudo
2785		lang: markFunction( function( lang ) {
2786
2787			// lang value must be a valid identifier
2788			if ( !ridentifier.test( lang || "" ) ) {
2789				find.error( "unsupported lang: " + lang );
2790			}
2791			lang = lang.replace( runescape, funescape ).toLowerCase();
2792			return function( elem ) {
2793				var elemLang;
2794				do {
2795					if ( ( elemLang = documentIsHTML ?
2796						elem.lang :
2797						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2798
2799						elemLang = elemLang.toLowerCase();
2800						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2801					}
2802				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2803				return false;
2804			};
2805		} ),
2806
2807		// Miscellaneous
2808		target: function( elem ) {
2809			var hash = window.location && window.location.hash;
2810			return hash && hash.slice( 1 ) === elem.id;
2811		},
2812
2813		root: function( elem ) {
2814			return elem === documentElement;
2815		},
2816
2817		focus: function( elem ) {
2818			return elem === safeActiveElement() &&
2819				document.hasFocus() &&
2820				!!( elem.type || elem.href || ~elem.tabIndex );
2821		},
2822
2823		// Boolean properties
2824		enabled: createDisabledPseudo( false ),
2825		disabled: createDisabledPseudo( true ),
2826
2827		checked: function( elem ) {
2828
2829			// In CSS3, :checked should return both checked and selected elements
2830			// https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2831			return ( nodeName( elem, "input" ) && !!elem.checked ) ||
2832				( nodeName( elem, "option" ) && !!elem.selected );
2833		},
2834
2835		selected: function( elem ) {
2836
2837			// Support: IE <=11+
2838			// Accessing the selectedIndex property
2839			// forces the browser to treat the default option as
2840			// selected when in an optgroup.
2841			if ( elem.parentNode ) {
2842				// eslint-disable-next-line no-unused-expressions
2843				elem.parentNode.selectedIndex;
2844			}
2845
2846			return elem.selected === true;
2847		},
2848
2849		// Contents
2850		empty: function( elem ) {
2851
2852			// https://www.w3.org/TR/selectors/#empty-pseudo
2853			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2854			//   but not by others (comment: 8; processing instruction: 7; etc.)
2855			// nodeType < 6 works because attributes (2) do not appear as children
2856			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2857				if ( elem.nodeType < 6 ) {
2858					return false;
2859				}
2860			}
2861			return true;
2862		},
2863
2864		parent: function( elem ) {
2865			return !Expr.pseudos.empty( elem );
2866		},
2867
2868		// Element/input types
2869		header: function( elem ) {
2870			return rheader.test( elem.nodeName );
2871		},
2872
2873		input: function( elem ) {
2874			return rinputs.test( elem.nodeName );
2875		},
2876
2877		button: function( elem ) {
2878			return nodeName( elem, "input" ) && elem.type === "button" ||
2879				nodeName( elem, "button" );
2880		},
2881
2882		text: function( elem ) {
2883			var attr;
2884			return nodeName( elem, "input" ) && elem.type === "text" &&
2885
2886				// Support: IE <10 only
2887				// New HTML5 attribute values (e.g., "search") appear
2888				// with elem.type === "text"
2889				( ( attr = elem.getAttribute( "type" ) ) == null ||
2890					attr.toLowerCase() === "text" );
2891		},
2892
2893		// Position-in-collection
2894		first: createPositionalPseudo( function() {
2895			return [ 0 ];
2896		} ),
2897
2898		last: createPositionalPseudo( function( _matchIndexes, length ) {
2899			return [ length - 1 ];
2900		} ),
2901
2902		eq: createPositionalPseudo( function( _matchIndexes, length, argument ) {
2903			return [ argument < 0 ? argument + length : argument ];
2904		} ),
2905
2906		even: createPositionalPseudo( function( matchIndexes, length ) {
2907			var i = 0;
2908			for ( ; i < length; i += 2 ) {
2909				matchIndexes.push( i );
2910			}
2911			return matchIndexes;
2912		} ),
2913
2914		odd: createPositionalPseudo( function( matchIndexes, length ) {
2915			var i = 1;
2916			for ( ; i < length; i += 2 ) {
2917				matchIndexes.push( i );
2918			}
2919			return matchIndexes;
2920		} ),
2921
2922		lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
2923			var i;
2924
2925			if ( argument < 0 ) {
2926				i = argument + length;
2927			} else if ( argument > length ) {
2928				i = length;
2929			} else {
2930				i = argument;
2931			}
2932
2933			for ( ; --i >= 0; ) {
2934				matchIndexes.push( i );
2935			}
2936			return matchIndexes;
2937		} ),
2938
2939		gt: createPositionalPseudo( function( matchIndexes, length, argument ) {
2940			var i = argument < 0 ? argument + length : argument;
2941			for ( ; ++i < length; ) {
2942				matchIndexes.push( i );
2943			}
2944			return matchIndexes;
2945		} )
2946	}
2947};
2948
2949Expr.pseudos.nth = Expr.pseudos.eq;
2950
2951// Add button/input type pseudos
2952for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2953	Expr.pseudos[ i ] = createInputPseudo( i );
2954}
2955for ( i in { submit: true, reset: true } ) {
2956	Expr.pseudos[ i ] = createButtonPseudo( i );
2957}
2958
2959// Easy API for creating new setFilters
2960function setFilters() {}
2961setFilters.prototype = Expr.filters = Expr.pseudos;
2962Expr.setFilters = new setFilters();
2963
2964function tokenize( selector, parseOnly ) {
2965	var matched, match, tokens, type,
2966		soFar, groups, preFilters,
2967		cached = tokenCache[ selector + " " ];
2968
2969	if ( cached ) {
2970		return parseOnly ? 0 : cached.slice( 0 );
2971	}
2972
2973	soFar = selector;
2974	groups = [];
2975	preFilters = Expr.preFilter;
2976
2977	while ( soFar ) {
2978
2979		// Comma and first run
2980		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2981			if ( match ) {
2982
2983				// Don't consume trailing commas as valid
2984				soFar = soFar.slice( match[ 0 ].length ) || soFar;
2985			}
2986			groups.push( ( tokens = [] ) );
2987		}
2988
2989		matched = false;
2990
2991		// Combinators
2992		if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
2993			matched = match.shift();
2994			tokens.push( {
2995				value: matched,
2996
2997				// Cast descendant combinators to space
2998				type: match[ 0 ].replace( rtrimCSS, " " )
2999			} );
3000			soFar = soFar.slice( matched.length );
3001		}
3002
3003		// Filters
3004		for ( type in Expr.filter ) {
3005			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
3006				( match = preFilters[ type ]( match ) ) ) ) {
3007				matched = match.shift();
3008				tokens.push( {
3009					value: matched,
3010					type: type,
3011					matches: match
3012				} );
3013				soFar = soFar.slice( matched.length );
3014			}
3015		}
3016
3017		if ( !matched ) {
3018			break;
3019		}
3020	}
3021
3022	// Return the length of the invalid excess
3023	// if we're just parsing
3024	// Otherwise, throw an error or return tokens
3025	if ( parseOnly ) {
3026		return soFar.length;
3027	}
3028
3029	return soFar ?
3030		find.error( selector ) :
3031
3032		// Cache the tokens
3033		tokenCache( selector, groups ).slice( 0 );
3034}
3035
3036function toSelector( tokens ) {
3037	var i = 0,
3038		len = tokens.length,
3039		selector = "";
3040	for ( ; i < len; i++ ) {
3041		selector += tokens[ i ].value;
3042	}
3043	return selector;
3044}
3045
3046function addCombinator( matcher, combinator, base ) {
3047	var dir = combinator.dir,
3048		skip = combinator.next,
3049		key = skip || dir,
3050		checkNonElements = base && key === "parentNode",
3051		doneName = done++;
3052
3053	return combinator.first ?
3054
3055		// Check against closest ancestor/preceding element
3056		function( elem, context, xml ) {
3057			while ( ( elem = elem[ dir ] ) ) {
3058				if ( elem.nodeType === 1 || checkNonElements ) {
3059					return matcher( elem, context, xml );
3060				}
3061			}
3062			return false;
3063		} :
3064
3065		// Check against all ancestor/preceding elements
3066		function( elem, context, xml ) {
3067			var oldCache, outerCache,
3068				newCache = [ dirruns, doneName ];
3069
3070			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
3071			if ( xml ) {
3072				while ( ( elem = elem[ dir ] ) ) {
3073					if ( elem.nodeType === 1 || checkNonElements ) {
3074						if ( matcher( elem, context, xml ) ) {
3075							return true;
3076						}
3077					}
3078				}
3079			} else {
3080				while ( ( elem = elem[ dir ] ) ) {
3081					if ( elem.nodeType === 1 || checkNonElements ) {
3082						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
3083
3084						if ( skip && nodeName( elem, skip ) ) {
3085							elem = elem[ dir ] || elem;
3086						} else if ( ( oldCache = outerCache[ key ] ) &&
3087							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
3088
3089							// Assign to newCache so results back-propagate to previous elements
3090							return ( newCache[ 2 ] = oldCache[ 2 ] );
3091						} else {
3092
3093							// Reuse newcache so results back-propagate to previous elements
3094							outerCache[ key ] = newCache;
3095
3096							// A match means we're done; a fail means we have to keep checking
3097							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
3098								return true;
3099							}
3100						}
3101					}
3102				}
3103			}
3104			return false;
3105		};
3106}
3107
3108function elementMatcher( matchers ) {
3109	return matchers.length > 1 ?
3110		function( elem, context, xml ) {
3111			var i = matchers.length;
3112			while ( i-- ) {
3113				if ( !matchers[ i ]( elem, context, xml ) ) {
3114					return false;
3115				}
3116			}
3117			return true;
3118		} :
3119		matchers[ 0 ];
3120}
3121
3122function multipleContexts( selector, contexts, results ) {
3123	var i = 0,
3124		len = contexts.length;
3125	for ( ; i < len; i++ ) {
3126		find( selector, contexts[ i ], results );
3127	}
3128	return results;
3129}
3130
3131function condense( unmatched, map, filter, context, xml ) {
3132	var elem,
3133		newUnmatched = [],
3134		i = 0,
3135		len = unmatched.length,
3136		mapped = map != null;
3137
3138	for ( ; i < len; i++ ) {
3139		if ( ( elem = unmatched[ i ] ) ) {
3140			if ( !filter || filter( elem, context, xml ) ) {
3141				newUnmatched.push( elem );
3142				if ( mapped ) {
3143					map.push( i );
3144				}
3145			}
3146		}
3147	}
3148
3149	return newUnmatched;
3150}
3151
3152function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
3153	if ( postFilter && !postFilter[ expando ] ) {
3154		postFilter = setMatcher( postFilter );
3155	}
3156	if ( postFinder && !postFinder[ expando ] ) {
3157		postFinder = setMatcher( postFinder, postSelector );
3158	}
3159	return markFunction( function( seed, results, context, xml ) {
3160		var temp, i, elem, matcherOut,
3161			preMap = [],
3162			postMap = [],
3163			preexisting = results.length,
3164
3165			// Get initial elements from seed or context
3166			elems = seed ||
3167				multipleContexts( selector || "*",
3168					context.nodeType ? [ context ] : context, [] ),
3169
3170			// Prefilter to get matcher input, preserving a map for seed-results synchronization
3171			matcherIn = preFilter && ( seed || !selector ) ?
3172				condense( elems, preMap, preFilter, context, xml ) :
3173				elems;
3174
3175		if ( matcher ) {
3176
3177			// If we have a postFinder, or filtered seed, or non-seed postFilter
3178			// or preexisting results,
3179			matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
3180
3181				// ...intermediate processing is necessary
3182				[] :
3183
3184				// ...otherwise use results directly
3185				results;
3186
3187			// Find primary matches
3188			matcher( matcherIn, matcherOut, context, xml );
3189		} else {
3190			matcherOut = matcherIn;
3191		}
3192
3193		// Apply postFilter
3194		if ( postFilter ) {
3195			temp = condense( matcherOut, postMap );
3196			postFilter( temp, [], context, xml );
3197
3198			// Un-match failing elements by moving them back to matcherIn
3199			i = temp.length;
3200			while ( i-- ) {
3201				if ( ( elem = temp[ i ] ) ) {
3202					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
3203				}
3204			}
3205		}
3206
3207		if ( seed ) {
3208			if ( postFinder || preFilter ) {
3209				if ( postFinder ) {
3210
3211					// Get the final matcherOut by condensing this intermediate into postFinder contexts
3212					temp = [];
3213					i = matcherOut.length;
3214					while ( i-- ) {
3215						if ( ( elem = matcherOut[ i ] ) ) {
3216
3217							// Restore matcherIn since elem is not yet a final match
3218							temp.push( ( matcherIn[ i ] = elem ) );
3219						}
3220					}
3221					postFinder( null, ( matcherOut = [] ), temp, xml );
3222				}
3223
3224				// Move matched elements from seed to results to keep them synchronized
3225				i = matcherOut.length;
3226				while ( i-- ) {
3227					if ( ( elem = matcherOut[ i ] ) &&
3228						( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {
3229
3230						seed[ temp ] = !( results[ temp ] = elem );
3231					}
3232				}
3233			}
3234
3235		// Add elements to results, through postFinder if defined
3236		} else {
3237			matcherOut = condense(
3238				matcherOut === results ?
3239					matcherOut.splice( preexisting, matcherOut.length ) :
3240					matcherOut
3241			);
3242			if ( postFinder ) {
3243				postFinder( null, results, matcherOut, xml );
3244			} else {
3245				push.apply( results, matcherOut );
3246			}
3247		}
3248	} );
3249}
3250
3251function matcherFromTokens( tokens ) {
3252	var checkContext, matcher, j,
3253		len = tokens.length,
3254		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
3255		implicitRelative = leadingRelative || Expr.relative[ " " ],
3256		i = leadingRelative ? 1 : 0,
3257
3258		// The foundational matcher ensures that elements are reachable from top-level context(s)
3259		matchContext = addCombinator( function( elem ) {
3260			return elem === checkContext;
3261		}, implicitRelative, true ),
3262		matchAnyContext = addCombinator( function( elem ) {
3263			return indexOf.call( checkContext, elem ) > -1;
3264		}, implicitRelative, true ),
3265		matchers = [ function( elem, context, xml ) {
3266
3267			// Support: IE 11+, Edge 17 - 18+
3268			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3269			// two documents; shallow comparisons work.
3270			// eslint-disable-next-line eqeqeq
3271			var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
3272				( checkContext = context ).nodeType ?
3273					matchContext( elem, context, xml ) :
3274					matchAnyContext( elem, context, xml ) );
3275
3276			// Avoid hanging onto element
3277			// (see https://github.com/jquery/sizzle/issues/299)
3278			checkContext = null;
3279			return ret;
3280		} ];
3281
3282	for ( ; i < len; i++ ) {
3283		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
3284			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
3285		} else {
3286			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
3287
3288			// Return special upon seeing a positional matcher
3289			if ( matcher[ expando ] ) {
3290
3291				// Find the next relative operator (if any) for proper handling
3292				j = ++i;
3293				for ( ; j < len; j++ ) {
3294					if ( Expr.relative[ tokens[ j ].type ] ) {
3295						break;
3296					}
3297				}
3298				return setMatcher(
3299					i > 1 && elementMatcher( matchers ),
3300					i > 1 && toSelector(
3301
3302						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
3303						tokens.slice( 0, i - 1 )
3304							.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
3305					).replace( rtrimCSS, "$1" ),
3306					matcher,
3307					i < j && matcherFromTokens( tokens.slice( i, j ) ),
3308					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
3309					j < len && toSelector( tokens )
3310				);
3311			}
3312			matchers.push( matcher );
3313		}
3314	}
3315
3316	return elementMatcher( matchers );
3317}
3318
3319function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
3320	var bySet = setMatchers.length > 0,
3321		byElement = elementMatchers.length > 0,
3322		superMatcher = function( seed, context, xml, results, outermost ) {
3323			var elem, j, matcher,
3324				matchedCount = 0,
3325				i = "0",
3326				unmatched = seed && [],
3327				setMatched = [],
3328				contextBackup = outermostContext,
3329
3330				// We must always have either seed elements or outermost context
3331				elems = seed || byElement && Expr.find.TAG( "*", outermost ),
3332
3333				// Use integer dirruns iff this is the outermost matcher
3334				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
3335				len = elems.length;
3336
3337			if ( outermost ) {
3338
3339				// Support: IE 11+, Edge 17 - 18+
3340				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3341				// two documents; shallow comparisons work.
3342				// eslint-disable-next-line eqeqeq
3343				outermostContext = context == document || context || outermost;
3344			}
3345
3346			// Add elements passing elementMatchers directly to results
3347			// Support: iOS <=7 - 9 only
3348			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
3349			// elements by id. (see trac-14142)
3350			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
3351				if ( byElement && elem ) {
3352					j = 0;
3353
3354					// Support: IE 11+, Edge 17 - 18+
3355					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3356					// two documents; shallow comparisons work.
3357					// eslint-disable-next-line eqeqeq
3358					if ( !context && elem.ownerDocument != document ) {
3359						setDocument( elem );
3360						xml = !documentIsHTML;
3361					}
3362					while ( ( matcher = elementMatchers[ j++ ] ) ) {
3363						if ( matcher( elem, context || document, xml ) ) {
3364							push.call( results, elem );
3365							break;
3366						}
3367					}
3368					if ( outermost ) {
3369						dirruns = dirrunsUnique;
3370					}
3371				}
3372
3373				// Track unmatched elements for set filters
3374				if ( bySet ) {
3375
3376					// They will have gone through all possible matchers
3377					if ( ( elem = !matcher && elem ) ) {
3378						matchedCount--;
3379					}
3380
3381					// Lengthen the array for every element, matched or not
3382					if ( seed ) {
3383						unmatched.push( elem );
3384					}
3385				}
3386			}
3387
3388			// `i` is now the count of elements visited above, and adding it to `matchedCount`
3389			// makes the latter nonnegative.
3390			matchedCount += i;
3391
3392			// Apply set filters to unmatched elements
3393			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
3394			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
3395			// no element matchers and no seed.
3396			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
3397			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
3398			// numerically zero.
3399			if ( bySet && i !== matchedCount ) {
3400				j = 0;
3401				while ( ( matcher = setMatchers[ j++ ] ) ) {
3402					matcher( unmatched, setMatched, context, xml );
3403				}
3404
3405				if ( seed ) {
3406
3407					// Reintegrate element matches to eliminate the need for sorting
3408					if ( matchedCount > 0 ) {
3409						while ( i-- ) {
3410							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
3411								setMatched[ i ] = pop.call( results );
3412							}
3413						}
3414					}
3415
3416					// Discard index placeholder values to get only actual matches
3417					setMatched = condense( setMatched );
3418				}
3419
3420				// Add matches to results
3421				push.apply( results, setMatched );
3422
3423				// Seedless set matches succeeding multiple successful matchers stipulate sorting
3424				if ( outermost && !seed && setMatched.length > 0 &&
3425					( matchedCount + setMatchers.length ) > 1 ) {
3426
3427					jQuery.uniqueSort( results );
3428				}
3429			}
3430
3431			// Override manipulation of globals by nested matchers
3432			if ( outermost ) {
3433				dirruns = dirrunsUnique;
3434				outermostContext = contextBackup;
3435			}
3436
3437			return unmatched;
3438		};
3439
3440	return bySet ?
3441		markFunction( superMatcher ) :
3442		superMatcher;
3443}
3444
3445function compile( selector, match /* Internal Use Only */ ) {
3446	var i,
3447		setMatchers = [],
3448		elementMatchers = [],
3449		cached = compilerCache[ selector + " " ];
3450
3451	if ( !cached ) {
3452
3453		// Generate a function of recursive functions that can be used to check each element
3454		if ( !match ) {
3455			match = tokenize( selector );
3456		}
3457		i = match.length;
3458		while ( i-- ) {
3459			cached = matcherFromTokens( match[ i ] );
3460			if ( cached[ expando ] ) {
3461				setMatchers.push( cached );
3462			} else {
3463				elementMatchers.push( cached );
3464			}
3465		}
3466
3467		// Cache the compiled function
3468		cached = compilerCache( selector,
3469			matcherFromGroupMatchers( elementMatchers, setMatchers ) );
3470
3471		// Save selector and tokenization
3472		cached.selector = selector;
3473	}
3474	return cached;
3475}
3476
3477/**
3478 * A low-level selection function that works with jQuery's compiled
3479 *  selector functions
3480 * @param {String|Function} selector A selector or a pre-compiled
3481 *  selector function built with jQuery selector compile
3482 * @param {Element} context
3483 * @param {Array} [results]
3484 * @param {Array} [seed] A set of elements to match against
3485 */
3486function select( selector, context, results, seed ) {
3487	var i, tokens, token, type, find,
3488		compiled = typeof selector === "function" && selector,
3489		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
3490
3491	results = results || [];
3492
3493	// Try to minimize operations if there is only one selector in the list and no seed
3494	// (the latter of which guarantees us context)
3495	if ( match.length === 1 ) {
3496
3497		// Reduce context if the leading compound selector is an ID
3498		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
3499		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
3500				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
3501
3502			context = ( Expr.find.ID(
3503				token.matches[ 0 ].replace( runescape, funescape ),
3504				context
3505			) || [] )[ 0 ];
3506			if ( !context ) {
3507				return results;
3508
3509			// Precompiled matchers will still verify ancestry, so step up a level
3510			} else if ( compiled ) {
3511				context = context.parentNode;
3512			}
3513
3514			selector = selector.slice( tokens.shift().value.length );
3515		}
3516
3517		// Fetch a seed set for right-to-left matching
3518		i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;
3519		while ( i-- ) {
3520			token = tokens[ i ];
3521
3522			// Abort if we hit a combinator
3523			if ( Expr.relative[ ( type = token.type ) ] ) {
3524				break;
3525			}
3526			if ( ( find = Expr.find[ type ] ) ) {
3527
3528				// Search, expanding context for leading sibling combinators
3529				if ( ( seed = find(
3530					token.matches[ 0 ].replace( runescape, funescape ),
3531					rsibling.test( tokens[ 0 ].type ) &&
3532						testContext( context.parentNode ) || context
3533				) ) ) {
3534
3535					// If seed is empty or no tokens remain, we can return early
3536					tokens.splice( i, 1 );
3537					selector = seed.length && toSelector( tokens );
3538					if ( !selector ) {
3539						push.apply( results, seed );
3540						return results;
3541					}
3542
3543					break;
3544				}
3545			}
3546		}
3547	}
3548
3549	// Compile and execute a filtering function if one is not provided
3550	// Provide `match` to avoid retokenization if we modified the selector above
3551	( compiled || compile( selector, match ) )(
3552		seed,
3553		context,
3554		!documentIsHTML,
3555		results,
3556		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
3557	);
3558	return results;
3559}
3560
3561// One-time assignments
3562
3563// Support: Android <=4.0 - 4.1+
3564// Sort stability
3565support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
3566
3567// Initialize against the default document
3568setDocument();
3569
3570// Support: Android <=4.0 - 4.1+
3571// Detached nodes confoundingly follow *each other*
3572support.sortDetached = assert( function( el ) {
3573
3574	// Should return 1, but returns 4 (following)
3575	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
3576} );
3577
3578jQuery.find = find;
3579
3580// Deprecated
3581jQuery.expr[ ":" ] = jQuery.expr.pseudos;
3582jQuery.unique = jQuery.uniqueSort;
3583
3584// These have always been private, but they used to be documented as part of
3585// Sizzle so let's maintain them for now for backwards compatibility purposes.
3586find.compile = compile;
3587find.select = select;
3588find.setDocument = setDocument;
3589find.tokenize = tokenize;
3590
3591find.escape = jQuery.escapeSelector;
3592find.getText = jQuery.text;
3593find.isXML = jQuery.isXMLDoc;
3594find.selectors = jQuery.expr;
3595find.support = jQuery.support;
3596find.uniqueSort = jQuery.uniqueSort;
3597
3598	/* eslint-enable */
3599
3600} )();
3601
3602
3603var dir = function( elem, dir, until ) {
3604	var matched = [],
3605		truncate = until !== undefined;
3606
3607	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3608		if ( elem.nodeType === 1 ) {
3609			if ( truncate && jQuery( elem ).is( until ) ) {
3610				break;
3611			}
3612			matched.push( elem );
3613		}
3614	}
3615	return matched;
3616};
3617
3618
3619var siblings = function( n, elem ) {
3620	var matched = [];
3621
3622	for ( ; n; n = n.nextSibling ) {
3623		if ( n.nodeType === 1 && n !== elem ) {
3624			matched.push( n );
3625		}
3626	}
3627
3628	return matched;
3629};
3630
3631
3632var rneedsContext = jQuery.expr.match.needsContext;
3633
3634var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3635
3636
3637
3638// Implement the identical functionality for filter and not
3639function winnow( elements, qualifier, not ) {
3640	if ( isFunction( qualifier ) ) {
3641		return jQuery.grep( elements, function( elem, i ) {
3642			return !!qualifier.call( elem, i, elem ) !== not;
3643		} );
3644	}
3645
3646	// Single element
3647	if ( qualifier.nodeType ) {
3648		return jQuery.grep( elements, function( elem ) {
3649			return ( elem === qualifier ) !== not;
3650		} );
3651	}
3652
3653	// Arraylike of elements (jQuery, arguments, Array)
3654	if ( typeof qualifier !== "string" ) {
3655		return jQuery.grep( elements, function( elem ) {
3656			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3657		} );
3658	}
3659
3660	// Filtered directly for both simple and complex selectors
3661	return jQuery.filter( qualifier, elements, not );
3662}
3663
3664jQuery.filter = function( expr, elems, not ) {
3665	var elem = elems[ 0 ];
3666
3667	if ( not ) {
3668		expr = ":not(" + expr + ")";
3669	}
3670
3671	if ( elems.length === 1 && elem.nodeType === 1 ) {
3672		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3673	}
3674
3675	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3676		return elem.nodeType === 1;
3677	} ) );
3678};
3679
3680jQuery.fn.extend( {
3681	find: function( selector ) {
3682		var i, ret,
3683			len = this.length,
3684			self = this;
3685
3686		if ( typeof selector !== "string" ) {
3687			return this.pushStack( jQuery( selector ).filter( function() {
3688				for ( i = 0; i < len; i++ ) {
3689					if ( jQuery.contains( self[ i ], this ) ) {
3690						return true;
3691					}
3692				}
3693			} ) );
3694		}
3695
3696		ret = this.pushStack( [] );
3697
3698		for ( i = 0; i < len; i++ ) {
3699			jQuery.find( selector, self[ i ], ret );
3700		}
3701
3702		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3703	},
3704	filter: function( selector ) {
3705		return this.pushStack( winnow( this, selector || [], false ) );
3706	},
3707	not: function( selector ) {
3708		return this.pushStack( winnow( this, selector || [], true ) );
3709	},
3710	is: function( selector ) {
3711		return !!winnow(
3712			this,
3713
3714			// If this is a positional/relative selector, check membership in the returned set
3715			// so $("p:first").is("p:last") won't return true for a doc with two "p".
3716			typeof selector === "string" && rneedsContext.test( selector ) ?
3717				jQuery( selector ) :
3718				selector || [],
3719			false
3720		).length;
3721	}
3722} );
3723
3724
3725// Initialize a jQuery object
3726
3727
3728// A central reference to the root jQuery(document)
3729var rootjQuery,
3730
3731	// A simple way to check for HTML strings
3732	// Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
3733	// Strict HTML recognition (trac-11290: must start with <)
3734	// Shortcut simple #id case for speed
3735	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3736
3737	init = jQuery.fn.init = function( selector, context, root ) {
3738		var match, elem;
3739
3740		// HANDLE: $(""), $(null), $(undefined), $(false)
3741		if ( !selector ) {
3742			return this;
3743		}
3744
3745		// Method init() accepts an alternate rootjQuery
3746		// so migrate can support jQuery.sub (gh-2101)
3747		root = root || rootjQuery;
3748
3749		// Handle HTML strings
3750		if ( typeof selector === "string" ) {
3751			if ( selector[ 0 ] === "<" &&
3752				selector[ selector.length - 1 ] === ">" &&
3753				selector.length >= 3 ) {
3754
3755				// Assume that strings that start and end with <> are HTML and skip the regex check
3756				match = [ null, selector, null ];
3757
3758			} else {
3759				match = rquickExpr.exec( selector );
3760			}
3761
3762			// Match html or make sure no context is specified for #id
3763			if ( match && ( match[ 1 ] || !context ) ) {
3764
3765				// HANDLE: $(html) -> $(array)
3766				if ( match[ 1 ] ) {
3767					context = context instanceof jQuery ? context[ 0 ] : context;
3768
3769					// Option to run scripts is true for back-compat
3770					// Intentionally let the error be thrown if parseHTML is not present
3771					jQuery.merge( this, jQuery.parseHTML(
3772						match[ 1 ],
3773						context && context.nodeType ? context.ownerDocument || context : document,
3774						true
3775					) );
3776
3777					// HANDLE: $(html, props)
3778					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3779						for ( match in context ) {
3780
3781							// Properties of context are called as methods if possible
3782							if ( isFunction( this[ match ] ) ) {
3783								this[ match ]( context[ match ] );
3784
3785							// ...and otherwise set as attributes
3786							} else {
3787								this.attr( match, context[ match ] );
3788							}
3789						}
3790					}
3791
3792					return this;
3793
3794				// HANDLE: $(#id)
3795				} else {
3796					elem = document.getElementById( match[ 2 ] );
3797
3798					if ( elem ) {
3799
3800						// Inject the element directly into the jQuery object
3801						this[ 0 ] = elem;
3802						this.length = 1;
3803					}
3804					return this;
3805				}
3806
3807			// HANDLE: $(expr, $(...))
3808			} else if ( !context || context.jquery ) {
3809				return ( context || root ).find( selector );
3810
3811			// HANDLE: $(expr, context)
3812			// (which is just equivalent to: $(context).find(expr)
3813			} else {
3814				return this.constructor( context ).find( selector );
3815			}
3816
3817		// HANDLE: $(DOMElement)
3818		} else if ( selector.nodeType ) {
3819			this[ 0 ] = selector;
3820			this.length = 1;
3821			return this;
3822
3823		// HANDLE: $(function)
3824		// Shortcut for document ready
3825		} else if ( isFunction( selector ) ) {
3826			return root.ready !== undefined ?
3827				root.ready( selector ) :
3828
3829				// Execute immediately if ready is not present
3830				selector( jQuery );
3831		}
3832
3833		return jQuery.makeArray( selector, this );
3834	};
3835
3836// Give the init function the jQuery prototype for later instantiation
3837init.prototype = jQuery.fn;
3838
3839// Initialize central reference
3840rootjQuery = jQuery( document );
3841
3842
3843var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3844
3845	// Methods guaranteed to produce a unique set when starting from a unique set
3846	guaranteedUnique = {
3847		children: true,
3848		contents: true,
3849		next: true,
3850		prev: true
3851	};
3852
3853jQuery.fn.extend( {
3854	has: function( target ) {
3855		var targets = jQuery( target, this ),
3856			l = targets.length;
3857
3858		return this.filter( function() {
3859			var i = 0;
3860			for ( ; i < l; i++ ) {
3861				if ( jQuery.contains( this, targets[ i ] ) ) {
3862					return true;
3863				}
3864			}
3865		} );
3866	},
3867
3868	closest: function( selectors, context ) {
3869		var cur,
3870			i = 0,
3871			l = this.length,
3872			matched = [],
3873			targets = typeof selectors !== "string" && jQuery( selectors );
3874
3875		// Positional selectors never match, since there's no _selection_ context
3876		if ( !rneedsContext.test( selectors ) ) {
3877			for ( ; i < l; i++ ) {
3878				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3879
3880					// Always skip document fragments
3881					if ( cur.nodeType < 11 && ( targets ?
3882						targets.index( cur ) > -1 :
3883
3884						// Don't pass non-elements to jQuery#find
3885						cur.nodeType === 1 &&
3886							jQuery.find.matchesSelector( cur, selectors ) ) ) {
3887
3888						matched.push( cur );
3889						break;
3890					}
3891				}
3892			}
3893		}
3894
3895		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3896	},
3897
3898	// Determine the position of an element within the set
3899	index: function( elem ) {
3900
3901		// No argument, return index in parent
3902		if ( !elem ) {
3903			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3904		}
3905
3906		// Index in selector
3907		if ( typeof elem === "string" ) {
3908			return indexOf.call( jQuery( elem ), this[ 0 ] );
3909		}
3910
3911		// Locate the position of the desired element
3912		return indexOf.call( this,
3913
3914			// If it receives a jQuery object, the first element is used
3915			elem.jquery ? elem[ 0 ] : elem
3916		);
3917	},
3918
3919	add: function( selector, context ) {
3920		return this.pushStack(
3921			jQuery.uniqueSort(
3922				jQuery.merge( this.get(), jQuery( selector, context ) )
3923			)
3924		);
3925	},
3926
3927	addBack: function( selector ) {
3928		return this.add( selector == null ?
3929			this.prevObject : this.prevObject.filter( selector )
3930		);
3931	}
3932} );
3933
3934function sibling( cur, dir ) {
3935	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3936	return cur;
3937}
3938
3939jQuery.each( {
3940	parent: function( elem ) {
3941		var parent = elem.parentNode;
3942		return parent && parent.nodeType !== 11 ? parent : null;
3943	},
3944	parents: function( elem ) {
3945		return dir( elem, "parentNode" );
3946	},
3947	parentsUntil: function( elem, _i, until ) {
3948		return dir( elem, "parentNode", until );
3949	},
3950	next: function( elem ) {
3951		return sibling( elem, "nextSibling" );
3952	},
3953	prev: function( elem ) {
3954		return sibling( elem, "previousSibling" );
3955	},
3956	nextAll: function( elem ) {
3957		return dir( elem, "nextSibling" );
3958	},
3959	prevAll: function( elem ) {
3960		return dir( elem, "previousSibling" );
3961	},
3962	nextUntil: function( elem, _i, until ) {
3963		return dir( elem, "nextSibling", until );
3964	},
3965	prevUntil: function( elem, _i, until ) {
3966		return dir( elem, "previousSibling", until );
3967	},
3968	siblings: function( elem ) {
3969		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3970	},
3971	children: function( elem ) {
3972		return siblings( elem.firstChild );
3973	},
3974	contents: function( elem ) {
3975		if ( elem.contentDocument != null &&
3976
3977			// Support: IE 11+
3978			// <object> elements with no `data` attribute has an object
3979			// `contentDocument` with a `null` prototype.
3980			getProto( elem.contentDocument ) ) {
3981
3982			return elem.contentDocument;
3983		}
3984
3985		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3986		// Treat the template element as a regular one in browsers that
3987		// don't support it.
3988		if ( nodeName( elem, "template" ) ) {
3989			elem = elem.content || elem;
3990		}
3991
3992		return jQuery.merge( [], elem.childNodes );
3993	}
3994}, function( name, fn ) {
3995	jQuery.fn[ name ] = function( until, selector ) {
3996		var matched = jQuery.map( this, fn, until );
3997
3998		if ( name.slice( -5 ) !== "Until" ) {
3999			selector = until;
4000		}
4001
4002		if ( selector && typeof selector === "string" ) {
4003			matched = jQuery.filter( selector, matched );
4004		}
4005
4006		if ( this.length > 1 ) {
4007
4008			// Remove duplicates
4009			if ( !guaranteedUnique[ name ] ) {
4010				jQuery.uniqueSort( matched );
4011			}
4012
4013			// Reverse order for parents* and prev-derivatives
4014			if ( rparentsprev.test( name ) ) {
4015				matched.reverse();
4016			}
4017		}
4018
4019		return this.pushStack( matched );
4020	};
4021} );
4022var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
4023
4024
4025
4026// Convert String-formatted options into Object-formatted ones
4027function createOptions( options ) {
4028	var object = {};
4029	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
4030		object[ flag ] = true;
4031	} );
4032	return object;
4033}
4034
4035/*
4036 * Create a callback list using the following parameters:
4037 *
4038 *	options: an optional list of space-separated options that will change how
4039 *			the callback list behaves or a more traditional option object
4040 *
4041 * By default a callback list will act like an event callback list and can be
4042 * "fired" multiple times.
4043 *
4044 * Possible options:
4045 *
4046 *	once:			will ensure the callback list can only be fired once (like a Deferred)
4047 *
4048 *	memory:			will keep track of previous values and will call any callback added
4049 *					after the list has been fired right away with the latest "memorized"
4050 *					values (like a Deferred)
4051 *
4052 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
4053 *
4054 *	stopOnFalse:	interrupt callings when a callback returns false
4055 *
4056 */
4057jQuery.Callbacks = function( options ) {
4058
4059	// Convert options from String-formatted to Object-formatted if needed
4060	// (we check in cache first)
4061	options = typeof options === "string" ?
4062		createOptions( options ) :
4063		jQuery.extend( {}, options );
4064
4065	var // Flag to know if list is currently firing
4066		firing,
4067
4068		// Last fire value for non-forgettable lists
4069		memory,
4070
4071		// Flag to know if list was already fired
4072		fired,
4073
4074		// Flag to prevent firing
4075		locked,
4076
4077		// Actual callback list
4078		list = [],
4079
4080		// Queue of execution data for repeatable lists
4081		queue = [],
4082
4083		// Index of currently firing callback (modified by add/remove as needed)
4084		firingIndex = -1,
4085
4086		// Fire callbacks
4087		fire = function() {
4088
4089			// Enforce single-firing
4090			locked = locked || options.once;
4091
4092			// Execute callbacks for all pending executions,
4093			// respecting firingIndex overrides and runtime changes
4094			fired = firing = true;
4095			for ( ; queue.length; firingIndex = -1 ) {
4096				memory = queue.shift();
4097				while ( ++firingIndex < list.length ) {
4098
4099					// Run callback and check for early termination
4100					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
4101						options.stopOnFalse ) {
4102
4103						// Jump to end and forget the data so .add doesn't re-fire
4104						firingIndex = list.length;
4105						memory = false;
4106					}
4107				}
4108			}
4109
4110			// Forget the data if we're done with it
4111			if ( !options.memory ) {
4112				memory = false;
4113			}
4114
4115			firing = false;
4116
4117			// Clean up if we're done firing for good
4118			if ( locked ) {
4119
4120				// Keep an empty list if we have data for future add calls
4121				if ( memory ) {
4122					list = [];
4123
4124				// Otherwise, this object is spent
4125				} else {
4126					list = "";
4127				}
4128			}
4129		},
4130
4131		// Actual Callbacks object
4132		self = {
4133
4134			// Add a callback or a collection of callbacks to the list
4135			add: function() {
4136				if ( list ) {
4137
4138					// If we have memory from a past run, we should fire after adding
4139					if ( memory && !firing ) {
4140						firingIndex = list.length - 1;
4141						queue.push( memory );
4142					}
4143
4144					( function add( args ) {
4145						jQuery.each( args, function( _, arg ) {
4146							if ( isFunction( arg ) ) {
4147								if ( !options.unique || !self.has( arg ) ) {
4148									list.push( arg );
4149								}
4150							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
4151
4152								// Inspect recursively
4153								add( arg );
4154							}
4155						} );
4156					} )( arguments );
4157
4158					if ( memory && !firing ) {
4159						fire();
4160					}
4161				}
4162				return this;
4163			},
4164
4165			// Remove a callback from the list
4166			remove: function() {
4167				jQuery.each( arguments, function( _, arg ) {
4168					var index;
4169					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
4170						list.splice( index, 1 );
4171
4172						// Handle firing indexes
4173						if ( index <= firingIndex ) {
4174							firingIndex--;
4175						}
4176					}
4177				} );
4178				return this;
4179			},
4180
4181			// Check if a given callback is in the list.
4182			// If no argument is given, return whether or not list has callbacks attached.
4183			has: function( fn ) {
4184				return fn ?
4185					jQuery.inArray( fn, list ) > -1 :
4186					list.length > 0;
4187			},
4188
4189			// Remove all callbacks from the list
4190			empty: function() {
4191				if ( list ) {
4192					list = [];
4193				}
4194				return this;
4195			},
4196
4197			// Disable .fire and .add
4198			// Abort any current/pending executions
4199			// Clear all callbacks and values
4200			disable: function() {
4201				locked = queue = [];
4202				list = memory = "";
4203				return this;
4204			},
4205			disabled: function() {
4206				return !list;
4207			},
4208
4209			// Disable .fire
4210			// Also disable .add unless we have memory (since it would have no effect)
4211			// Abort any pending executions
4212			lock: function() {
4213				locked = queue = [];
4214				if ( !memory && !firing ) {
4215					list = memory = "";
4216				}
4217				return this;
4218			},
4219			locked: function() {
4220				return !!locked;
4221			},
4222
4223			// Call all callbacks with the given context and arguments
4224			fireWith: function( context, args ) {
4225				if ( !locked ) {
4226					args = args || [];
4227					args = [ context, args.slice ? args.slice() : args ];
4228					queue.push( args );
4229					if ( !firing ) {
4230						fire();
4231					}
4232				}
4233				return this;
4234			},
4235
4236			// Call all the callbacks with the given arguments
4237			fire: function() {
4238				self.fireWith( this, arguments );
4239				return this;
4240			},
4241
4242			// To know if the callbacks have already been called at least once
4243			fired: function() {
4244				return !!fired;
4245			}
4246		};
4247
4248	return self;
4249};
4250
4251
4252function Identity( v ) {
4253	return v;
4254}
4255function Thrower( ex ) {
4256	throw ex;
4257}
4258
4259function adoptValue( value, resolve, reject, noValue ) {
4260	var method;
4261
4262	try {
4263
4264		// Check for promise aspect first to privilege synchronous behavior
4265		if ( value && isFunction( ( method = value.promise ) ) ) {
4266			method.call( value ).done( resolve ).fail( reject );
4267
4268		// Other thenables
4269		} else if ( value && isFunction( ( method = value.then ) ) ) {
4270			method.call( value, resolve, reject );
4271
4272		// Other non-thenables
4273		} else {
4274
4275			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
4276			// * false: [ value ].slice( 0 ) => resolve( value )
4277			// * true: [ value ].slice( 1 ) => resolve()
4278			resolve.apply( undefined, [ value ].slice( noValue ) );
4279		}
4280
4281	// For Promises/A+, convert exceptions into rejections
4282	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
4283	// Deferred#then to conditionally suppress rejection.
4284	} catch ( value ) {
4285
4286		// Support: Android 4.0 only
4287		// Strict mode functions invoked without .call/.apply get global-object context
4288		reject.apply( undefined, [ value ] );
4289	}
4290}
4291
4292jQuery.extend( {
4293
4294	Deferred: function( func ) {
4295		var tuples = [
4296
4297				// action, add listener, callbacks,
4298				// ... .then handlers, argument index, [final state]
4299				[ "notify", "progress", jQuery.Callbacks( "memory" ),
4300					jQuery.Callbacks( "memory" ), 2 ],
4301				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
4302					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
4303				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
4304					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
4305			],
4306			state = "pending",
4307			promise = {
4308				state: function() {
4309					return state;
4310				},
4311				always: function() {
4312					deferred.done( arguments ).fail( arguments );
4313					return this;
4314				},
4315				"catch": function( fn ) {
4316					return promise.then( null, fn );
4317				},
4318
4319				// Keep pipe for back-compat
4320				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
4321					var fns = arguments;
4322
4323					return jQuery.Deferred( function( newDefer ) {
4324						jQuery.each( tuples, function( _i, tuple ) {
4325
4326							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
4327							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
4328
4329							// deferred.progress(function() { bind to newDefer or newDefer.notify })
4330							// deferred.done(function() { bind to newDefer or newDefer.resolve })
4331							// deferred.fail(function() { bind to newDefer or newDefer.reject })
4332							deferred[ tuple[ 1 ] ]( function() {
4333								var returned = fn && fn.apply( this, arguments );
4334								if ( returned && isFunction( returned.promise ) ) {
4335									returned.promise()
4336										.progress( newDefer.notify )
4337										.done( newDefer.resolve )
4338										.fail( newDefer.reject );
4339								} else {
4340									newDefer[ tuple[ 0 ] + "With" ](
4341										this,
4342										fn ? [ returned ] : arguments
4343									);
4344								}
4345							} );
4346						} );
4347						fns = null;
4348					} ).promise();
4349				},
4350				then: function( onFulfilled, onRejected, onProgress ) {
4351					var maxDepth = 0;
4352					function resolve( depth, deferred, handler, special ) {
4353						return function() {
4354							var that = this,
4355								args = arguments,
4356								mightThrow = function() {
4357									var returned, then;
4358
4359									// Support: Promises/A+ section 2.3.3.3.3
4360									// https://promisesaplus.com/#point-59
4361									// Ignore double-resolution attempts
4362									if ( depth < maxDepth ) {
4363										return;
4364									}
4365
4366									returned = handler.apply( that, args );
4367
4368									// Support: Promises/A+ section 2.3.1
4369									// https://promisesaplus.com/#point-48
4370									if ( returned === deferred.promise() ) {
4371										throw new TypeError( "Thenable self-resolution" );
4372									}
4373
4374									// Support: Promises/A+ sections 2.3.3.1, 3.5
4375									// https://promisesaplus.com/#point-54
4376									// https://promisesaplus.com/#point-75
4377									// Retrieve `then` only once
4378									then = returned &&
4379
4380										// Support: Promises/A+ section 2.3.4
4381										// https://promisesaplus.com/#point-64
4382										// Only check objects and functions for thenability
4383										( typeof returned === "object" ||
4384											typeof returned === "function" ) &&
4385										returned.then;
4386
4387									// Handle a returned thenable
4388									if ( isFunction( then ) ) {
4389
4390										// Special processors (notify) just wait for resolution
4391										if ( special ) {
4392											then.call(
4393												returned,
4394												resolve( maxDepth, deferred, Identity, special ),
4395												resolve( maxDepth, deferred, Thrower, special )
4396											);
4397
4398										// Normal processors (resolve) also hook into progress
4399										} else {
4400
4401											// ...and disregard older resolution values
4402											maxDepth++;
4403
4404											then.call(
4405												returned,
4406												resolve( maxDepth, deferred, Identity, special ),
4407												resolve( maxDepth, deferred, Thrower, special ),
4408												resolve( maxDepth, deferred, Identity,
4409													deferred.notifyWith )
4410											);
4411										}
4412
4413									// Handle all other returned values
4414									} else {
4415
4416										// Only substitute handlers pass on context
4417										// and multiple values (non-spec behavior)
4418										if ( handler !== Identity ) {
4419											that = undefined;
4420											args = [ returned ];
4421										}
4422
4423										// Process the value(s)
4424										// Default process is resolve
4425										( special || deferred.resolveWith )( that, args );
4426									}
4427								},
4428
4429								// Only normal processors (resolve) catch and reject exceptions
4430								process = special ?
4431									mightThrow :
4432									function() {
4433										try {
4434											mightThrow();
4435										} catch ( e ) {
4436
4437											if ( jQuery.Deferred.exceptionHook ) {
4438												jQuery.Deferred.exceptionHook( e,
4439													process.error );
4440											}
4441
4442											// Support: Promises/A+ section 2.3.3.3.4.1
4443											// https://promisesaplus.com/#point-61
4444											// Ignore post-resolution exceptions
4445											if ( depth + 1 >= maxDepth ) {
4446
4447												// Only substitute handlers pass on context
4448												// and multiple values (non-spec behavior)
4449												if ( handler !== Thrower ) {
4450													that = undefined;
4451													args = [ e ];
4452												}
4453
4454												deferred.rejectWith( that, args );
4455											}
4456										}
4457									};
4458
4459							// Support: Promises/A+ section 2.3.3.3.1
4460							// https://promisesaplus.com/#point-57
4461							// Re-resolve promises immediately to dodge false rejection from
4462							// subsequent errors
4463							if ( depth ) {
4464								process();
4465							} else {
4466
4467								// Call an optional hook to record the error, in case of exception
4468								// since it's otherwise lost when execution goes async
4469								if ( jQuery.Deferred.getErrorHook ) {
4470									process.error = jQuery.Deferred.getErrorHook();
4471
4472								// The deprecated alias of the above. While the name suggests
4473								// returning the stack, not an error instance, jQuery just passes
4474								// it directly to `console.warn` so both will work; an instance
4475								// just better cooperates with source maps.
4476								} else if ( jQuery.Deferred.getStackHook ) {
4477									process.error = jQuery.Deferred.getStackHook();
4478								}
4479								window.setTimeout( process );
4480							}
4481						};
4482					}
4483
4484					return jQuery.Deferred( function( newDefer ) {
4485
4486						// progress_handlers.add( ... )
4487						tuples[ 0 ][ 3 ].add(
4488							resolve(
4489								0,
4490								newDefer,
4491								isFunction( onProgress ) ?
4492									onProgress :
4493									Identity,
4494								newDefer.notifyWith
4495							)
4496						);
4497
4498						// fulfilled_handlers.add( ... )
4499						tuples[ 1 ][ 3 ].add(
4500							resolve(
4501								0,
4502								newDefer,
4503								isFunction( onFulfilled ) ?
4504									onFulfilled :
4505									Identity
4506							)
4507						);
4508
4509						// rejected_handlers.add( ... )
4510						tuples[ 2 ][ 3 ].add(
4511							resolve(
4512								0,
4513								newDefer,
4514								isFunction( onRejected ) ?
4515									onRejected :
4516									Thrower
4517							)
4518						);
4519					} ).promise();
4520				},
4521
4522				// Get a promise for this deferred
4523				// If obj is provided, the promise aspect is added to the object
4524				promise: function( obj ) {
4525					return obj != null ? jQuery.extend( obj, promise ) : promise;
4526				}
4527			},
4528			deferred = {};
4529
4530		// Add list-specific methods
4531		jQuery.each( tuples, function( i, tuple ) {
4532			var list = tuple[ 2 ],
4533				stateString = tuple[ 5 ];
4534
4535			// promise.progress = list.add
4536			// promise.done = list.add
4537			// promise.fail = list.add
4538			promise[ tuple[ 1 ] ] = list.add;
4539
4540			// Handle state
4541			if ( stateString ) {
4542				list.add(
4543					function() {
4544
4545						// state = "resolved" (i.e., fulfilled)
4546						// state = "rejected"
4547						state = stateString;
4548					},
4549
4550					// rejected_callbacks.disable
4551					// fulfilled_callbacks.disable
4552					tuples[ 3 - i ][ 2 ].disable,
4553
4554					// rejected_handlers.disable
4555					// fulfilled_handlers.disable
4556					tuples[ 3 - i ][ 3 ].disable,
4557
4558					// progress_callbacks.lock
4559					tuples[ 0 ][ 2 ].lock,
4560
4561					// progress_handlers.lock
4562					tuples[ 0 ][ 3 ].lock
4563				);
4564			}
4565
4566			// progress_handlers.fire
4567			// fulfilled_handlers.fire
4568			// rejected_handlers.fire
4569			list.add( tuple[ 3 ].fire );
4570
4571			// deferred.notify = function() { deferred.notifyWith(...) }
4572			// deferred.resolve = function() { deferred.resolveWith(...) }
4573			// deferred.reject = function() { deferred.rejectWith(...) }
4574			deferred[ tuple[ 0 ] ] = function() {
4575				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
4576				return this;
4577			};
4578
4579			// deferred.notifyWith = list.fireWith
4580			// deferred.resolveWith = list.fireWith
4581			// deferred.rejectWith = list.fireWith
4582			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
4583		} );
4584
4585		// Make the deferred a promise
4586		promise.promise( deferred );
4587
4588		// Call given func if any
4589		if ( func ) {
4590			func.call( deferred, deferred );
4591		}
4592
4593		// All done!
4594		return deferred;
4595	},
4596
4597	// Deferred helper
4598	when: function( singleValue ) {
4599		var
4600
4601			// count of uncompleted subordinates
4602			remaining = arguments.length,
4603
4604			// count of unprocessed arguments
4605			i = remaining,
4606
4607			// subordinate fulfillment data
4608			resolveContexts = Array( i ),
4609			resolveValues = slice.call( arguments ),
4610
4611			// the primary Deferred
4612			primary = jQuery.Deferred(),
4613
4614			// subordinate callback factory
4615			updateFunc = function( i ) {
4616				return function( value ) {
4617					resolveContexts[ i ] = this;
4618					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4619					if ( !( --remaining ) ) {
4620						primary.resolveWith( resolveContexts, resolveValues );
4621					}
4622				};
4623			};
4624
4625		// Single- and empty arguments are adopted like Promise.resolve
4626		if ( remaining <= 1 ) {
4627			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
4628				!remaining );
4629
4630			// Use .then() to unwrap secondary thenables (cf. gh-3000)
4631			if ( primary.state() === "pending" ||
4632				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4633
4634				return primary.then();
4635			}
4636		}
4637
4638		// Multiple arguments are aggregated like Promise.all array elements
4639		while ( i-- ) {
4640			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
4641		}
4642
4643		return primary.promise();
4644	}
4645} );
4646
4647
4648// These usually indicate a programmer mistake during development,
4649// warn about them ASAP rather than swallowing them by default.
4650var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4651
4652// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
4653// captured before the async barrier to get the original error cause
4654// which may otherwise be hidden.
4655jQuery.Deferred.exceptionHook = function( error, asyncError ) {
4656
4657	// Support: IE 8 - 9 only
4658	// Console exists when dev tools are open, which can happen at any time
4659	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4660		window.console.warn( "jQuery.Deferred exception: " + error.message,
4661			error.stack, asyncError );
4662	}
4663};
4664
4665
4666
4667
4668jQuery.readyException = function( error ) {
4669	window.setTimeout( function() {
4670		throw error;
4671	} );
4672};
4673
4674
4675
4676
4677// The deferred used on DOM ready
4678var readyList = jQuery.Deferred();
4679
4680jQuery.fn.ready = function( fn ) {
4681
4682	readyList
4683		.then( fn )
4684
4685		// Wrap jQuery.readyException in a function so that the lookup
4686		// happens at the time of error handling instead of callback
4687		// registration.
4688		.catch( function( error ) {
4689			jQuery.readyException( error );
4690		} );
4691
4692	return this;
4693};
4694
4695jQuery.extend( {
4696
4697	// Is the DOM ready to be used? Set to true once it occurs.
4698	isReady: false,
4699
4700	// A counter to track how many items to wait for before
4701	// the ready event fires. See trac-6781
4702	readyWait: 1,
4703
4704	// Handle when the DOM is ready
4705	ready: function( wait ) {
4706
4707		// Abort if there are pending holds or we're already ready
4708		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4709			return;
4710		}
4711
4712		// Remember that the DOM is ready
4713		jQuery.isReady = true;
4714
4715		// If a normal DOM Ready event fired, decrement, and wait if need be
4716		if ( wait !== true && --jQuery.readyWait > 0 ) {
4717			return;
4718		}
4719
4720		// If there are functions bound, to execute
4721		readyList.resolveWith( document, [ jQuery ] );
4722	}
4723} );
4724
4725jQuery.ready.then = readyList.then;
4726
4727// The ready event handler and self cleanup method
4728function completed() {
4729	document.removeEventListener( "DOMContentLoaded", completed );
4730	window.removeEventListener( "load", completed );
4731	jQuery.ready();
4732}
4733
4734// Catch cases where $(document).ready() is called
4735// after the browser event has already occurred.
4736// Support: IE <=9 - 10 only
4737// Older IE sometimes signals "interactive" too soon
4738if ( document.readyState === "complete" ||
4739	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4740
4741	// Handle it asynchronously to allow scripts the opportunity to delay ready
4742	window.setTimeout( jQuery.ready );
4743
4744} else {
4745
4746	// Use the handy event callback
4747	document.addEventListener( "DOMContentLoaded", completed );
4748
4749	// A fallback to window.onload, that will always work
4750	window.addEventListener( "load", completed );
4751}
4752
4753
4754
4755
4756// Multifunctional method to get and set values of a collection
4757// The value/s can optionally be executed if it's a function
4758var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4759	var i = 0,
4760		len = elems.length,
4761		bulk = key == null;
4762
4763	// Sets many values
4764	if ( toType( key ) === "object" ) {
4765		chainable = true;
4766		for ( i in key ) {
4767			access( elems, fn, i, key[ i ], true, emptyGet, raw );
4768		}
4769
4770	// Sets one value
4771	} else if ( value !== undefined ) {
4772		chainable = true;
4773
4774		if ( !isFunction( value ) ) {
4775			raw = true;
4776		}
4777
4778		if ( bulk ) {
4779
4780			// Bulk operations run against the entire set
4781			if ( raw ) {
4782				fn.call( elems, value );
4783				fn = null;
4784
4785			// ...except when executing function values
4786			} else {
4787				bulk = fn;
4788				fn = function( elem, _key, value ) {
4789					return bulk.call( jQuery( elem ), value );
4790				};
4791			}
4792		}
4793
4794		if ( fn ) {
4795			for ( ; i < len; i++ ) {
4796				fn(
4797					elems[ i ], key, raw ?
4798						value :
4799						value.call( elems[ i ], i, fn( elems[ i ], key ) )
4800				);
4801			}
4802		}
4803	}
4804
4805	if ( chainable ) {
4806		return elems;
4807	}
4808
4809	// Gets
4810	if ( bulk ) {
4811		return fn.call( elems );
4812	}
4813
4814	return len ? fn( elems[ 0 ], key ) : emptyGet;
4815};
4816
4817
4818// Matches dashed string for camelizing
4819var rmsPrefix = /^-ms-/,
4820	rdashAlpha = /-([a-z])/g;
4821
4822// Used by camelCase as callback to replace()
4823function fcamelCase( _all, letter ) {
4824	return letter.toUpperCase();
4825}
4826
4827// Convert dashed to camelCase; used by the css and data modules
4828// Support: IE <=9 - 11, Edge 12 - 15
4829// Microsoft forgot to hump their vendor prefix (trac-9572)
4830function camelCase( string ) {
4831	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4832}
4833var acceptData = function( owner ) {
4834
4835	// Accepts only:
4836	//  - Node
4837	//    - Node.ELEMENT_NODE
4838	//    - Node.DOCUMENT_NODE
4839	//  - Object
4840	//    - Any
4841	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4842};
4843
4844
4845
4846
4847function Data() {
4848	this.expando = jQuery.expando + Data.uid++;
4849}
4850
4851Data.uid = 1;
4852
4853Data.prototype = {
4854
4855	cache: function( owner ) {
4856
4857		// Check if the owner object already has a cache
4858		var value = owner[ this.expando ];
4859
4860		// If not, create one
4861		if ( !value ) {
4862			value = {};
4863
4864			// We can accept data for non-element nodes in modern browsers,
4865			// but we should not, see trac-8335.
4866			// Always return an empty object.
4867			if ( acceptData( owner ) ) {
4868
4869				// If it is a node unlikely to be stringify-ed or looped over
4870				// use plain assignment
4871				if ( owner.nodeType ) {
4872					owner[ this.expando ] = value;
4873
4874				// Otherwise secure it in a non-enumerable property
4875				// configurable must be true to allow the property to be
4876				// deleted when data is removed
4877				} else {
4878					Object.defineProperty( owner, this.expando, {
4879						value: value,
4880						configurable: true
4881					} );
4882				}
4883			}
4884		}
4885
4886		return value;
4887	},
4888	set: function( owner, data, value ) {
4889		var prop,
4890			cache = this.cache( owner );
4891
4892		// Handle: [ owner, key, value ] args
4893		// Always use camelCase key (gh-2257)
4894		if ( typeof data === "string" ) {
4895			cache[ camelCase( data ) ] = value;
4896
4897		// Handle: [ owner, { properties } ] args
4898		} else {
4899
4900			// Copy the properties one-by-one to the cache object
4901			for ( prop in data ) {
4902				cache[ camelCase( prop ) ] = data[ prop ];
4903			}
4904		}
4905		return cache;
4906	},
4907	get: function( owner, key ) {
4908		return key === undefined ?
4909			this.cache( owner ) :
4910
4911			// Always use camelCase key (gh-2257)
4912			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4913	},
4914	access: function( owner, key, value ) {
4915
4916		// In cases where either:
4917		//
4918		//   1. No key was specified
4919		//   2. A string key was specified, but no value provided
4920		//
4921		// Take the "read" path and allow the get method to determine
4922		// which value to return, respectively either:
4923		//
4924		//   1. The entire cache object
4925		//   2. The data stored at the key
4926		//
4927		if ( key === undefined ||
4928				( ( key && typeof key === "string" ) && value === undefined ) ) {
4929
4930			return this.get( owner, key );
4931		}
4932
4933		// When the key is not a string, or both a key and value
4934		// are specified, set or extend (existing objects) with either:
4935		//
4936		//   1. An object of properties
4937		//   2. A key and value
4938		//
4939		this.set( owner, key, value );
4940
4941		// Since the "set" path can have two possible entry points
4942		// return the expected data based on which path was taken[*]
4943		return value !== undefined ? value : key;
4944	},
4945	remove: function( owner, key ) {
4946		var i,
4947			cache = owner[ this.expando ];
4948
4949		if ( cache === undefined ) {
4950			return;
4951		}
4952
4953		if ( key !== undefined ) {
4954
4955			// Support array or space separated string of keys
4956			if ( Array.isArray( key ) ) {
4957
4958				// If key is an array of keys...
4959				// We always set camelCase keys, so remove that.
4960				key = key.map( camelCase );
4961			} else {
4962				key = camelCase( key );
4963
4964				// If a key with the spaces exists, use it.
4965				// Otherwise, create an array by matching non-whitespace
4966				key = key in cache ?
4967					[ key ] :
4968					( key.match( rnothtmlwhite ) || [] );
4969			}
4970
4971			i = key.length;
4972
4973			while ( i-- ) {
4974				delete cache[ key[ i ] ];
4975			}
4976		}
4977
4978		// Remove the expando if there's no more data
4979		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4980
4981			// Support: Chrome <=35 - 45
4982			// Webkit & Blink performance suffers when deleting properties
4983			// from DOM nodes, so set to undefined instead
4984			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4985			if ( owner.nodeType ) {
4986				owner[ this.expando ] = undefined;
4987			} else {
4988				delete owner[ this.expando ];
4989			}
4990		}
4991	},
4992	hasData: function( owner ) {
4993		var cache = owner[ this.expando ];
4994		return cache !== undefined && !jQuery.isEmptyObject( cache );
4995	}
4996};
4997var dataPriv = new Data();
4998
4999var dataUser = new Data();
5000
5001
5002
5003//	Implementation Summary
5004//
5005//	1. Enforce API surface and semantic compatibility with 1.9.x branch
5006//	2. Improve the module's maintainability by reducing the storage
5007//		paths to a single mechanism.
5008//	3. Use the same single mechanism to support "private" and "user" data.
5009//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
5010//	5. Avoid exposing implementation details on user objects (eg. expando properties)
5011//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
5012
5013var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
5014	rmultiDash = /[A-Z]/g;
5015
5016function getData( data ) {
5017	if ( data === "true" ) {
5018		return true;
5019	}
5020
5021	if ( data === "false" ) {
5022		return false;
5023	}
5024
5025	if ( data === "null" ) {
5026		return null;
5027	}
5028
5029	// Only convert to a number if it doesn't change the string
5030	if ( data === +data + "" ) {
5031		return +data;
5032	}
5033
5034	if ( rbrace.test( data ) ) {
5035		return JSON.parse( data );
5036	}
5037
5038	return data;
5039}
5040
5041function dataAttr( elem, key, data ) {
5042	var name;
5043
5044	// If nothing was found internally, try to fetch any
5045	// data from the HTML5 data-* attribute
5046	if ( data === undefined && elem.nodeType === 1 ) {
5047		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
5048		data = elem.getAttribute( name );
5049
5050		if ( typeof data === "string" ) {
5051			try {
5052				data = getData( data );
5053			} catch ( e ) {}
5054
5055			// Make sure we set the data so it isn't changed later
5056			dataUser.set( elem, key, data );
5057		} else {
5058			data = undefined;
5059		}
5060	}
5061	return data;
5062}
5063
5064jQuery.extend( {
5065	hasData: function( elem ) {
5066		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
5067	},
5068
5069	data: function( elem, name, data ) {
5070		return dataUser.access( elem, name, data );
5071	},
5072
5073	removeData: function( elem, name ) {
5074		dataUser.remove( elem, name );
5075	},
5076
5077	// TODO: Now that all calls to _data and _removeData have been replaced
5078	// with direct calls to dataPriv methods, these can be deprecated.
5079	_data: function( elem, name, data ) {
5080		return dataPriv.access( elem, name, data );
5081	},
5082
5083	_removeData: function( elem, name ) {
5084		dataPriv.remove( elem, name );
5085	}
5086} );
5087
5088jQuery.fn.extend( {
5089	data: function( key, value ) {
5090		var i, name, data,
5091			elem = this[ 0 ],
5092			attrs = elem && elem.attributes;
5093
5094		// Gets all values
5095		if ( key === undefined ) {
5096			if ( this.length ) {
5097				data = dataUser.get( elem );
5098
5099				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
5100					i = attrs.length;
5101					while ( i-- ) {
5102
5103						// Support: IE 11 only
5104						// The attrs elements can be null (trac-14894)
5105						if ( attrs[ i ] ) {
5106							name = attrs[ i ].name;
5107							if ( name.indexOf( "data-" ) === 0 ) {
5108								name = camelCase( name.slice( 5 ) );
5109								dataAttr( elem, name, data[ name ] );
5110							}
5111						}
5112					}
5113					dataPriv.set( elem, "hasDataAttrs", true );
5114				}
5115			}
5116
5117			return data;
5118		}
5119
5120		// Sets multiple values
5121		if ( typeof key === "object" ) {
5122			return this.each( function() {
5123				dataUser.set( this, key );
5124			} );
5125		}
5126
5127		return access( this, function( value ) {
5128			var data;
5129
5130			// The calling jQuery object (element matches) is not empty
5131			// (and therefore has an element appears at this[ 0 ]) and the
5132			// `value` parameter was not undefined. An empty jQuery object
5133			// will result in `undefined` for elem = this[ 0 ] which will
5134			// throw an exception if an attempt to read a data cache is made.
5135			if ( elem && value === undefined ) {
5136
5137				// Attempt to get data from the cache
5138				// The key will always be camelCased in Data
5139				data = dataUser.get( elem, key );
5140				if ( data !== undefined ) {
5141					return data;
5142				}
5143
5144				// Attempt to "discover" the data in
5145				// HTML5 custom data-* attrs
5146				data = dataAttr( elem, key );
5147				if ( data !== undefined ) {
5148					return data;
5149				}
5150
5151				// We tried really hard, but the data doesn't exist.
5152				return;
5153			}
5154
5155			// Set the data...
5156			this.each( function() {
5157
5158				// We always store the camelCased key
5159				dataUser.set( this, key, value );
5160			} );
5161		}, null, value, arguments.length > 1, null, true );
5162	},
5163
5164	removeData: function( key ) {
5165		return this.each( function() {
5166			dataUser.remove( this, key );
5167		} );
5168	}
5169} );
5170
5171
5172jQuery.extend( {
5173	queue: function( elem, type, data ) {
5174		var queue;
5175
5176		if ( elem ) {
5177			type = ( type || "fx" ) + "queue";
5178			queue = dataPriv.get( elem, type );
5179
5180			// Speed up dequeue by getting out quickly if this is just a lookup
5181			if ( data ) {
5182				if ( !queue || Array.isArray( data ) ) {
5183					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
5184				} else {
5185					queue.push( data );
5186				}
5187			}
5188			return queue || [];
5189		}
5190	},
5191
5192	dequeue: function( elem, type ) {
5193		type = type || "fx";
5194
5195		var queue = jQuery.queue( elem, type ),
5196			startLength = queue.length,
5197			fn = queue.shift(),
5198			hooks = jQuery._queueHooks( elem, type ),
5199			next = function() {
5200				jQuery.dequeue( elem, type );
5201			};
5202
5203		// If the fx queue is dequeued, always remove the progress sentinel
5204		if ( fn === "inprogress" ) {
5205			fn = queue.shift();
5206			startLength--;
5207		}
5208
5209		if ( fn ) {
5210
5211			// Add a progress sentinel to prevent the fx queue from being
5212			// automatically dequeued
5213			if ( type === "fx" ) {
5214				queue.unshift( "inprogress" );
5215			}
5216
5217			// Clear up the last queue stop function
5218			delete hooks.stop;
5219			fn.call( elem, next, hooks );
5220		}
5221
5222		if ( !startLength && hooks ) {
5223			hooks.empty.fire();
5224		}
5225	},
5226
5227	// Not public - generate a queueHooks object, or return the current one
5228	_queueHooks: function( elem, type ) {
5229		var key = type + "queueHooks";
5230		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
5231			empty: jQuery.Callbacks( "once memory" ).add( function() {
5232				dataPriv.remove( elem, [ type + "queue", key ] );
5233			} )
5234		} );
5235	}
5236} );
5237
5238jQuery.fn.extend( {
5239	queue: function( type, data ) {
5240		var setter = 2;
5241
5242		if ( typeof type !== "string" ) {
5243			data = type;
5244			type = "fx";
5245			setter--;
5246		}
5247
5248		if ( arguments.length < setter ) {
5249			return jQuery.queue( this[ 0 ], type );
5250		}
5251
5252		return data === undefined ?
5253			this :
5254			this.each( function() {
5255				var queue = jQuery.queue( this, type, data );
5256
5257				// Ensure a hooks for this queue
5258				jQuery._queueHooks( this, type );
5259
5260				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
5261					jQuery.dequeue( this, type );
5262				}
5263			} );
5264	},
5265	dequeue: function( type ) {
5266		return this.each( function() {
5267			jQuery.dequeue( this, type );
5268		} );
5269	},
5270	clearQueue: function( type ) {
5271		return this.queue( type || "fx", [] );
5272	},
5273
5274	// Get a promise resolved when queues of a certain type
5275	// are emptied (fx is the type by default)
5276	promise: function( type, obj ) {
5277		var tmp,
5278			count = 1,
5279			defer = jQuery.Deferred(),
5280			elements = this,
5281			i = this.length,
5282			resolve = function() {
5283				if ( !( --count ) ) {
5284					defer.resolveWith( elements, [ elements ] );
5285				}
5286			};
5287
5288		if ( typeof type !== "string" ) {
5289			obj = type;
5290			type = undefined;
5291		}
5292		type = type || "fx";
5293
5294		while ( i-- ) {
5295			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
5296			if ( tmp && tmp.empty ) {
5297				count++;
5298				tmp.empty.add( resolve );
5299			}
5300		}
5301		resolve();
5302		return defer.promise( obj );
5303	}
5304} );
5305var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
5306
5307var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
5308
5309
5310var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
5311
5312var documentElement = document.documentElement;
5313
5314
5315
5316	var isAttached = function( elem ) {
5317			return jQuery.contains( elem.ownerDocument, elem );
5318		},
5319		composed = { composed: true };
5320
5321	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
5322	// Check attachment across shadow DOM boundaries when possible (gh-3504)
5323	// Support: iOS 10.0-10.2 only
5324	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
5325	// leading to errors. We need to check for `getRootNode`.
5326	if ( documentElement.getRootNode ) {
5327		isAttached = function( elem ) {
5328			return jQuery.contains( elem.ownerDocument, elem ) ||
5329				elem.getRootNode( composed ) === elem.ownerDocument;
5330		};
5331	}
5332var isHiddenWithinTree = function( elem, el ) {
5333
5334		// isHiddenWithinTree might be called from jQuery#filter function;
5335		// in that case, element will be second argument
5336		elem = el || elem;
5337
5338		// Inline style trumps all
5339		return elem.style.display === "none" ||
5340			elem.style.display === "" &&
5341
5342			// Otherwise, check computed style
5343			// Support: Firefox <=43 - 45
5344			// Disconnected elements can have computed display: none, so first confirm that elem is
5345			// in the document.
5346			isAttached( elem ) &&
5347
5348			jQuery.css( elem, "display" ) === "none";
5349	};
5350
5351
5352
5353function adjustCSS( elem, prop, valueParts, tween ) {
5354	var adjusted, scale,
5355		maxIterations = 20,
5356		currentValue = tween ?
5357			function() {
5358				return tween.cur();
5359			} :
5360			function() {
5361				return jQuery.css( elem, prop, "" );
5362			},
5363		initial = currentValue(),
5364		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
5365
5366		// Starting value computation is required for potential unit mismatches
5367		initialInUnit = elem.nodeType &&
5368			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
5369			rcssNum.exec( jQuery.css( elem, prop ) );
5370
5371	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
5372
5373		// Support: Firefox <=54
5374		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
5375		initial = initial / 2;
5376
5377		// Trust units reported by jQuery.css
5378		unit = unit || initialInUnit[ 3 ];
5379
5380		// Iteratively approximate from a nonzero starting point
5381		initialInUnit = +initial || 1;
5382
5383		while ( maxIterations-- ) {
5384
5385			// Evaluate and update our best guess (doubling guesses that zero out).
5386			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
5387			jQuery.style( elem, prop, initialInUnit + unit );
5388			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
5389				maxIterations = 0;
5390			}
5391			initialInUnit = initialInUnit / scale;
5392
5393		}
5394
5395		initialInUnit = initialInUnit * 2;
5396		jQuery.style( elem, prop, initialInUnit + unit );
5397
5398		// Make sure we update the tween properties later on
5399		valueParts = valueParts || [];
5400	}
5401
5402	if ( valueParts ) {
5403		initialInUnit = +initialInUnit || +initial || 0;
5404
5405		// Apply relative offset (+=/-=) if specified
5406		adjusted = valueParts[ 1 ] ?
5407			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
5408			+valueParts[ 2 ];
5409		if ( tween ) {
5410			tween.unit = unit;
5411			tween.start = initialInUnit;
5412			tween.end = adjusted;
5413		}
5414	}
5415	return adjusted;
5416}
5417
5418
5419var defaultDisplayMap = {};
5420
5421function getDefaultDisplay( elem ) {
5422	var temp,
5423		doc = elem.ownerDocument,
5424		nodeName = elem.nodeName,
5425		display = defaultDisplayMap[ nodeName ];
5426
5427	if ( display ) {
5428		return display;
5429	}
5430
5431	temp = doc.body.appendChild( doc.createElement( nodeName ) );
5432	display = jQuery.css( temp, "display" );
5433
5434	temp.parentNode.removeChild( temp );
5435
5436	if ( display === "none" ) {
5437		display = "block";
5438	}
5439	defaultDisplayMap[ nodeName ] = display;
5440
5441	return display;
5442}
5443
5444function showHide( elements, show ) {
5445	var display, elem,
5446		values = [],
5447		index = 0,
5448		length = elements.length;
5449
5450	// Determine new display value for elements that need to change
5451	for ( ; index < length; index++ ) {
5452		elem = elements[ index ];
5453		if ( !elem.style ) {
5454			continue;
5455		}
5456
5457		display = elem.style.display;
5458		if ( show ) {
5459
5460			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
5461			// check is required in this first loop unless we have a nonempty display value (either
5462			// inline or about-to-be-restored)
5463			if ( display === "none" ) {
5464				values[ index ] = dataPriv.get( elem, "display" ) || null;
5465				if ( !values[ index ] ) {
5466					elem.style.display = "";
5467				}
5468			}
5469			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
5470				values[ index ] = getDefaultDisplay( elem );
5471			}
5472		} else {
5473			if ( display !== "none" ) {
5474				values[ index ] = "none";
5475
5476				// Remember what we're overwriting
5477				dataPriv.set( elem, "display", display );
5478			}
5479		}
5480	}
5481
5482	// Set the display of the elements in a second loop to avoid constant reflow
5483	for ( index = 0; index < length; index++ ) {
5484		if ( values[ index ] != null ) {
5485			elements[ index ].style.display = values[ index ];
5486		}
5487	}
5488
5489	return elements;
5490}
5491
5492jQuery.fn.extend( {
5493	show: function() {
5494		return showHide( this, true );
5495	},
5496	hide: function() {
5497		return showHide( this );
5498	},
5499	toggle: function( state ) {
5500		if ( typeof state === "boolean" ) {
5501			return state ? this.show() : this.hide();
5502		}
5503
5504		return this.each( function() {
5505			if ( isHiddenWithinTree( this ) ) {
5506				jQuery( this ).show();
5507			} else {
5508				jQuery( this ).hide();
5509			}
5510		} );
5511	}
5512} );
5513var rcheckableType = ( /^(?:checkbox|radio)$/i );
5514
5515var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
5516
5517var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
5518
5519
5520
5521( function() {
5522	var fragment = document.createDocumentFragment(),
5523		div = fragment.appendChild( document.createElement( "div" ) ),
5524		input = document.createElement( "input" );
5525
5526	// Support: Android 4.0 - 4.3 only
5527	// Check state lost if the name is set (trac-11217)
5528	// Support: Windows Web Apps (WWA)
5529	// `name` and `type` must use .setAttribute for WWA (trac-14901)
5530	input.setAttribute( "type", "radio" );
5531	input.setAttribute( "checked", "checked" );
5532	input.setAttribute( "name", "t" );
5533
5534	div.appendChild( input );
5535
5536	// Support: Android <=4.1 only
5537	// Older WebKit doesn't clone checked state correctly in fragments
5538	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
5539
5540	// Support: IE <=11 only
5541	// Make sure textarea (and checkbox) defaultValue is properly cloned
5542	div.innerHTML = "<textarea>x</textarea>";
5543	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
5544
5545	// Support: IE <=9 only
5546	// IE <=9 replaces <option> tags with their contents when inserted outside of
5547	// the select element.
5548	div.innerHTML = "<option></option>";
5549	support.option = !!div.lastChild;
5550} )();
5551
5552
5553// We have to close these tags to support XHTML (trac-13200)
5554var wrapMap = {
5555
5556	// XHTML parsers do not magically insert elements in the
5557	// same way that tag soup parsers do. So we cannot shorten
5558	// this by omitting <tbody> or other required elements.
5559	thead: [ 1, "<table>", "</table>" ],
5560	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
5561	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5562	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5563
5564	_default: [ 0, "", "" ]
5565};
5566
5567wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5568wrapMap.th = wrapMap.td;
5569
5570// Support: IE <=9 only
5571if ( !support.option ) {
5572	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
5573}
5574
5575
5576function getAll( context, tag ) {
5577
5578	// Support: IE <=9 - 11 only
5579	// Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
5580	var ret;
5581
5582	if ( typeof context.getElementsByTagName !== "undefined" ) {
5583		ret = context.getElementsByTagName( tag || "*" );
5584
5585	} else if ( typeof context.querySelectorAll !== "undefined" ) {
5586		ret = context.querySelectorAll( tag || "*" );
5587
5588	} else {
5589		ret = [];
5590	}
5591
5592	if ( tag === undefined || tag && nodeName( context, tag ) ) {
5593		return jQuery.merge( [ context ], ret );
5594	}
5595
5596	return ret;
5597}
5598
5599
5600// Mark scripts as having already been evaluated
5601function setGlobalEval( elems, refElements ) {
5602	var i = 0,
5603		l = elems.length;
5604
5605	for ( ; i < l; i++ ) {
5606		dataPriv.set(
5607			elems[ i ],
5608			"globalEval",
5609			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
5610		);
5611	}
5612}
5613
5614
5615var rhtml = /<|&#?\w+;/;
5616
5617function buildFragment( elems, context, scripts, selection, ignored ) {
5618	var elem, tmp, tag, wrap, attached, j,
5619		fragment = context.createDocumentFragment(),
5620		nodes = [],
5621		i = 0,
5622		l = elems.length;
5623
5624	for ( ; i < l; i++ ) {
5625		elem = elems[ i ];
5626
5627		if ( elem || elem === 0 ) {
5628
5629			// Add nodes directly
5630			if ( toType( elem ) === "object" ) {
5631
5632				// Support: Android <=4.0 only, PhantomJS 1 only
5633				// push.apply(_, arraylike) throws on ancient WebKit
5634				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5635
5636			// Convert non-html into a text node
5637			} else if ( !rhtml.test( elem ) ) {
5638				nodes.push( context.createTextNode( elem ) );
5639
5640			// Convert html into DOM nodes
5641			} else {
5642				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5643
5644				// Deserialize a standard representation
5645				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5646				wrap = wrapMap[ tag ] || wrapMap._default;
5647				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5648
5649				// Descend through wrappers to the right content
5650				j = wrap[ 0 ];
5651				while ( j-- ) {
5652					tmp = tmp.lastChild;
5653				}
5654
5655				// Support: Android <=4.0 only, PhantomJS 1 only
5656				// push.apply(_, arraylike) throws on ancient WebKit
5657				jQuery.merge( nodes, tmp.childNodes );
5658
5659				// Remember the top-level container
5660				tmp = fragment.firstChild;
5661
5662				// Ensure the created nodes are orphaned (trac-12392)
5663				tmp.textContent = "";
5664			}
5665		}
5666	}
5667
5668	// Remove wrapper from fragment
5669	fragment.textContent = "";
5670
5671	i = 0;
5672	while ( ( elem = nodes[ i++ ] ) ) {
5673
5674		// Skip elements already in the context collection (trac-4087)
5675		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5676			if ( ignored ) {
5677				ignored.push( elem );
5678			}
5679			continue;
5680		}
5681
5682		attached = isAttached( elem );
5683
5684		// Append to fragment
5685		tmp = getAll( fragment.appendChild( elem ), "script" );
5686
5687		// Preserve script evaluation history
5688		if ( attached ) {
5689			setGlobalEval( tmp );
5690		}
5691
5692		// Capture executables
5693		if ( scripts ) {
5694			j = 0;
5695			while ( ( elem = tmp[ j++ ] ) ) {
5696				if ( rscriptType.test( elem.type || "" ) ) {
5697					scripts.push( elem );
5698				}
5699			}
5700		}
5701	}
5702
5703	return fragment;
5704}
5705
5706
5707var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5708
5709function returnTrue() {
5710	return true;
5711}
5712
5713function returnFalse() {
5714	return false;
5715}
5716
5717function on( elem, types, selector, data, fn, one ) {
5718	var origFn, type;
5719
5720	// Types can be a map of types/handlers
5721	if ( typeof types === "object" ) {
5722
5723		// ( types-Object, selector, data )
5724		if ( typeof selector !== "string" ) {
5725
5726			// ( types-Object, data )
5727			data = data || selector;
5728			selector = undefined;
5729		}
5730		for ( type in types ) {
5731			on( elem, type, selector, data, types[ type ], one );
5732		}
5733		return elem;
5734	}
5735
5736	if ( data == null && fn == null ) {
5737
5738		// ( types, fn )
5739		fn = selector;
5740		data = selector = undefined;
5741	} else if ( fn == null ) {
5742		if ( typeof selector === "string" ) {
5743
5744			// ( types, selector, fn )
5745			fn = data;
5746			data = undefined;
5747		} else {
5748
5749			// ( types, data, fn )
5750			fn = data;
5751			data = selector;
5752			selector = undefined;
5753		}
5754	}
5755	if ( fn === false ) {
5756		fn = returnFalse;
5757	} else if ( !fn ) {
5758		return elem;
5759	}
5760
5761	if ( one === 1 ) {
5762		origFn = fn;
5763		fn = function( event ) {
5764
5765			// Can use an empty set, since event contains the info
5766			jQuery().off( event );
5767			return origFn.apply( this, arguments );
5768		};
5769
5770		// Use same guid so caller can remove using origFn
5771		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5772	}
5773	return elem.each( function() {
5774		jQuery.event.add( this, types, fn, data, selector );
5775	} );
5776}
5777
5778/*
5779 * Helper functions for managing events -- not part of the public interface.
5780 * Props to Dean Edwards' addEvent library for many of the ideas.
5781 */
5782jQuery.event = {
5783
5784	global: {},
5785
5786	add: function( elem, types, handler, data, selector ) {
5787
5788		var handleObjIn, eventHandle, tmp,
5789			events, t, handleObj,
5790			special, handlers, type, namespaces, origType,
5791			elemData = dataPriv.get( elem );
5792
5793		// Only attach events to objects that accept data
5794		if ( !acceptData( elem ) ) {
5795			return;
5796		}
5797
5798		// Caller can pass in an object of custom data in lieu of the handler
5799		if ( handler.handler ) {
5800			handleObjIn = handler;
5801			handler = handleObjIn.handler;
5802			selector = handleObjIn.selector;
5803		}
5804
5805		// Ensure that invalid selectors throw exceptions at attach time
5806		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
5807		if ( selector ) {
5808			jQuery.find.matchesSelector( documentElement, selector );
5809		}
5810
5811		// Make sure that the handler has a unique ID, used to find/remove it later
5812		if ( !handler.guid ) {
5813			handler.guid = jQuery.guid++;
5814		}
5815
5816		// Init the element's event structure and main handler, if this is the first
5817		if ( !( events = elemData.events ) ) {
5818			events = elemData.events = Object.create( null );
5819		}
5820		if ( !( eventHandle = elemData.handle ) ) {
5821			eventHandle = elemData.handle = function( e ) {
5822
5823				// Discard the second event of a jQuery.event.trigger() and
5824				// when an event is called after a page has unloaded
5825				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5826					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5827			};
5828		}
5829
5830		// Handle multiple events separated by a space
5831		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5832		t = types.length;
5833		while ( t-- ) {
5834			tmp = rtypenamespace.exec( types[ t ] ) || [];
5835			type = origType = tmp[ 1 ];
5836			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5837
5838			// There *must* be a type, no attaching namespace-only handlers
5839			if ( !type ) {
5840				continue;
5841			}
5842
5843			// If event changes its type, use the special event handlers for the changed type
5844			special = jQuery.event.special[ type ] || {};
5845
5846			// If selector defined, determine special event api type, otherwise given type
5847			type = ( selector ? special.delegateType : special.bindType ) || type;
5848
5849			// Update special based on newly reset type
5850			special = jQuery.event.special[ type ] || {};
5851
5852			// handleObj is passed to all event handlers
5853			handleObj = jQuery.extend( {
5854				type: type,
5855				origType: origType,
5856				data: data,
5857				handler: handler,
5858				guid: handler.guid,
5859				selector: selector,
5860				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5861				namespace: namespaces.join( "." )
5862			}, handleObjIn );
5863
5864			// Init the event handler queue if we're the first
5865			if ( !( handlers = events[ type ] ) ) {
5866				handlers = events[ type ] = [];
5867				handlers.delegateCount = 0;
5868
5869				// Only use addEventListener if the special events handler returns false
5870				if ( !special.setup ||
5871					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5872
5873					if ( elem.addEventListener ) {
5874						elem.addEventListener( type, eventHandle );
5875					}
5876				}
5877			}
5878
5879			if ( special.add ) {
5880				special.add.call( elem, handleObj );
5881
5882				if ( !handleObj.handler.guid ) {
5883					handleObj.handler.guid = handler.guid;
5884				}
5885			}
5886
5887			// Add to the element's handler list, delegates in front
5888			if ( selector ) {
5889				handlers.splice( handlers.delegateCount++, 0, handleObj );
5890			} else {
5891				handlers.push( handleObj );
5892			}
5893
5894			// Keep track of which events have ever been used, for event optimization
5895			jQuery.event.global[ type ] = true;
5896		}
5897
5898	},
5899
5900	// Detach an event or set of events from an element
5901	remove: function( elem, types, handler, selector, mappedTypes ) {
5902
5903		var j, origCount, tmp,
5904			events, t, handleObj,
5905			special, handlers, type, namespaces, origType,
5906			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5907
5908		if ( !elemData || !( events = elemData.events ) ) {
5909			return;
5910		}
5911
5912		// Once for each type.namespace in types; type may be omitted
5913		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5914		t = types.length;
5915		while ( t-- ) {
5916			tmp = rtypenamespace.exec( types[ t ] ) || [];
5917			type = origType = tmp[ 1 ];
5918			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5919
5920			// Unbind all events (on this namespace, if provided) for the element
5921			if ( !type ) {
5922				for ( type in events ) {
5923					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5924				}
5925				continue;
5926			}
5927
5928			special = jQuery.event.special[ type ] || {};
5929			type = ( selector ? special.delegateType : special.bindType ) || type;
5930			handlers = events[ type ] || [];
5931			tmp = tmp[ 2 ] &&
5932				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5933
5934			// Remove matching events
5935			origCount = j = handlers.length;
5936			while ( j-- ) {
5937				handleObj = handlers[ j ];
5938
5939				if ( ( mappedTypes || origType === handleObj.origType ) &&
5940					( !handler || handler.guid === handleObj.guid ) &&
5941					( !tmp || tmp.test( handleObj.namespace ) ) &&
5942					( !selector || selector === handleObj.selector ||
5943						selector === "**" && handleObj.selector ) ) {
5944					handlers.splice( j, 1 );
5945
5946					if ( handleObj.selector ) {
5947						handlers.delegateCount--;
5948					}
5949					if ( special.remove ) {
5950						special.remove.call( elem, handleObj );
5951					}
5952				}
5953			}
5954
5955			// Remove generic event handler if we removed something and no more handlers exist
5956			// (avoids potential for endless recursion during removal of special event handlers)
5957			if ( origCount && !handlers.length ) {
5958				if ( !special.teardown ||
5959					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5960
5961					jQuery.removeEvent( elem, type, elemData.handle );
5962				}
5963
5964				delete events[ type ];
5965			}
5966		}
5967
5968		// Remove data and the expando if it's no longer used
5969		if ( jQuery.isEmptyObject( events ) ) {
5970			dataPriv.remove( elem, "handle events" );
5971		}
5972	},
5973
5974	dispatch: function( nativeEvent ) {
5975
5976		var i, j, ret, matched, handleObj, handlerQueue,
5977			args = new Array( arguments.length ),
5978
5979			// Make a writable jQuery.Event from the native event object
5980			event = jQuery.event.fix( nativeEvent ),
5981
5982			handlers = (
5983				dataPriv.get( this, "events" ) || Object.create( null )
5984			)[ event.type ] || [],
5985			special = jQuery.event.special[ event.type ] || {};
5986
5987		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5988		args[ 0 ] = event;
5989
5990		for ( i = 1; i < arguments.length; i++ ) {
5991			args[ i ] = arguments[ i ];
5992		}
5993
5994		event.delegateTarget = this;
5995
5996		// Call the preDispatch hook for the mapped type, and let it bail if desired
5997		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5998			return;
5999		}
6000
6001		// Determine handlers
6002		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
6003
6004		// Run delegates first; they may want to stop propagation beneath us
6005		i = 0;
6006		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
6007			event.currentTarget = matched.elem;
6008
6009			j = 0;
6010			while ( ( handleObj = matched.handlers[ j++ ] ) &&
6011				!event.isImmediatePropagationStopped() ) {
6012
6013				// If the event is namespaced, then each handler is only invoked if it is
6014				// specially universal or its namespaces are a superset of the event's.
6015				if ( !event.rnamespace || handleObj.namespace === false ||
6016					event.rnamespace.test( handleObj.namespace ) ) {
6017
6018					event.handleObj = handleObj;
6019					event.data = handleObj.data;
6020
6021					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
6022						handleObj.handler ).apply( matched.elem, args );
6023
6024					if ( ret !== undefined ) {
6025						if ( ( event.result = ret ) === false ) {
6026							event.preventDefault();
6027							event.stopPropagation();
6028						}
6029					}
6030				}
6031			}
6032		}
6033
6034		// Call the postDispatch hook for the mapped type
6035		if ( special.postDispatch ) {
6036			special.postDispatch.call( this, event );
6037		}
6038
6039		return event.result;
6040	},
6041
6042	handlers: function( event, handlers ) {
6043		var i, handleObj, sel, matchedHandlers, matchedSelectors,
6044			handlerQueue = [],
6045			delegateCount = handlers.delegateCount,
6046			cur = event.target;
6047
6048		// Find delegate handlers
6049		if ( delegateCount &&
6050
6051			// Support: IE <=9
6052			// Black-hole SVG <use> instance trees (trac-13180)
6053			cur.nodeType &&
6054
6055			// Support: Firefox <=42
6056			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
6057			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
6058			// Support: IE 11 only
6059			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
6060			!( event.type === "click" && event.button >= 1 ) ) {
6061
6062			for ( ; cur !== this; cur = cur.parentNode || this ) {
6063
6064				// Don't check non-elements (trac-13208)
6065				// Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
6066				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
6067					matchedHandlers = [];
6068					matchedSelectors = {};
6069					for ( i = 0; i < delegateCount; i++ ) {
6070						handleObj = handlers[ i ];
6071
6072						// Don't conflict with Object.prototype properties (trac-13203)
6073						sel = handleObj.selector + " ";
6074
6075						if ( matchedSelectors[ sel ] === undefined ) {
6076							matchedSelectors[ sel ] = handleObj.needsContext ?
6077								jQuery( sel, this ).index( cur ) > -1 :
6078								jQuery.find( sel, this, null, [ cur ] ).length;
6079						}
6080						if ( matchedSelectors[ sel ] ) {
6081							matchedHandlers.push( handleObj );
6082						}
6083					}
6084					if ( matchedHandlers.length ) {
6085						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
6086					}
6087				}
6088			}
6089		}
6090
6091		// Add the remaining (directly-bound) handlers
6092		cur = this;
6093		if ( delegateCount < handlers.length ) {
6094			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
6095		}
6096
6097		return handlerQueue;
6098	},
6099
6100	addProp: function( name, hook ) {
6101		Object.defineProperty( jQuery.Event.prototype, name, {
6102			enumerable: true,
6103			configurable: true,
6104
6105			get: isFunction( hook ) ?
6106				function() {
6107					if ( this.originalEvent ) {
6108						return hook( this.originalEvent );
6109					}
6110				} :
6111				function() {
6112					if ( this.originalEvent ) {
6113						return this.originalEvent[ name ];
6114					}
6115				},
6116
6117			set: function( value ) {
6118				Object.defineProperty( this, name, {
6119					enumerable: true,
6120					configurable: true,
6121					writable: true,
6122					value: value
6123				} );
6124			}
6125		} );
6126	},
6127
6128	fix: function( originalEvent ) {
6129		return originalEvent[ jQuery.expando ] ?
6130			originalEvent :
6131			new jQuery.Event( originalEvent );
6132	},
6133
6134	special: {
6135		load: {
6136
6137			// Prevent triggered image.load events from bubbling to window.load
6138			noBubble: true
6139		},
6140		click: {
6141
6142			// Utilize native event to ensure correct state for checkable inputs
6143			setup: function( data ) {
6144
6145				// For mutual compressibility with _default, replace `this` access with a local var.
6146				// `|| data` is dead code meant only to preserve the variable through minification.
6147				var el = this || data;
6148
6149				// Claim the first handler
6150				if ( rcheckableType.test( el.type ) &&
6151					el.click && nodeName( el, "input" ) ) {
6152
6153					// dataPriv.set( el, "click", ... )
6154					leverageNative( el, "click", true );
6155				}
6156
6157				// Return false to allow normal processing in the caller
6158				return false;
6159			},
6160			trigger: function( data ) {
6161
6162				// For mutual compressibility with _default, replace `this` access with a local var.
6163				// `|| data` is dead code meant only to preserve the variable through minification.
6164				var el = this || data;
6165
6166				// Force setup before triggering a click
6167				if ( rcheckableType.test( el.type ) &&
6168					el.click && nodeName( el, "input" ) ) {
6169
6170					leverageNative( el, "click" );
6171				}
6172
6173				// Return non-false to allow normal event-path propagation
6174				return true;
6175			},
6176
6177			// For cross-browser consistency, suppress native .click() on links
6178			// Also prevent it if we're currently inside a leveraged native-event stack
6179			_default: function( event ) {
6180				var target = event.target;
6181				return rcheckableType.test( target.type ) &&
6182					target.click && nodeName( target, "input" ) &&
6183					dataPriv.get( target, "click" ) ||
6184					nodeName( target, "a" );
6185			}
6186		},
6187
6188		beforeunload: {
6189			postDispatch: function( event ) {
6190
6191				// Support: Firefox 20+
6192				// Firefox doesn't alert if the returnValue field is not set.
6193				if ( event.result !== undefined && event.originalEvent ) {
6194					event.originalEvent.returnValue = event.result;
6195				}
6196			}
6197		}
6198	}
6199};
6200
6201// Ensure the presence of an event listener that handles manually-triggered
6202// synthetic events by interrupting progress until reinvoked in response to
6203// *native* events that it fires directly, ensuring that state changes have
6204// already occurred before other listeners are invoked.
6205function leverageNative( el, type, isSetup ) {
6206
6207	// Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
6208	if ( !isSetup ) {
6209		if ( dataPriv.get( el, type ) === undefined ) {
6210			jQuery.event.add( el, type, returnTrue );
6211		}
6212		return;
6213	}
6214
6215	// Register the controller as a special universal handler for all event namespaces
6216	dataPriv.set( el, type, false );
6217	jQuery.event.add( el, type, {
6218		namespace: false,
6219		handler: function( event ) {
6220			var result,
6221				saved = dataPriv.get( this, type );
6222
6223			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
6224
6225				// Interrupt processing of the outer synthetic .trigger()ed event
6226				if ( !saved ) {
6227
6228					// Store arguments for use when handling the inner native event
6229					// There will always be at least one argument (an event object), so this array
6230					// will not be confused with a leftover capture object.
6231					saved = slice.call( arguments );
6232					dataPriv.set( this, type, saved );
6233
6234					// Trigger the native event and capture its result
6235					this[ type ]();
6236					result = dataPriv.get( this, type );
6237					dataPriv.set( this, type, false );
6238
6239					if ( saved !== result ) {
6240
6241						// Cancel the outer synthetic event
6242						event.stopImmediatePropagation();
6243						event.preventDefault();
6244
6245						return result;
6246					}
6247
6248				// If this is an inner synthetic event for an event with a bubbling surrogate
6249				// (focus or blur), assume that the surrogate already propagated from triggering
6250				// the native event and prevent that from happening again here.
6251				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
6252				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
6253				// less bad than duplication.
6254				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
6255					event.stopPropagation();
6256				}
6257
6258			// If this is a native event triggered above, everything is now in order
6259			// Fire an inner synthetic event with the original arguments
6260			} else if ( saved ) {
6261
6262				// ...and capture the result
6263				dataPriv.set( this, type, jQuery.event.trigger(
6264					saved[ 0 ],
6265					saved.slice( 1 ),
6266					this
6267				) );
6268
6269				// Abort handling of the native event by all jQuery handlers while allowing
6270				// native handlers on the same element to run. On target, this is achieved
6271				// by stopping immediate propagation just on the jQuery event. However,
6272				// the native event is re-wrapped by a jQuery one on each level of the
6273				// propagation so the only way to stop it for jQuery is to stop it for
6274				// everyone via native `stopPropagation()`. This is not a problem for
6275				// focus/blur which don't bubble, but it does also stop click on checkboxes
6276				// and radios. We accept this limitation.
6277				event.stopPropagation();
6278				event.isImmediatePropagationStopped = returnTrue;
6279			}
6280		}
6281	} );
6282}
6283
6284jQuery.removeEvent = function( elem, type, handle ) {
6285
6286	// This "if" is needed for plain objects
6287	if ( elem.removeEventListener ) {
6288		elem.removeEventListener( type, handle );
6289	}
6290};
6291
6292jQuery.Event = function( src, props ) {
6293
6294	// Allow instantiation without the 'new' keyword
6295	if ( !( this instanceof jQuery.Event ) ) {
6296		return new jQuery.Event( src, props );
6297	}
6298
6299	// Event object
6300	if ( src && src.type ) {
6301		this.originalEvent = src;
6302		this.type = src.type;
6303
6304		// Events bubbling up the document may have been marked as prevented
6305		// by a handler lower down the tree; reflect the correct value.
6306		this.isDefaultPrevented = src.defaultPrevented ||
6307				src.defaultPrevented === undefined &&
6308
6309				// Support: Android <=2.3 only
6310				src.returnValue === false ?
6311			returnTrue :
6312			returnFalse;
6313
6314		// Create target properties
6315		// Support: Safari <=6 - 7 only
6316		// Target should not be a text node (trac-504, trac-13143)
6317		this.target = ( src.target && src.target.nodeType === 3 ) ?
6318			src.target.parentNode :
6319			src.target;
6320
6321		this.currentTarget = src.currentTarget;
6322		this.relatedTarget = src.relatedTarget;
6323
6324	// Event type
6325	} else {
6326		this.type = src;
6327	}
6328
6329	// Put explicitly provided properties onto the event object
6330	if ( props ) {
6331		jQuery.extend( this, props );
6332	}
6333
6334	// Create a timestamp if incoming event doesn't have one
6335	this.timeStamp = src && src.timeStamp || Date.now();
6336
6337	// Mark it as fixed
6338	this[ jQuery.expando ] = true;
6339};
6340
6341// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
6342// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
6343jQuery.Event.prototype = {
6344	constructor: jQuery.Event,
6345	isDefaultPrevented: returnFalse,
6346	isPropagationStopped: returnFalse,
6347	isImmediatePropagationStopped: returnFalse,
6348	isSimulated: false,
6349
6350	preventDefault: function() {
6351		var e = this.originalEvent;
6352
6353		this.isDefaultPrevented = returnTrue;
6354
6355		if ( e && !this.isSimulated ) {
6356			e.preventDefault();
6357		}
6358	},
6359	stopPropagation: function() {
6360		var e = this.originalEvent;
6361
6362		this.isPropagationStopped = returnTrue;
6363
6364		if ( e && !this.isSimulated ) {
6365			e.stopPropagation();
6366		}
6367	},
6368	stopImmediatePropagation: function() {
6369		var e = this.originalEvent;
6370
6371		this.isImmediatePropagationStopped = returnTrue;
6372
6373		if ( e && !this.isSimulated ) {
6374			e.stopImmediatePropagation();
6375		}
6376
6377		this.stopPropagation();
6378	}
6379};
6380
6381// Includes all common event props including KeyEvent and MouseEvent specific props
6382jQuery.each( {
6383	altKey: true,
6384	bubbles: true,
6385	cancelable: true,
6386	changedTouches: true,
6387	ctrlKey: true,
6388	detail: true,
6389	eventPhase: true,
6390	metaKey: true,
6391	pageX: true,
6392	pageY: true,
6393	shiftKey: true,
6394	view: true,
6395	"char": true,
6396	code: true,
6397	charCode: true,
6398	key: true,
6399	keyCode: true,
6400	button: true,
6401	buttons: true,
6402	clientX: true,
6403	clientY: true,
6404	offsetX: true,
6405	offsetY: true,
6406	pointerId: true,
6407	pointerType: true,
6408	screenX: true,
6409	screenY: true,
6410	targetTouches: true,
6411	toElement: true,
6412	touches: true,
6413	which: true
6414}, jQuery.event.addProp );
6415
6416jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
6417
6418	function focusMappedHandler( nativeEvent ) {
6419		if ( document.documentMode ) {
6420
6421			// Support: IE 11+
6422			// Attach a single focusin/focusout handler on the document while someone wants
6423			// focus/blur. This is because the former are synchronous in IE while the latter
6424			// are async. In other browsers, all those handlers are invoked synchronously.
6425
6426			// `handle` from private data would already wrap the event, but we need
6427			// to change the `type` here.
6428			var handle = dataPriv.get( this, "handle" ),
6429				event = jQuery.event.fix( nativeEvent );
6430			event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
6431			event.isSimulated = true;
6432
6433			// First, handle focusin/focusout
6434			handle( nativeEvent );
6435
6436			// ...then, handle focus/blur
6437			//
6438			// focus/blur don't bubble while focusin/focusout do; simulate the former by only
6439			// invoking the handler at the lower level.
6440			if ( event.target === event.currentTarget ) {
6441
6442				// The setup part calls `leverageNative`, which, in turn, calls
6443				// `jQuery.event.add`, so event handle will already have been set
6444				// by this point.
6445				handle( event );
6446			}
6447		} else {
6448
6449			// For non-IE browsers, attach a single capturing handler on the document
6450			// while someone wants focusin/focusout.
6451			jQuery.event.simulate( delegateType, nativeEvent.target,
6452				jQuery.event.fix( nativeEvent ) );
6453		}
6454	}
6455
6456	jQuery.event.special[ type ] = {
6457
6458		// Utilize native event if possible so blur/focus sequence is correct
6459		setup: function() {
6460
6461			var attaches;
6462
6463			// Claim the first handler
6464			// dataPriv.set( this, "focus", ... )
6465			// dataPriv.set( this, "blur", ... )
6466			leverageNative( this, type, true );
6467
6468			if ( document.documentMode ) {
6469
6470				// Support: IE 9 - 11+
6471				// We use the same native handler for focusin & focus (and focusout & blur)
6472				// so we need to coordinate setup & teardown parts between those events.
6473				// Use `delegateType` as the key as `type` is already used by `leverageNative`.
6474				attaches = dataPriv.get( this, delegateType );
6475				if ( !attaches ) {
6476					this.addEventListener( delegateType, focusMappedHandler );
6477				}
6478				dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 );
6479			} else {
6480
6481				// Return false to allow normal processing in the caller
6482				return false;
6483			}
6484		},
6485		trigger: function() {
6486
6487			// Force setup before trigger
6488			leverageNative( this, type );
6489
6490			// Return non-false to allow normal event-path propagation
6491			return true;
6492		},
6493
6494		teardown: function() {
6495			var attaches;
6496
6497			if ( document.documentMode ) {
6498				attaches = dataPriv.get( this, delegateType ) - 1;
6499				if ( !attaches ) {
6500					this.removeEventListener( delegateType, focusMappedHandler );
6501					dataPriv.remove( this, delegateType );
6502				} else {
6503					dataPriv.set( this, delegateType, attaches );
6504				}
6505			} else {
6506
6507				// Return false to indicate standard teardown should be applied
6508				return false;
6509			}
6510		},
6511
6512		// Suppress native focus or blur if we're currently inside
6513		// a leveraged native-event stack
6514		_default: function( event ) {
6515			return dataPriv.get( event.target, type );
6516		},
6517
6518		delegateType: delegateType
6519	};
6520
6521	// Support: Firefox <=44
6522	// Firefox doesn't have focus(in | out) events
6523	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
6524	//
6525	// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
6526	// focus(in | out) events fire after focus & blur events,
6527	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
6528	// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
6529	//
6530	// Support: IE 9 - 11+
6531	// To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
6532	// attach a single handler for both events in IE.
6533	jQuery.event.special[ delegateType ] = {
6534		setup: function() {
6535
6536			// Handle: regular nodes (via `this.ownerDocument`), window
6537			// (via `this.document`) & document (via `this`).
6538			var doc = this.ownerDocument || this.document || this,
6539				dataHolder = document.documentMode ? this : doc,
6540				attaches = dataPriv.get( dataHolder, delegateType );
6541
6542			// Support: IE 9 - 11+
6543			// We use the same native handler for focusin & focus (and focusout & blur)
6544			// so we need to coordinate setup & teardown parts between those events.
6545			// Use `delegateType` as the key as `type` is already used by `leverageNative`.
6546			if ( !attaches ) {
6547				if ( document.documentMode ) {
6548					this.addEventListener( delegateType, focusMappedHandler );
6549				} else {
6550					doc.addEventListener( type, focusMappedHandler, true );
6551				}
6552			}
6553			dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 );
6554		},
6555		teardown: function() {
6556			var doc = this.ownerDocument || this.document || this,
6557				dataHolder = document.documentMode ? this : doc,
6558				attaches = dataPriv.get( dataHolder, delegateType ) - 1;
6559
6560			if ( !attaches ) {
6561				if ( document.documentMode ) {
6562					this.removeEventListener( delegateType, focusMappedHandler );
6563				} else {
6564					doc.removeEventListener( type, focusMappedHandler, true );
6565				}
6566				dataPriv.remove( dataHolder, delegateType );
6567			} else {
6568				dataPriv.set( dataHolder, delegateType, attaches );
6569			}
6570		}
6571	};
6572} );
6573
6574// Create mouseenter/leave events using mouseover/out and event-time checks
6575// so that event delegation works in jQuery.
6576// Do the same for pointerenter/pointerleave and pointerover/pointerout
6577//
6578// Support: Safari 7 only
6579// Safari sends mouseenter too often; see:
6580// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
6581// for the description of the bug (it existed in older Chrome versions as well).
6582jQuery.each( {
6583	mouseenter: "mouseover",
6584	mouseleave: "mouseout",
6585	pointerenter: "pointerover",
6586	pointerleave: "pointerout"
6587}, function( orig, fix ) {
6588	jQuery.event.special[ orig ] = {
6589		delegateType: fix,
6590		bindType: fix,
6591
6592		handle: function( event ) {
6593			var ret,
6594				target = this,
6595				related = event.relatedTarget,
6596				handleObj = event.handleObj;
6597
6598			// For mouseenter/leave call the handler if related is outside the target.
6599			// NB: No relatedTarget if the mouse left/entered the browser window
6600			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
6601				event.type = handleObj.origType;
6602				ret = handleObj.handler.apply( this, arguments );
6603				event.type = fix;
6604			}
6605			return ret;
6606		}
6607	};
6608} );
6609
6610jQuery.fn.extend( {
6611
6612	on: function( types, selector, data, fn ) {
6613		return on( this, types, selector, data, fn );
6614	},
6615	one: function( types, selector, data, fn ) {
6616		return on( this, types, selector, data, fn, 1 );
6617	},
6618	off: function( types, selector, fn ) {
6619		var handleObj, type;
6620		if ( types && types.preventDefault && types.handleObj ) {
6621
6622			// ( event )  dispatched jQuery.Event
6623			handleObj = types.handleObj;
6624			jQuery( types.delegateTarget ).off(
6625				handleObj.namespace ?
6626					handleObj.origType + "." + handleObj.namespace :
6627					handleObj.origType,
6628				handleObj.selector,
6629				handleObj.handler
6630			);
6631			return this;
6632		}
6633		if ( typeof types === "object" ) {
6634
6635			// ( types-object [, selector] )
6636			for ( type in types ) {
6637				this.off( type, selector, types[ type ] );
6638			}
6639			return this;
6640		}
6641		if ( selector === false || typeof selector === "function" ) {
6642
6643			// ( types [, fn] )
6644			fn = selector;
6645			selector = undefined;
6646		}
6647		if ( fn === false ) {
6648			fn = returnFalse;
6649		}
6650		return this.each( function() {
6651			jQuery.event.remove( this, types, fn, selector );
6652		} );
6653	}
6654} );
6655
6656
6657var
6658
6659	// Support: IE <=10 - 11, Edge 12 - 13 only
6660	// In IE/Edge using regex groups here causes severe slowdowns.
6661	// See https://connect.microsoft.com/IE/feedback/details/1736512/
6662	rnoInnerhtml = /<script|<style|<link/i,
6663
6664	// checked="checked" or checked
6665	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
6666
6667	rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
6668
6669// Prefer a tbody over its parent table for containing new rows
6670function manipulationTarget( elem, content ) {
6671	if ( nodeName( elem, "table" ) &&
6672		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
6673
6674		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
6675	}
6676
6677	return elem;
6678}
6679
6680// Replace/restore the type attribute of script elements for safe DOM manipulation
6681function disableScript( elem ) {
6682	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
6683	return elem;
6684}
6685function restoreScript( elem ) {
6686	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
6687		elem.type = elem.type.slice( 5 );
6688	} else {
6689		elem.removeAttribute( "type" );
6690	}
6691
6692	return elem;
6693}
6694
6695function cloneCopyEvent( src, dest ) {
6696	var i, l, type, pdataOld, udataOld, udataCur, events;
6697
6698	if ( dest.nodeType !== 1 ) {
6699		return;
6700	}
6701
6702	// 1. Copy private data: events, handlers, etc.
6703	if ( dataPriv.hasData( src ) ) {
6704		pdataOld = dataPriv.get( src );
6705		events = pdataOld.events;
6706
6707		if ( events ) {
6708			dataPriv.remove( dest, "handle events" );
6709
6710			for ( type in events ) {
6711				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6712					jQuery.event.add( dest, type, events[ type ][ i ] );
6713				}
6714			}
6715		}
6716	}
6717
6718	// 2. Copy user data
6719	if ( dataUser.hasData( src ) ) {
6720		udataOld = dataUser.access( src );
6721		udataCur = jQuery.extend( {}, udataOld );
6722
6723		dataUser.set( dest, udataCur );
6724	}
6725}
6726
6727// Fix IE bugs, see support tests
6728function fixInput( src, dest ) {
6729	var nodeName = dest.nodeName.toLowerCase();
6730
6731	// Fails to persist the checked state of a cloned checkbox or radio button.
6732	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6733		dest.checked = src.checked;
6734
6735	// Fails to return the selected option to the default selected state when cloning options
6736	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6737		dest.defaultValue = src.defaultValue;
6738	}
6739}
6740
6741function domManip( collection, args, callback, ignored ) {
6742
6743	// Flatten any nested arrays
6744	args = flat( args );
6745
6746	var fragment, first, scripts, hasScripts, node, doc,
6747		i = 0,
6748		l = collection.length,
6749		iNoClone = l - 1,
6750		value = args[ 0 ],
6751		valueIsFunction = isFunction( value );
6752
6753	// We can't cloneNode fragments that contain checked, in WebKit
6754	if ( valueIsFunction ||
6755			( l > 1 && typeof value === "string" &&
6756				!support.checkClone && rchecked.test( value ) ) ) {
6757		return collection.each( function( index ) {
6758			var self = collection.eq( index );
6759			if ( valueIsFunction ) {
6760				args[ 0 ] = value.call( this, index, self.html() );
6761			}
6762			domManip( self, args, callback, ignored );
6763		} );
6764	}
6765
6766	if ( l ) {
6767		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6768		first = fragment.firstChild;
6769
6770		if ( fragment.childNodes.length === 1 ) {
6771			fragment = first;
6772		}
6773
6774		// Require either new content or an interest in ignored elements to invoke the callback
6775		if ( first || ignored ) {
6776			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6777			hasScripts = scripts.length;
6778
6779			// Use the original fragment for the last item
6780			// instead of the first because it can end up
6781			// being emptied incorrectly in certain situations (trac-8070).
6782			for ( ; i < l; i++ ) {
6783				node = fragment;
6784
6785				if ( i !== iNoClone ) {
6786					node = jQuery.clone( node, true, true );
6787
6788					// Keep references to cloned scripts for later restoration
6789					if ( hasScripts ) {
6790
6791						// Support: Android <=4.0 only, PhantomJS 1 only
6792						// push.apply(_, arraylike) throws on ancient WebKit
6793						jQuery.merge( scripts, getAll( node, "script" ) );
6794					}
6795				}
6796
6797				callback.call( collection[ i ], node, i );
6798			}
6799
6800			if ( hasScripts ) {
6801				doc = scripts[ scripts.length - 1 ].ownerDocument;
6802
6803				// Re-enable scripts
6804				jQuery.map( scripts, restoreScript );
6805
6806				// Evaluate executable scripts on first document insertion
6807				for ( i = 0; i < hasScripts; i++ ) {
6808					node = scripts[ i ];
6809					if ( rscriptType.test( node.type || "" ) &&
6810						!dataPriv.access( node, "globalEval" ) &&
6811						jQuery.contains( doc, node ) ) {
6812
6813						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
6814
6815							// Optional AJAX dependency, but won't run scripts if not present
6816							if ( jQuery._evalUrl && !node.noModule ) {
6817								jQuery._evalUrl( node.src, {
6818									nonce: node.nonce || node.getAttribute( "nonce" )
6819								}, doc );
6820							}
6821						} else {
6822
6823							// Unwrap a CDATA section containing script contents. This shouldn't be
6824							// needed as in XML documents they're already not visible when
6825							// inspecting element contents and in HTML documents they have no
6826							// meaning but we're preserving that logic for backwards compatibility.
6827							// This will be removed completely in 4.0. See gh-4904.
6828							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6829						}
6830					}
6831				}
6832			}
6833		}
6834	}
6835
6836	return collection;
6837}
6838
6839function remove( elem, selector, keepData ) {
6840	var node,
6841		nodes = selector ? jQuery.filter( selector, elem ) : elem,
6842		i = 0;
6843
6844	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6845		if ( !keepData && node.nodeType === 1 ) {
6846			jQuery.cleanData( getAll( node ) );
6847		}
6848
6849		if ( node.parentNode ) {
6850			if ( keepData && isAttached( node ) ) {
6851				setGlobalEval( getAll( node, "script" ) );
6852			}
6853			node.parentNode.removeChild( node );
6854		}
6855	}
6856
6857	return elem;
6858}
6859
6860jQuery.extend( {
6861	htmlPrefilter: function( html ) {
6862		return html;
6863	},
6864
6865	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6866		var i, l, srcElements, destElements,
6867			clone = elem.cloneNode( true ),
6868			inPage = isAttached( elem );
6869
6870		// Fix IE cloning issues
6871		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6872				!jQuery.isXMLDoc( elem ) ) {
6873
6874			// We eschew jQuery#find here for performance reasons:
6875			// https://jsperf.com/getall-vs-sizzle/2
6876			destElements = getAll( clone );
6877			srcElements = getAll( elem );
6878
6879			for ( i = 0, l = srcElements.length; i < l; i++ ) {
6880				fixInput( srcElements[ i ], destElements[ i ] );
6881			}
6882		}
6883
6884		// Copy the events from the original to the clone
6885		if ( dataAndEvents ) {
6886			if ( deepDataAndEvents ) {
6887				srcElements = srcElements || getAll( elem );
6888				destElements = destElements || getAll( clone );
6889
6890				for ( i = 0, l = srcElements.length; i < l; i++ ) {
6891					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6892				}
6893			} else {
6894				cloneCopyEvent( elem, clone );
6895			}
6896		}
6897
6898		// Preserve script evaluation history
6899		destElements = getAll( clone, "script" );
6900		if ( destElements.length > 0 ) {
6901			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6902		}
6903
6904		// Return the cloned set
6905		return clone;
6906	},
6907
6908	cleanData: function( elems ) {
6909		var data, elem, type,
6910			special = jQuery.event.special,
6911			i = 0;
6912
6913		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6914			if ( acceptData( elem ) ) {
6915				if ( ( data = elem[ dataPriv.expando ] ) ) {
6916					if ( data.events ) {
6917						for ( type in data.events ) {
6918							if ( special[ type ] ) {
6919								jQuery.event.remove( elem, type );
6920
6921							// This is a shortcut to avoid jQuery.event.remove's overhead
6922							} else {
6923								jQuery.removeEvent( elem, type, data.handle );
6924							}
6925						}
6926					}
6927
6928					// Support: Chrome <=35 - 45+
6929					// Assign undefined instead of using delete, see Data#remove
6930					elem[ dataPriv.expando ] = undefined;
6931				}
6932				if ( elem[ dataUser.expando ] ) {
6933
6934					// Support: Chrome <=35 - 45+
6935					// Assign undefined instead of using delete, see Data#remove
6936					elem[ dataUser.expando ] = undefined;
6937				}
6938			}
6939		}
6940	}
6941} );
6942
6943jQuery.fn.extend( {
6944	detach: function( selector ) {
6945		return remove( this, selector, true );
6946	},
6947
6948	remove: function( selector ) {
6949		return remove( this, selector );
6950	},
6951
6952	text: function( value ) {
6953		return access( this, function( value ) {
6954			return value === undefined ?
6955				jQuery.text( this ) :
6956				this.empty().each( function() {
6957					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6958						this.textContent = value;
6959					}
6960				} );
6961		}, null, value, arguments.length );
6962	},
6963
6964	append: function() {
6965		return domManip( this, arguments, function( elem ) {
6966			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6967				var target = manipulationTarget( this, elem );
6968				target.appendChild( elem );
6969			}
6970		} );
6971	},
6972
6973	prepend: function() {
6974		return domManip( this, arguments, function( elem ) {
6975			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6976				var target = manipulationTarget( this, elem );
6977				target.insertBefore( elem, target.firstChild );
6978			}
6979		} );
6980	},
6981
6982	before: function() {
6983		return domManip( this, arguments, function( elem ) {
6984			if ( this.parentNode ) {
6985				this.parentNode.insertBefore( elem, this );
6986			}
6987		} );
6988	},
6989
6990	after: function() {
6991		return domManip( this, arguments, function( elem ) {
6992			if ( this.parentNode ) {
6993				this.parentNode.insertBefore( elem, this.nextSibling );
6994			}
6995		} );
6996	},
6997
6998	empty: function() {
6999		var elem,
7000			i = 0;
7001
7002		for ( ; ( elem = this[ i ] ) != null; i++ ) {
7003			if ( elem.nodeType === 1 ) {
7004
7005				// Prevent memory leaks
7006				jQuery.cleanData( getAll( elem, false ) );
7007
7008				// Remove any remaining nodes
7009				elem.textContent = "";
7010			}
7011		}
7012
7013		return this;
7014	},
7015
7016	clone: function( dataAndEvents, deepDataAndEvents ) {
7017		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
7018		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
7019
7020		return this.map( function() {
7021			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
7022		} );
7023	},
7024
7025	html: function( value ) {
7026		return access( this, function( value ) {
7027			var elem = this[ 0 ] || {},
7028				i = 0,
7029				l = this.length;
7030
7031			if ( value === undefined && elem.nodeType === 1 ) {
7032				return elem.innerHTML;
7033			}
7034
7035			// See if we can take a shortcut and just use innerHTML
7036			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
7037				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
7038
7039				value = jQuery.htmlPrefilter( value );
7040
7041				try {
7042					for ( ; i < l; i++ ) {
7043						elem = this[ i ] || {};
7044
7045						// Remove element nodes and prevent memory leaks
7046						if ( elem.nodeType === 1 ) {
7047							jQuery.cleanData( getAll( elem, false ) );
7048							elem.innerHTML = value;
7049						}
7050					}
7051
7052					elem = 0;
7053
7054				// If using innerHTML throws an exception, use the fallback method
7055				} catch ( e ) {}
7056			}
7057
7058			if ( elem ) {
7059				this.empty().append( value );
7060			}
7061		}, null, value, arguments.length );
7062	},
7063
7064	replaceWith: function() {
7065		var ignored = [];
7066
7067		// Make the changes, replacing each non-ignored context element with the new content
7068		return domManip( this, arguments, function( elem ) {
7069			var parent = this.parentNode;
7070
7071			if ( jQuery.inArray( this, ignored ) < 0 ) {
7072				jQuery.cleanData( getAll( this ) );
7073				if ( parent ) {
7074					parent.replaceChild( elem, this );
7075				}
7076			}
7077
7078		// Force callback invocation
7079		}, ignored );
7080	}
7081} );
7082
7083jQuery.each( {
7084	appendTo: "append",
7085	prependTo: "prepend",
7086	insertBefore: "before",
7087	insertAfter: "after",
7088	replaceAll: "replaceWith"
7089}, function( name, original ) {
7090	jQuery.fn[ name ] = function( selector ) {
7091		var elems,
7092			ret = [],
7093			insert = jQuery( selector ),
7094			last = insert.length - 1,
7095			i = 0;
7096
7097		for ( ; i <= last; i++ ) {
7098			elems = i === last ? this : this.clone( true );
7099			jQuery( insert[ i ] )[ original ]( elems );
7100
7101			// Support: Android <=4.0 only, PhantomJS 1 only
7102			// .get() because push.apply(_, arraylike) throws on ancient WebKit
7103			push.apply( ret, elems.get() );
7104		}
7105
7106		return this.pushStack( ret );
7107	};
7108} );
7109var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
7110
7111var rcustomProp = /^--/;
7112
7113
7114var getStyles = function( elem ) {
7115
7116		// Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
7117		// IE throws on elements created in popups
7118		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
7119		var view = elem.ownerDocument.defaultView;
7120
7121		if ( !view || !view.opener ) {
7122			view = window;
7123		}
7124
7125		return view.getComputedStyle( elem );
7126	};
7127
7128var swap = function( elem, options, callback ) {
7129	var ret, name,
7130		old = {};
7131
7132	// Remember the old values, and insert the new ones
7133	for ( name in options ) {
7134		old[ name ] = elem.style[ name ];
7135		elem.style[ name ] = options[ name ];
7136	}
7137
7138	ret = callback.call( elem );
7139
7140	// Revert the old values
7141	for ( name in options ) {
7142		elem.style[ name ] = old[ name ];
7143	}
7144
7145	return ret;
7146};
7147
7148
7149var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
7150
7151
7152
7153( function() {
7154
7155	// Executing both pixelPosition & boxSizingReliable tests require only one layout
7156	// so they're executed at the same time to save the second computation.
7157	function computeStyleTests() {
7158
7159		// This is a singleton, we need to execute it only once
7160		if ( !div ) {
7161			return;
7162		}
7163
7164		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
7165			"margin-top:1px;padding:0;border:0";
7166		div.style.cssText =
7167			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
7168			"margin:auto;border:1px;padding:1px;" +
7169			"width:60%;top:1%";
7170		documentElement.appendChild( container ).appendChild( div );
7171
7172		var divStyle = window.getComputedStyle( div );
7173		pixelPositionVal = divStyle.top !== "1%";
7174
7175		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
7176		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
7177
7178		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
7179		// Some styles come back with percentage values, even though they shouldn't
7180		div.style.right = "60%";
7181		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
7182
7183		// Support: IE 9 - 11 only
7184		// Detect misreporting of content dimensions for box-sizing:border-box elements
7185		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
7186
7187		// Support: IE 9 only
7188		// Detect overflow:scroll screwiness (gh-3699)
7189		// Support: Chrome <=64
7190		// Don't get tricked when zoom affects offsetWidth (gh-4029)
7191		div.style.position = "absolute";
7192		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
7193
7194		documentElement.removeChild( container );
7195
7196		// Nullify the div so it wouldn't be stored in the memory and
7197		// it will also be a sign that checks already performed
7198		div = null;
7199	}
7200
7201	function roundPixelMeasures( measure ) {
7202		return Math.round( parseFloat( measure ) );
7203	}
7204
7205	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
7206		reliableTrDimensionsVal, reliableMarginLeftVal,
7207		container = document.createElement( "div" ),
7208		div = document.createElement( "div" );
7209
7210	// Finish early in limited (non-browser) environments
7211	if ( !div.style ) {
7212		return;
7213	}
7214
7215	// Support: IE <=9 - 11 only
7216	// Style of cloned element affects source element cloned (trac-8908)
7217	div.style.backgroundClip = "content-box";
7218	div.cloneNode( true ).style.backgroundClip = "";
7219	support.clearCloneStyle = div.style.backgroundClip === "content-box";
7220
7221	jQuery.extend( support, {
7222		boxSizingReliable: function() {
7223			computeStyleTests();
7224			return boxSizingReliableVal;
7225		},
7226		pixelBoxStyles: function() {
7227			computeStyleTests();
7228			return pixelBoxStylesVal;
7229		},
7230		pixelPosition: function() {
7231			computeStyleTests();
7232			return pixelPositionVal;
7233		},
7234		reliableMarginLeft: function() {
7235			computeStyleTests();
7236			return reliableMarginLeftVal;
7237		},
7238		scrollboxSize: function() {
7239			computeStyleTests();
7240			return scrollboxSizeVal;
7241		},
7242
7243		// Support: IE 9 - 11+, Edge 15 - 18+
7244		// IE/Edge misreport `getComputedStyle` of table rows with width/height
7245		// set in CSS while `offset*` properties report correct values.
7246		// Behavior in IE 9 is more subtle than in newer versions & it passes
7247		// some versions of this test; make sure not to make it pass there!
7248		//
7249		// Support: Firefox 70+
7250		// Only Firefox includes border widths
7251		// in computed dimensions. (gh-4529)
7252		reliableTrDimensions: function() {
7253			var table, tr, trChild, trStyle;
7254			if ( reliableTrDimensionsVal == null ) {
7255				table = document.createElement( "table" );
7256				tr = document.createElement( "tr" );
7257				trChild = document.createElement( "div" );
7258
7259				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
7260				tr.style.cssText = "box-sizing:content-box;border:1px solid";
7261
7262				// Support: Chrome 86+
7263				// Height set through cssText does not get applied.
7264				// Computed height then comes back as 0.
7265				tr.style.height = "1px";
7266				trChild.style.height = "9px";
7267
7268				// Support: Android 8 Chrome 86+
7269				// In our bodyBackground.html iframe,
7270				// display for all div elements is set to "inline",
7271				// which causes a problem only in Android 8 Chrome 86.
7272				// Ensuring the div is `display: block`
7273				// gets around this issue.
7274				trChild.style.display = "block";
7275
7276				documentElement
7277					.appendChild( table )
7278					.appendChild( tr )
7279					.appendChild( trChild );
7280
7281				trStyle = window.getComputedStyle( tr );
7282				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
7283					parseInt( trStyle.borderTopWidth, 10 ) +
7284					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
7285
7286				documentElement.removeChild( table );
7287			}
7288			return reliableTrDimensionsVal;
7289		}
7290	} );
7291} )();
7292
7293
7294function curCSS( elem, name, computed ) {
7295	var width, minWidth, maxWidth, ret,
7296		isCustomProp = rcustomProp.test( name ),
7297
7298		// Support: Firefox 51+
7299		// Retrieving style before computed somehow
7300		// fixes an issue with getting wrong values
7301		// on detached elements
7302		style = elem.style;
7303
7304	computed = computed || getStyles( elem );
7305
7306	// getPropertyValue is needed for:
7307	//   .css('filter') (IE 9 only, trac-12537)
7308	//   .css('--customProperty) (gh-3144)
7309	if ( computed ) {
7310
7311		// Support: IE <=9 - 11+
7312		// IE only supports `"float"` in `getPropertyValue`; in computed styles
7313		// it's only available as `"cssFloat"`. We no longer modify properties
7314		// sent to `.css()` apart from camelCasing, so we need to check both.
7315		// Normally, this would create difference in behavior: if
7316		// `getPropertyValue` returns an empty string, the value returned
7317		// by `.css()` would be `undefined`. This is usually the case for
7318		// disconnected elements. However, in IE even disconnected elements
7319		// with no styles return `"none"` for `getPropertyValue( "float" )`
7320		ret = computed.getPropertyValue( name ) || computed[ name ];
7321
7322		if ( isCustomProp && ret ) {
7323
7324			// Support: Firefox 105+, Chrome <=105+
7325			// Spec requires trimming whitespace for custom properties (gh-4926).
7326			// Firefox only trims leading whitespace. Chrome just collapses
7327			// both leading & trailing whitespace to a single space.
7328			//
7329			// Fall back to `undefined` if empty string returned.
7330			// This collapses a missing definition with property defined
7331			// and set to an empty string but there's no standard API
7332			// allowing us to differentiate them without a performance penalty
7333			// and returning `undefined` aligns with older jQuery.
7334			//
7335			// rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED
7336			// as whitespace while CSS does not, but this is not a problem
7337			// because CSS preprocessing replaces them with U+000A LINE FEED
7338			// (which *is* CSS whitespace)
7339			// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
7340			ret = ret.replace( rtrimCSS, "$1" ) || undefined;
7341		}
7342
7343		if ( ret === "" && !isAttached( elem ) ) {
7344			ret = jQuery.style( elem, name );
7345		}
7346
7347		// A tribute to the "awesome hack by Dean Edwards"
7348		// Android Browser returns percentage for some values,
7349		// but width seems to be reliably pixels.
7350		// This is against the CSSOM draft spec:
7351		// https://drafts.csswg.org/cssom/#resolved-values
7352		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
7353
7354			// Remember the original values
7355			width = style.width;
7356			minWidth = style.minWidth;
7357			maxWidth = style.maxWidth;
7358
7359			// Put in the new values to get a computed value out
7360			style.minWidth = style.maxWidth = style.width = ret;
7361			ret = computed.width;
7362
7363			// Revert the changed values
7364			style.width = width;
7365			style.minWidth = minWidth;
7366			style.maxWidth = maxWidth;
7367		}
7368	}
7369
7370	return ret !== undefined ?
7371
7372		// Support: IE <=9 - 11 only
7373		// IE returns zIndex value as an integer.
7374		ret + "" :
7375		ret;
7376}
7377
7378
7379function addGetHookIf( conditionFn, hookFn ) {
7380
7381	// Define the hook, we'll check on the first run if it's really needed.
7382	return {
7383		get: function() {
7384			if ( conditionFn() ) {
7385
7386				// Hook not needed (or it's not possible to use it due
7387				// to missing dependency), remove it.
7388				delete this.get;
7389				return;
7390			}
7391
7392			// Hook needed; redefine it so that the support test is not executed again.
7393			return ( this.get = hookFn ).apply( this, arguments );
7394		}
7395	};
7396}
7397
7398
7399var cssPrefixes = [ "Webkit", "Moz", "ms" ],
7400	emptyStyle = document.createElement( "div" ).style,
7401	vendorProps = {};
7402
7403// Return a vendor-prefixed property or undefined
7404function vendorPropName( name ) {
7405
7406	// Check for vendor prefixed names
7407	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
7408		i = cssPrefixes.length;
7409
7410	while ( i-- ) {
7411		name = cssPrefixes[ i ] + capName;
7412		if ( name in emptyStyle ) {
7413			return name;
7414		}
7415	}
7416}
7417
7418// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
7419function finalPropName( name ) {
7420	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
7421
7422	if ( final ) {
7423		return final;
7424	}
7425	if ( name in emptyStyle ) {
7426		return name;
7427	}
7428	return vendorProps[ name ] = vendorPropName( name ) || name;
7429}
7430
7431
7432var
7433
7434	// Swappable if display is none or starts with table
7435	// except "table", "table-cell", or "table-caption"
7436	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
7437	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
7438	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
7439	cssNormalTransform = {
7440		letterSpacing: "0",
7441		fontWeight: "400"
7442	};
7443
7444function setPositiveNumber( _elem, value, subtract ) {
7445
7446	// Any relative (+/-) values have already been
7447	// normalized at this point
7448	var matches = rcssNum.exec( value );
7449	return matches ?
7450
7451		// Guard against undefined "subtract", e.g., when used as in cssHooks
7452		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
7453		value;
7454}
7455
7456function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
7457	var i = dimension === "width" ? 1 : 0,
7458		extra = 0,
7459		delta = 0,
7460		marginDelta = 0;
7461
7462	// Adjustment may not be necessary
7463	if ( box === ( isBorderBox ? "border" : "content" ) ) {
7464		return 0;
7465	}
7466
7467	for ( ; i < 4; i += 2 ) {
7468
7469		// Both box models exclude margin
7470		// Count margin delta separately to only add it after scroll gutter adjustment.
7471		// This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
7472		if ( box === "margin" ) {
7473			marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
7474		}
7475
7476		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
7477		if ( !isBorderBox ) {
7478
7479			// Add padding
7480			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
7481
7482			// For "border" or "margin", add border
7483			if ( box !== "padding" ) {
7484				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7485
7486			// But still keep track of it otherwise
7487			} else {
7488				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7489			}
7490
7491		// If we get here with a border-box (content + padding + border), we're seeking "content" or
7492		// "padding" or "margin"
7493		} else {
7494
7495			// For "content", subtract padding
7496			if ( box === "content" ) {
7497				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
7498			}
7499
7500			// For "content" or "padding", subtract border
7501			if ( box !== "margin" ) {
7502				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7503			}
7504		}
7505	}
7506
7507	// Account for positive content-box scroll gutter when requested by providing computedVal
7508	if ( !isBorderBox && computedVal >= 0 ) {
7509
7510		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
7511		// Assuming integer scroll gutter, subtract the rest and round down
7512		delta += Math.max( 0, Math.ceil(
7513			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7514			computedVal -
7515			delta -
7516			extra -
7517			0.5
7518
7519		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
7520		// Use an explicit zero to avoid NaN (gh-3964)
7521		) ) || 0;
7522	}
7523
7524	return delta + marginDelta;
7525}
7526
7527function getWidthOrHeight( elem, dimension, extra ) {
7528
7529	// Start with computed style
7530	var styles = getStyles( elem ),
7531
7532		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
7533		// Fake content-box until we know it's needed to know the true value.
7534		boxSizingNeeded = !support.boxSizingReliable() || extra,
7535		isBorderBox = boxSizingNeeded &&
7536			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7537		valueIsBorderBox = isBorderBox,
7538
7539		val = curCSS( elem, dimension, styles ),
7540		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
7541
7542	// Support: Firefox <=54
7543	// Return a confounding non-pixel value or feign ignorance, as appropriate.
7544	if ( rnumnonpx.test( val ) ) {
7545		if ( !extra ) {
7546			return val;
7547		}
7548		val = "auto";
7549	}
7550
7551
7552	// Support: IE 9 - 11 only
7553	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
7554	// In those cases, the computed value can be trusted to be border-box.
7555	if ( ( !support.boxSizingReliable() && isBorderBox ||
7556
7557		// Support: IE 10 - 11+, Edge 15 - 18+
7558		// IE/Edge misreport `getComputedStyle` of table rows with width/height
7559		// set in CSS while `offset*` properties report correct values.
7560		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
7561		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
7562
7563		// Fall back to offsetWidth/offsetHeight when value is "auto"
7564		// This happens for inline elements with no explicit setting (gh-3571)
7565		val === "auto" ||
7566
7567		// Support: Android <=4.1 - 4.3 only
7568		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
7569		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
7570
7571		// Make sure the element is visible & connected
7572		elem.getClientRects().length ) {
7573
7574		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
7575
7576		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
7577		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
7578		// retrieved value as a content box dimension.
7579		valueIsBorderBox = offsetProp in elem;
7580		if ( valueIsBorderBox ) {
7581			val = elem[ offsetProp ];
7582		}
7583	}
7584
7585	// Normalize "" and auto
7586	val = parseFloat( val ) || 0;
7587
7588	// Adjust for the element's box model
7589	return ( val +
7590		boxModelAdjustment(
7591			elem,
7592			dimension,
7593			extra || ( isBorderBox ? "border" : "content" ),
7594			valueIsBorderBox,
7595			styles,
7596
7597			// Provide the current computed size to request scroll gutter calculation (gh-3589)
7598			val
7599		)
7600	) + "px";
7601}
7602
7603jQuery.extend( {
7604
7605	// Add in style property hooks for overriding the default
7606	// behavior of getting and setting a style property
7607	cssHooks: {
7608		opacity: {
7609			get: function( elem, computed ) {
7610				if ( computed ) {
7611
7612					// We should always get a number back from opacity
7613					var ret = curCSS( elem, "opacity" );
7614					return ret === "" ? "1" : ret;
7615				}
7616			}
7617		}
7618	},
7619
7620	// Don't automatically add "px" to these possibly-unitless properties
7621	cssNumber: {
7622		animationIterationCount: true,
7623		aspectRatio: true,
7624		borderImageSlice: true,
7625		columnCount: true,
7626		flexGrow: true,
7627		flexShrink: true,
7628		fontWeight: true,
7629		gridArea: true,
7630		gridColumn: true,
7631		gridColumnEnd: true,
7632		gridColumnStart: true,
7633		gridRow: true,
7634		gridRowEnd: true,
7635		gridRowStart: true,
7636		lineHeight: true,
7637		opacity: true,
7638		order: true,
7639		orphans: true,
7640		scale: true,
7641		widows: true,
7642		zIndex: true,
7643		zoom: true,
7644
7645		// SVG-related
7646		fillOpacity: true,
7647		floodOpacity: true,
7648		stopOpacity: true,
7649		strokeMiterlimit: true,
7650		strokeOpacity: true
7651	},
7652
7653	// Add in properties whose names you wish to fix before
7654	// setting or getting the value
7655	cssProps: {},
7656
7657	// Get and set the style property on a DOM Node
7658	style: function( elem, name, value, extra ) {
7659
7660		// Don't set styles on text and comment nodes
7661		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7662			return;
7663		}
7664
7665		// Make sure that we're working with the right name
7666		var ret, type, hooks,
7667			origName = camelCase( name ),
7668			isCustomProp = rcustomProp.test( name ),
7669			style = elem.style;
7670
7671		// Make sure that we're working with the right name. We don't
7672		// want to query the value if it is a CSS custom property
7673		// since they are user-defined.
7674		if ( !isCustomProp ) {
7675			name = finalPropName( origName );
7676		}
7677
7678		// Gets hook for the prefixed version, then unprefixed version
7679		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7680
7681		// Check if we're setting a value
7682		if ( value !== undefined ) {
7683			type = typeof value;
7684
7685			// Convert "+=" or "-=" to relative numbers (trac-7345)
7686			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7687				value = adjustCSS( elem, name, ret );
7688
7689				// Fixes bug trac-9237
7690				type = "number";
7691			}
7692
7693			// Make sure that null and NaN values aren't set (trac-7116)
7694			if ( value == null || value !== value ) {
7695				return;
7696			}
7697
7698			// If a number was passed in, add the unit (except for certain CSS properties)
7699			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
7700			// "px" to a few hardcoded values.
7701			if ( type === "number" && !isCustomProp ) {
7702				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7703			}
7704
7705			// background-* props affect original clone's values
7706			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7707				style[ name ] = "inherit";
7708			}
7709
7710			// If a hook was provided, use that value, otherwise just set the specified value
7711			if ( !hooks || !( "set" in hooks ) ||
7712				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7713
7714				if ( isCustomProp ) {
7715					style.setProperty( name, value );
7716				} else {
7717					style[ name ] = value;
7718				}
7719			}
7720
7721		} else {
7722
7723			// If a hook was provided get the non-computed value from there
7724			if ( hooks && "get" in hooks &&
7725				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7726
7727				return ret;
7728			}
7729
7730			// Otherwise just get the value from the style object
7731			return style[ name ];
7732		}
7733	},
7734
7735	css: function( elem, name, extra, styles ) {
7736		var val, num, hooks,
7737			origName = camelCase( name ),
7738			isCustomProp = rcustomProp.test( name );
7739
7740		// Make sure that we're working with the right name. We don't
7741		// want to modify the value if it is a CSS custom property
7742		// since they are user-defined.
7743		if ( !isCustomProp ) {
7744			name = finalPropName( origName );
7745		}
7746
7747		// Try prefixed name followed by the unprefixed name
7748		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7749
7750		// If a hook was provided get the computed value from there
7751		if ( hooks && "get" in hooks ) {
7752			val = hooks.get( elem, true, extra );
7753		}
7754
7755		// Otherwise, if a way to get the computed value exists, use that
7756		if ( val === undefined ) {
7757			val = curCSS( elem, name, styles );
7758		}
7759
7760		// Convert "normal" to computed value
7761		if ( val === "normal" && name in cssNormalTransform ) {
7762			val = cssNormalTransform[ name ];
7763		}
7764
7765		// Make numeric if forced or a qualifier was provided and val looks numeric
7766		if ( extra === "" || extra ) {
7767			num = parseFloat( val );
7768			return extra === true || isFinite( num ) ? num || 0 : val;
7769		}
7770
7771		return val;
7772	}
7773} );
7774
7775jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7776	jQuery.cssHooks[ dimension ] = {
7777		get: function( elem, computed, extra ) {
7778			if ( computed ) {
7779
7780				// Certain elements can have dimension info if we invisibly show them
7781				// but it must have a current display style that would benefit
7782				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7783
7784					// Support: Safari 8+
7785					// Table columns in Safari have non-zero offsetWidth & zero
7786					// getBoundingClientRect().width unless display is changed.
7787					// Support: IE <=11 only
7788					// Running getBoundingClientRect on a disconnected node
7789					// in IE throws an error.
7790					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7791					swap( elem, cssShow, function() {
7792						return getWidthOrHeight( elem, dimension, extra );
7793					} ) :
7794					getWidthOrHeight( elem, dimension, extra );
7795			}
7796		},
7797
7798		set: function( elem, value, extra ) {
7799			var matches,
7800				styles = getStyles( elem ),
7801
7802				// Only read styles.position if the test has a chance to fail
7803				// to avoid forcing a reflow.
7804				scrollboxSizeBuggy = !support.scrollboxSize() &&
7805					styles.position === "absolute",
7806
7807				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7808				boxSizingNeeded = scrollboxSizeBuggy || extra,
7809				isBorderBox = boxSizingNeeded &&
7810					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7811				subtract = extra ?
7812					boxModelAdjustment(
7813						elem,
7814						dimension,
7815						extra,
7816						isBorderBox,
7817						styles
7818					) :
7819					0;
7820
7821			// Account for unreliable border-box dimensions by comparing offset* to computed and
7822			// faking a content-box to get border and padding (gh-3699)
7823			if ( isBorderBox && scrollboxSizeBuggy ) {
7824				subtract -= Math.ceil(
7825					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7826					parseFloat( styles[ dimension ] ) -
7827					boxModelAdjustment( elem, dimension, "border", false, styles ) -
7828					0.5
7829				);
7830			}
7831
7832			// Convert to pixels if value adjustment is needed
7833			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7834				( matches[ 3 ] || "px" ) !== "px" ) {
7835
7836				elem.style[ dimension ] = value;
7837				value = jQuery.css( elem, dimension );
7838			}
7839
7840			return setPositiveNumber( elem, value, subtract );
7841		}
7842	};
7843} );
7844
7845jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7846	function( elem, computed ) {
7847		if ( computed ) {
7848			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7849				elem.getBoundingClientRect().left -
7850					swap( elem, { marginLeft: 0 }, function() {
7851						return elem.getBoundingClientRect().left;
7852					} )
7853			) + "px";
7854		}
7855	}
7856);
7857
7858// These hooks are used by animate to expand properties
7859jQuery.each( {
7860	margin: "",
7861	padding: "",
7862	border: "Width"
7863}, function( prefix, suffix ) {
7864	jQuery.cssHooks[ prefix + suffix ] = {
7865		expand: function( value ) {
7866			var i = 0,
7867				expanded = {},
7868
7869				// Assumes a single number if not a string
7870				parts = typeof value === "string" ? value.split( " " ) : [ value ];
7871
7872			for ( ; i < 4; i++ ) {
7873				expanded[ prefix + cssExpand[ i ] + suffix ] =
7874					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7875			}
7876
7877			return expanded;
7878		}
7879	};
7880
7881	if ( prefix !== "margin" ) {
7882		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7883	}
7884} );
7885
7886jQuery.fn.extend( {
7887	css: function( name, value ) {
7888		return access( this, function( elem, name, value ) {
7889			var styles, len,
7890				map = {},
7891				i = 0;
7892
7893			if ( Array.isArray( name ) ) {
7894				styles = getStyles( elem );
7895				len = name.length;
7896
7897				for ( ; i < len; i++ ) {
7898					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7899				}
7900
7901				return map;
7902			}
7903
7904			return value !== undefined ?
7905				jQuery.style( elem, name, value ) :
7906				jQuery.css( elem, name );
7907		}, name, value, arguments.length > 1 );
7908	}
7909} );
7910
7911
7912function Tween( elem, options, prop, end, easing ) {
7913	return new Tween.prototype.init( elem, options, prop, end, easing );
7914}
7915jQuery.Tween = Tween;
7916
7917Tween.prototype = {
7918	constructor: Tween,
7919	init: function( elem, options, prop, end, easing, unit ) {
7920		this.elem = elem;
7921		this.prop = prop;
7922		this.easing = easing || jQuery.easing._default;
7923		this.options = options;
7924		this.start = this.now = this.cur();
7925		this.end = end;
7926		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7927	},
7928	cur: function() {
7929		var hooks = Tween.propHooks[ this.prop ];
7930
7931		return hooks && hooks.get ?
7932			hooks.get( this ) :
7933			Tween.propHooks._default.get( this );
7934	},
7935	run: function( percent ) {
7936		var eased,
7937			hooks = Tween.propHooks[ this.prop ];
7938
7939		if ( this.options.duration ) {
7940			this.pos = eased = jQuery.easing[ this.easing ](
7941				percent, this.options.duration * percent, 0, 1, this.options.duration
7942			);
7943		} else {
7944			this.pos = eased = percent;
7945		}
7946		this.now = ( this.end - this.start ) * eased + this.start;
7947
7948		if ( this.options.step ) {
7949			this.options.step.call( this.elem, this.now, this );
7950		}
7951
7952		if ( hooks && hooks.set ) {
7953			hooks.set( this );
7954		} else {
7955			Tween.propHooks._default.set( this );
7956		}
7957		return this;
7958	}
7959};
7960
7961Tween.prototype.init.prototype = Tween.prototype;
7962
7963Tween.propHooks = {
7964	_default: {
7965		get: function( tween ) {
7966			var result;
7967
7968			// Use a property on the element directly when it is not a DOM element,
7969			// or when there is no matching style property that exists.
7970			if ( tween.elem.nodeType !== 1 ||
7971				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7972				return tween.elem[ tween.prop ];
7973			}
7974
7975			// Passing an empty string as a 3rd parameter to .css will automatically
7976			// attempt a parseFloat and fallback to a string if the parse fails.
7977			// Simple values such as "10px" are parsed to Float;
7978			// complex values such as "rotate(1rad)" are returned as-is.
7979			result = jQuery.css( tween.elem, tween.prop, "" );
7980
7981			// Empty strings, null, undefined and "auto" are converted to 0.
7982			return !result || result === "auto" ? 0 : result;
7983		},
7984		set: function( tween ) {
7985
7986			// Use step hook for back compat.
7987			// Use cssHook if its there.
7988			// Use .style if available and use plain properties where available.
7989			if ( jQuery.fx.step[ tween.prop ] ) {
7990				jQuery.fx.step[ tween.prop ]( tween );
7991			} else if ( tween.elem.nodeType === 1 && (
7992				jQuery.cssHooks[ tween.prop ] ||
7993					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7994				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7995			} else {
7996				tween.elem[ tween.prop ] = tween.now;
7997			}
7998		}
7999	}
8000};
8001
8002// Support: IE <=9 only
8003// Panic based approach to setting things on disconnected nodes
8004Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
8005	set: function( tween ) {
8006		if ( tween.elem.nodeType && tween.elem.parentNode ) {
8007			tween.elem[ tween.prop ] = tween.now;
8008		}
8009	}
8010};
8011
8012jQuery.easing = {
8013	linear: function( p ) {
8014		return p;
8015	},
8016	swing: function( p ) {
8017		return 0.5 - Math.cos( p * Math.PI ) / 2;
8018	},
8019	_default: "swing"
8020};
8021
8022jQuery.fx = Tween.prototype.init;
8023
8024// Back compat <1.8 extension point
8025jQuery.fx.step = {};
8026
8027
8028
8029
8030var
8031	fxNow, inProgress,
8032	rfxtypes = /^(?:toggle|show|hide)$/,
8033	rrun = /queueHooks$/;
8034
8035function schedule() {
8036	if ( inProgress ) {
8037		if ( document.hidden === false && window.requestAnimationFrame ) {
8038			window.requestAnimationFrame( schedule );
8039		} else {
8040			window.setTimeout( schedule, jQuery.fx.interval );
8041		}
8042
8043		jQuery.fx.tick();
8044	}
8045}
8046
8047// Animations created synchronously will run synchronously
8048function createFxNow() {
8049	window.setTimeout( function() {
8050		fxNow = undefined;
8051	} );
8052	return ( fxNow = Date.now() );
8053}
8054
8055// Generate parameters to create a standard animation
8056function genFx( type, includeWidth ) {
8057	var which,
8058		i = 0,
8059		attrs = { height: type };
8060
8061	// If we include width, step value is 1 to do all cssExpand values,
8062	// otherwise step value is 2 to skip over Left and Right
8063	includeWidth = includeWidth ? 1 : 0;
8064	for ( ; i < 4; i += 2 - includeWidth ) {
8065		which = cssExpand[ i ];
8066		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
8067	}
8068
8069	if ( includeWidth ) {
8070		attrs.opacity = attrs.width = type;
8071	}
8072
8073	return attrs;
8074}
8075
8076function createTween( value, prop, animation ) {
8077	var tween,
8078		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
8079		index = 0,
8080		length = collection.length;
8081	for ( ; index < length; index++ ) {
8082		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
8083
8084			// We're done with this property
8085			return tween;
8086		}
8087	}
8088}
8089
8090function defaultPrefilter( elem, props, opts ) {
8091	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
8092		isBox = "width" in props || "height" in props,
8093		anim = this,
8094		orig = {},
8095		style = elem.style,
8096		hidden = elem.nodeType && isHiddenWithinTree( elem ),
8097		dataShow = dataPriv.get( elem, "fxshow" );
8098
8099	// Queue-skipping animations hijack the fx hooks
8100	if ( !opts.queue ) {
8101		hooks = jQuery._queueHooks( elem, "fx" );
8102		if ( hooks.unqueued == null ) {
8103			hooks.unqueued = 0;
8104			oldfire = hooks.empty.fire;
8105			hooks.empty.fire = function() {
8106				if ( !hooks.unqueued ) {
8107					oldfire();
8108				}
8109			};
8110		}
8111		hooks.unqueued++;
8112
8113		anim.always( function() {
8114
8115			// Ensure the complete handler is called before this completes
8116			anim.always( function() {
8117				hooks.unqueued--;
8118				if ( !jQuery.queue( elem, "fx" ).length ) {
8119					hooks.empty.fire();
8120				}
8121			} );
8122		} );
8123	}
8124
8125	// Detect show/hide animations
8126	for ( prop in props ) {
8127		value = props[ prop ];
8128		if ( rfxtypes.test( value ) ) {
8129			delete props[ prop ];
8130			toggle = toggle || value === "toggle";
8131			if ( value === ( hidden ? "hide" : "show" ) ) {
8132
8133				// Pretend to be hidden if this is a "show" and
8134				// there is still data from a stopped show/hide
8135				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
8136					hidden = true;
8137
8138				// Ignore all other no-op show/hide data
8139				} else {
8140					continue;
8141				}
8142			}
8143			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
8144		}
8145	}
8146
8147	// Bail out if this is a no-op like .hide().hide()
8148	propTween = !jQuery.isEmptyObject( props );
8149	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
8150		return;
8151	}
8152
8153	// Restrict "overflow" and "display" styles during box animations
8154	if ( isBox && elem.nodeType === 1 ) {
8155
8156		// Support: IE <=9 - 11, Edge 12 - 15
8157		// Record all 3 overflow attributes because IE does not infer the shorthand
8158		// from identically-valued overflowX and overflowY and Edge just mirrors
8159		// the overflowX value there.
8160		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8161
8162		// Identify a display type, preferring old show/hide data over the CSS cascade
8163		restoreDisplay = dataShow && dataShow.display;
8164		if ( restoreDisplay == null ) {
8165			restoreDisplay = dataPriv.get( elem, "display" );
8166		}
8167		display = jQuery.css( elem, "display" );
8168		if ( display === "none" ) {
8169			if ( restoreDisplay ) {
8170				display = restoreDisplay;
8171			} else {
8172
8173				// Get nonempty value(s) by temporarily forcing visibility
8174				showHide( [ elem ], true );
8175				restoreDisplay = elem.style.display || restoreDisplay;
8176				display = jQuery.css( elem, "display" );
8177				showHide( [ elem ] );
8178			}
8179		}
8180
8181		// Animate inline elements as inline-block
8182		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
8183			if ( jQuery.css( elem, "float" ) === "none" ) {
8184
8185				// Restore the original display value at the end of pure show/hide animations
8186				if ( !propTween ) {
8187					anim.done( function() {
8188						style.display = restoreDisplay;
8189					} );
8190					if ( restoreDisplay == null ) {
8191						display = style.display;
8192						restoreDisplay = display === "none" ? "" : display;
8193					}
8194				}
8195				style.display = "inline-block";
8196			}
8197		}
8198	}
8199
8200	if ( opts.overflow ) {
8201		style.overflow = "hidden";
8202		anim.always( function() {
8203			style.overflow = opts.overflow[ 0 ];
8204			style.overflowX = opts.overflow[ 1 ];
8205			style.overflowY = opts.overflow[ 2 ];
8206		} );
8207	}
8208
8209	// Implement show/hide animations
8210	propTween = false;
8211	for ( prop in orig ) {
8212
8213		// General show/hide setup for this element animation
8214		if ( !propTween ) {
8215			if ( dataShow ) {
8216				if ( "hidden" in dataShow ) {
8217					hidden = dataShow.hidden;
8218				}
8219			} else {
8220				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
8221			}
8222
8223			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
8224			if ( toggle ) {
8225				dataShow.hidden = !hidden;
8226			}
8227
8228			// Show elements before animating them
8229			if ( hidden ) {
8230				showHide( [ elem ], true );
8231			}
8232
8233			/* eslint-disable no-loop-func */
8234
8235			anim.done( function() {
8236
8237				/* eslint-enable no-loop-func */
8238
8239				// The final step of a "hide" animation is actually hiding the element
8240				if ( !hidden ) {
8241					showHide( [ elem ] );
8242				}
8243				dataPriv.remove( elem, "fxshow" );
8244				for ( prop in orig ) {
8245					jQuery.style( elem, prop, orig[ prop ] );
8246				}
8247			} );
8248		}
8249
8250		// Per-property setup
8251		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
8252		if ( !( prop in dataShow ) ) {
8253			dataShow[ prop ] = propTween.start;
8254			if ( hidden ) {
8255				propTween.end = propTween.start;
8256				propTween.start = 0;
8257			}
8258		}
8259	}
8260}
8261
8262function propFilter( props, specialEasing ) {
8263	var index, name, easing, value, hooks;
8264
8265	// camelCase, specialEasing and expand cssHook pass
8266	for ( index in props ) {
8267		name = camelCase( index );
8268		easing = specialEasing[ name ];
8269		value = props[ index ];
8270		if ( Array.isArray( value ) ) {
8271			easing = value[ 1 ];
8272			value = props[ index ] = value[ 0 ];
8273		}
8274
8275		if ( index !== name ) {
8276			props[ name ] = value;
8277			delete props[ index ];
8278		}
8279
8280		hooks = jQuery.cssHooks[ name ];
8281		if ( hooks && "expand" in hooks ) {
8282			value = hooks.expand( value );
8283			delete props[ name ];
8284
8285			// Not quite $.extend, this won't overwrite existing keys.
8286			// Reusing 'index' because we have the correct "name"
8287			for ( index in value ) {
8288				if ( !( index in props ) ) {
8289					props[ index ] = value[ index ];
8290					specialEasing[ index ] = easing;
8291				}
8292			}
8293		} else {
8294			specialEasing[ name ] = easing;
8295		}
8296	}
8297}
8298
8299function Animation( elem, properties, options ) {
8300	var result,
8301		stopped,
8302		index = 0,
8303		length = Animation.prefilters.length,
8304		deferred = jQuery.Deferred().always( function() {
8305
8306			// Don't match elem in the :animated selector
8307			delete tick.elem;
8308		} ),
8309		tick = function() {
8310			if ( stopped ) {
8311				return false;
8312			}
8313			var currentTime = fxNow || createFxNow(),
8314				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8315
8316				// Support: Android 2.3 only
8317				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
8318				temp = remaining / animation.duration || 0,
8319				percent = 1 - temp,
8320				index = 0,
8321				length = animation.tweens.length;
8322
8323			for ( ; index < length; index++ ) {
8324				animation.tweens[ index ].run( percent );
8325			}
8326
8327			deferred.notifyWith( elem, [ animation, percent, remaining ] );
8328
8329			// If there's more to do, yield
8330			if ( percent < 1 && length ) {
8331				return remaining;
8332			}
8333
8334			// If this was an empty animation, synthesize a final progress notification
8335			if ( !length ) {
8336				deferred.notifyWith( elem, [ animation, 1, 0 ] );
8337			}
8338
8339			// Resolve the animation and report its conclusion
8340			deferred.resolveWith( elem, [ animation ] );
8341			return false;
8342		},
8343		animation = deferred.promise( {
8344			elem: elem,
8345			props: jQuery.extend( {}, properties ),
8346			opts: jQuery.extend( true, {
8347				specialEasing: {},
8348				easing: jQuery.easing._default
8349			}, options ),
8350			originalProperties: properties,
8351			originalOptions: options,
8352			startTime: fxNow || createFxNow(),
8353			duration: options.duration,
8354			tweens: [],
8355			createTween: function( prop, end ) {
8356				var tween = jQuery.Tween( elem, animation.opts, prop, end,
8357					animation.opts.specialEasing[ prop ] || animation.opts.easing );
8358				animation.tweens.push( tween );
8359				return tween;
8360			},
8361			stop: function( gotoEnd ) {
8362				var index = 0,
8363
8364					// If we are going to the end, we want to run all the tweens
8365					// otherwise we skip this part
8366					length = gotoEnd ? animation.tweens.length : 0;
8367				if ( stopped ) {
8368					return this;
8369				}
8370				stopped = true;
8371				for ( ; index < length; index++ ) {
8372					animation.tweens[ index ].run( 1 );
8373				}
8374
8375				// Resolve when we played the last frame; otherwise, reject
8376				if ( gotoEnd ) {
8377					deferred.notifyWith( elem, [ animation, 1, 0 ] );
8378					deferred.resolveWith( elem, [ animation, gotoEnd ] );
8379				} else {
8380					deferred.rejectWith( elem, [ animation, gotoEnd ] );
8381				}
8382				return this;
8383			}
8384		} ),
8385		props = animation.props;
8386
8387	propFilter( props, animation.opts.specialEasing );
8388
8389	for ( ; index < length; index++ ) {
8390		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
8391		if ( result ) {
8392			if ( isFunction( result.stop ) ) {
8393				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
8394					result.stop.bind( result );
8395			}
8396			return result;
8397		}
8398	}
8399
8400	jQuery.map( props, createTween, animation );
8401
8402	if ( isFunction( animation.opts.start ) ) {
8403		animation.opts.start.call( elem, animation );
8404	}
8405
8406	// Attach callbacks from options
8407	animation
8408		.progress( animation.opts.progress )
8409		.done( animation.opts.done, animation.opts.complete )
8410		.fail( animation.opts.fail )
8411		.always( animation.opts.always );
8412
8413	jQuery.fx.timer(
8414		jQuery.extend( tick, {
8415			elem: elem,
8416			anim: animation,
8417			queue: animation.opts.queue
8418		} )
8419	);
8420
8421	return animation;
8422}
8423
8424jQuery.Animation = jQuery.extend( Animation, {
8425
8426	tweeners: {
8427		"*": [ function( prop, value ) {
8428			var tween = this.createTween( prop, value );
8429			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
8430			return tween;
8431		} ]
8432	},
8433
8434	tweener: function( props, callback ) {
8435		if ( isFunction( props ) ) {
8436			callback = props;
8437			props = [ "*" ];
8438		} else {
8439			props = props.match( rnothtmlwhite );
8440		}
8441
8442		var prop,
8443			index = 0,
8444			length = props.length;
8445
8446		for ( ; index < length; index++ ) {
8447			prop = props[ index ];
8448			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
8449			Animation.tweeners[ prop ].unshift( callback );
8450		}
8451	},
8452
8453	prefilters: [ defaultPrefilter ],
8454
8455	prefilter: function( callback, prepend ) {
8456		if ( prepend ) {
8457			Animation.prefilters.unshift( callback );
8458		} else {
8459			Animation.prefilters.push( callback );
8460		}
8461	}
8462} );
8463
8464jQuery.speed = function( speed, easing, fn ) {
8465	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8466		complete: fn || !fn && easing ||
8467			isFunction( speed ) && speed,
8468		duration: speed,
8469		easing: fn && easing || easing && !isFunction( easing ) && easing
8470	};
8471
8472	// Go to the end state if fx are off
8473	if ( jQuery.fx.off ) {
8474		opt.duration = 0;
8475
8476	} else {
8477		if ( typeof opt.duration !== "number" ) {
8478			if ( opt.duration in jQuery.fx.speeds ) {
8479				opt.duration = jQuery.fx.speeds[ opt.duration ];
8480
8481			} else {
8482				opt.duration = jQuery.fx.speeds._default;
8483			}
8484		}
8485	}
8486
8487	// Normalize opt.queue - true/undefined/null -> "fx"
8488	if ( opt.queue == null || opt.queue === true ) {
8489		opt.queue = "fx";
8490	}
8491
8492	// Queueing
8493	opt.old = opt.complete;
8494
8495	opt.complete = function() {
8496		if ( isFunction( opt.old ) ) {
8497			opt.old.call( this );
8498		}
8499
8500		if ( opt.queue ) {
8501			jQuery.dequeue( this, opt.queue );
8502		}
8503	};
8504
8505	return opt;
8506};
8507
8508jQuery.fn.extend( {
8509	fadeTo: function( speed, to, easing, callback ) {
8510
8511		// Show any hidden elements after setting opacity to 0
8512		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
8513
8514			// Animate to the value specified
8515			.end().animate( { opacity: to }, speed, easing, callback );
8516	},
8517	animate: function( prop, speed, easing, callback ) {
8518		var empty = jQuery.isEmptyObject( prop ),
8519			optall = jQuery.speed( speed, easing, callback ),
8520			doAnimation = function() {
8521
8522				// Operate on a copy of prop so per-property easing won't be lost
8523				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
8524
8525				// Empty animations, or finishing resolves immediately
8526				if ( empty || dataPriv.get( this, "finish" ) ) {
8527					anim.stop( true );
8528				}
8529			};
8530
8531		doAnimation.finish = doAnimation;
8532
8533		return empty || optall.queue === false ?
8534			this.each( doAnimation ) :
8535			this.queue( optall.queue, doAnimation );
8536	},
8537	stop: function( type, clearQueue, gotoEnd ) {
8538		var stopQueue = function( hooks ) {
8539			var stop = hooks.stop;
8540			delete hooks.stop;
8541			stop( gotoEnd );
8542		};
8543
8544		if ( typeof type !== "string" ) {
8545			gotoEnd = clearQueue;
8546			clearQueue = type;
8547			type = undefined;
8548		}
8549		if ( clearQueue ) {
8550			this.queue( type || "fx", [] );
8551		}
8552
8553		return this.each( function() {
8554			var dequeue = true,
8555				index = type != null && type + "queueHooks",
8556				timers = jQuery.timers,
8557				data = dataPriv.get( this );
8558
8559			if ( index ) {
8560				if ( data[ index ] && data[ index ].stop ) {
8561					stopQueue( data[ index ] );
8562				}
8563			} else {
8564				for ( index in data ) {
8565					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
8566						stopQueue( data[ index ] );
8567					}
8568				}
8569			}
8570
8571			for ( index = timers.length; index--; ) {
8572				if ( timers[ index ].elem === this &&
8573					( type == null || timers[ index ].queue === type ) ) {
8574
8575					timers[ index ].anim.stop( gotoEnd );
8576					dequeue = false;
8577					timers.splice( index, 1 );
8578				}
8579			}
8580
8581			// Start the next in the queue if the last step wasn't forced.
8582			// Timers currently will call their complete callbacks, which
8583			// will dequeue but only if they were gotoEnd.
8584			if ( dequeue || !gotoEnd ) {
8585				jQuery.dequeue( this, type );
8586			}
8587		} );
8588	},
8589	finish: function( type ) {
8590		if ( type !== false ) {
8591			type = type || "fx";
8592		}
8593		return this.each( function() {
8594			var index,
8595				data = dataPriv.get( this ),
8596				queue = data[ type + "queue" ],
8597				hooks = data[ type + "queueHooks" ],
8598				timers = jQuery.timers,
8599				length = queue ? queue.length : 0;
8600
8601			// Enable finishing flag on private data
8602			data.finish = true;
8603
8604			// Empty the queue first
8605			jQuery.queue( this, type, [] );
8606
8607			if ( hooks && hooks.stop ) {
8608				hooks.stop.call( this, true );
8609			}
8610
8611			// Look for any active animations, and finish them
8612			for ( index = timers.length; index--; ) {
8613				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8614					timers[ index ].anim.stop( true );
8615					timers.splice( index, 1 );
8616				}
8617			}
8618
8619			// Look for any animations in the old queue and finish them
8620			for ( index = 0; index < length; index++ ) {
8621				if ( queue[ index ] && queue[ index ].finish ) {
8622					queue[ index ].finish.call( this );
8623				}
8624			}
8625
8626			// Turn off finishing flag
8627			delete data.finish;
8628		} );
8629	}
8630} );
8631
8632jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
8633	var cssFn = jQuery.fn[ name ];
8634	jQuery.fn[ name ] = function( speed, easing, callback ) {
8635		return speed == null || typeof speed === "boolean" ?
8636			cssFn.apply( this, arguments ) :
8637			this.animate( genFx( name, true ), speed, easing, callback );
8638	};
8639} );
8640
8641// Generate shortcuts for custom animations
8642jQuery.each( {
8643	slideDown: genFx( "show" ),
8644	slideUp: genFx( "hide" ),
8645	slideToggle: genFx( "toggle" ),
8646	fadeIn: { opacity: "show" },
8647	fadeOut: { opacity: "hide" },
8648	fadeToggle: { opacity: "toggle" }
8649}, function( name, props ) {
8650	jQuery.fn[ name ] = function( speed, easing, callback ) {
8651		return this.animate( props, speed, easing, callback );
8652	};
8653} );
8654
8655jQuery.timers = [];
8656jQuery.fx.tick = function() {
8657	var timer,
8658		i = 0,
8659		timers = jQuery.timers;
8660
8661	fxNow = Date.now();
8662
8663	for ( ; i < timers.length; i++ ) {
8664		timer = timers[ i ];
8665
8666		// Run the timer and safely remove it when done (allowing for external removal)
8667		if ( !timer() && timers[ i ] === timer ) {
8668			timers.splice( i--, 1 );
8669		}
8670	}
8671
8672	if ( !timers.length ) {
8673		jQuery.fx.stop();
8674	}
8675	fxNow = undefined;
8676};
8677
8678jQuery.fx.timer = function( timer ) {
8679	jQuery.timers.push( timer );
8680	jQuery.fx.start();
8681};
8682
8683jQuery.fx.interval = 13;
8684jQuery.fx.start = function() {
8685	if ( inProgress ) {
8686		return;
8687	}
8688
8689	inProgress = true;
8690	schedule();
8691};
8692
8693jQuery.fx.stop = function() {
8694	inProgress = null;
8695};
8696
8697jQuery.fx.speeds = {
8698	slow: 600,
8699	fast: 200,
8700
8701	// Default speed
8702	_default: 400
8703};
8704
8705
8706// Based off of the plugin by Clint Helfers, with permission.
8707jQuery.fn.delay = function( time, type ) {
8708	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8709	type = type || "fx";
8710
8711	return this.queue( type, function( next, hooks ) {
8712		var timeout = window.setTimeout( next, time );
8713		hooks.stop = function() {
8714			window.clearTimeout( timeout );
8715		};
8716	} );
8717};
8718
8719
8720( function() {
8721	var input = document.createElement( "input" ),
8722		select = document.createElement( "select" ),
8723		opt = select.appendChild( document.createElement( "option" ) );
8724
8725	input.type = "checkbox";
8726
8727	// Support: Android <=4.3 only
8728	// Default value for a checkbox should be "on"
8729	support.checkOn = input.value !== "";
8730
8731	// Support: IE <=11 only
8732	// Must access selectedIndex to make default options select
8733	support.optSelected = opt.selected;
8734
8735	// Support: IE <=11 only
8736	// An input loses its value after becoming a radio
8737	input = document.createElement( "input" );
8738	input.value = "t";
8739	input.type = "radio";
8740	support.radioValue = input.value === "t";
8741} )();
8742
8743
8744var boolHook,
8745	attrHandle = jQuery.expr.attrHandle;
8746
8747jQuery.fn.extend( {
8748	attr: function( name, value ) {
8749		return access( this, jQuery.attr, name, value, arguments.length > 1 );
8750	},
8751
8752	removeAttr: function( name ) {
8753		return this.each( function() {
8754			jQuery.removeAttr( this, name );
8755		} );
8756	}
8757} );
8758
8759jQuery.extend( {
8760	attr: function( elem, name, value ) {
8761		var ret, hooks,
8762			nType = elem.nodeType;
8763
8764		// Don't get/set attributes on text, comment and attribute nodes
8765		if ( nType === 3 || nType === 8 || nType === 2 ) {
8766			return;
8767		}
8768
8769		// Fallback to prop when attributes are not supported
8770		if ( typeof elem.getAttribute === "undefined" ) {
8771			return jQuery.prop( elem, name, value );
8772		}
8773
8774		// Attribute hooks are determined by the lowercase version
8775		// Grab necessary hook if one is defined
8776		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8777			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8778				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8779		}
8780
8781		if ( value !== undefined ) {
8782			if ( value === null ) {
8783				jQuery.removeAttr( elem, name );
8784				return;
8785			}
8786
8787			if ( hooks && "set" in hooks &&
8788				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8789				return ret;
8790			}
8791
8792			elem.setAttribute( name, value + "" );
8793			return value;
8794		}
8795
8796		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8797			return ret;
8798		}
8799
8800		ret = jQuery.find.attr( elem, name );
8801
8802		// Non-existent attributes return null, we normalize to undefined
8803		return ret == null ? undefined : ret;
8804	},
8805
8806	attrHooks: {
8807		type: {
8808			set: function( elem, value ) {
8809				if ( !support.radioValue && value === "radio" &&
8810					nodeName( elem, "input" ) ) {
8811					var val = elem.value;
8812					elem.setAttribute( "type", value );
8813					if ( val ) {
8814						elem.value = val;
8815					}
8816					return value;
8817				}
8818			}
8819		}
8820	},
8821
8822	removeAttr: function( elem, value ) {
8823		var name,
8824			i = 0,
8825
8826			// Attribute names can contain non-HTML whitespace characters
8827			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8828			attrNames = value && value.match( rnothtmlwhite );
8829
8830		if ( attrNames && elem.nodeType === 1 ) {
8831			while ( ( name = attrNames[ i++ ] ) ) {
8832				elem.removeAttribute( name );
8833			}
8834		}
8835	}
8836} );
8837
8838// Hooks for boolean attributes
8839boolHook = {
8840	set: function( elem, value, name ) {
8841		if ( value === false ) {
8842
8843			// Remove boolean attributes when set to false
8844			jQuery.removeAttr( elem, name );
8845		} else {
8846			elem.setAttribute( name, name );
8847		}
8848		return name;
8849	}
8850};
8851
8852jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8853	var getter = attrHandle[ name ] || jQuery.find.attr;
8854
8855	attrHandle[ name ] = function( elem, name, isXML ) {
8856		var ret, handle,
8857			lowercaseName = name.toLowerCase();
8858
8859		if ( !isXML ) {
8860
8861			// Avoid an infinite loop by temporarily removing this function from the getter
8862			handle = attrHandle[ lowercaseName ];
8863			attrHandle[ lowercaseName ] = ret;
8864			ret = getter( elem, name, isXML ) != null ?
8865				lowercaseName :
8866				null;
8867			attrHandle[ lowercaseName ] = handle;
8868		}
8869		return ret;
8870	};
8871} );
8872
8873
8874
8875
8876var rfocusable = /^(?:input|select|textarea|button)$/i,
8877	rclickable = /^(?:a|area)$/i;
8878
8879jQuery.fn.extend( {
8880	prop: function( name, value ) {
8881		return access( this, jQuery.prop, name, value, arguments.length > 1 );
8882	},
8883
8884	removeProp: function( name ) {
8885		return this.each( function() {
8886			delete this[ jQuery.propFix[ name ] || name ];
8887		} );
8888	}
8889} );
8890
8891jQuery.extend( {
8892	prop: function( elem, name, value ) {
8893		var ret, hooks,
8894			nType = elem.nodeType;
8895
8896		// Don't get/set properties on text, comment and attribute nodes
8897		if ( nType === 3 || nType === 8 || nType === 2 ) {
8898			return;
8899		}
8900
8901		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8902
8903			// Fix name and attach hooks
8904			name = jQuery.propFix[ name ] || name;
8905			hooks = jQuery.propHooks[ name ];
8906		}
8907
8908		if ( value !== undefined ) {
8909			if ( hooks && "set" in hooks &&
8910				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8911				return ret;
8912			}
8913
8914			return ( elem[ name ] = value );
8915		}
8916
8917		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8918			return ret;
8919		}
8920
8921		return elem[ name ];
8922	},
8923
8924	propHooks: {
8925		tabIndex: {
8926			get: function( elem ) {
8927
8928				// Support: IE <=9 - 11 only
8929				// elem.tabIndex doesn't always return the
8930				// correct value when it hasn't been explicitly set
8931				// Use proper attribute retrieval (trac-12072)
8932				var tabindex = jQuery.find.attr( elem, "tabindex" );
8933
8934				if ( tabindex ) {
8935					return parseInt( tabindex, 10 );
8936				}
8937
8938				if (
8939					rfocusable.test( elem.nodeName ) ||
8940					rclickable.test( elem.nodeName ) &&
8941					elem.href
8942				) {
8943					return 0;
8944				}
8945
8946				return -1;
8947			}
8948		}
8949	},
8950
8951	propFix: {
8952		"for": "htmlFor",
8953		"class": "className"
8954	}
8955} );
8956
8957// Support: IE <=11 only
8958// Accessing the selectedIndex property
8959// forces the browser to respect setting selected
8960// on the option
8961// The getter ensures a default option is selected
8962// when in an optgroup
8963// eslint rule "no-unused-expressions" is disabled for this code
8964// since it considers such accessions noop
8965if ( !support.optSelected ) {
8966	jQuery.propHooks.selected = {
8967		get: function( elem ) {
8968
8969			/* eslint no-unused-expressions: "off" */
8970
8971			var parent = elem.parentNode;
8972			if ( parent && parent.parentNode ) {
8973				parent.parentNode.selectedIndex;
8974			}
8975			return null;
8976		},
8977		set: function( elem ) {
8978
8979			/* eslint no-unused-expressions: "off" */
8980
8981			var parent = elem.parentNode;
8982			if ( parent ) {
8983				parent.selectedIndex;
8984
8985				if ( parent.parentNode ) {
8986					parent.parentNode.selectedIndex;
8987				}
8988			}
8989		}
8990	};
8991}
8992
8993jQuery.each( [
8994	"tabIndex",
8995	"readOnly",
8996	"maxLength",
8997	"cellSpacing",
8998	"cellPadding",
8999	"rowSpan",
9000	"colSpan",
9001	"useMap",
9002	"frameBorder",
9003	"contentEditable"
9004], function() {
9005	jQuery.propFix[ this.toLowerCase() ] = this;
9006} );
9007
9008
9009
9010
9011	// Strip and collapse whitespace according to HTML spec
9012	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
9013	function stripAndCollapse( value ) {
9014		var tokens = value.match( rnothtmlwhite ) || [];
9015		return tokens.join( " " );
9016	}
9017
9018
9019function getClass( elem ) {
9020	return elem.getAttribute && elem.getAttribute( "class" ) || "";
9021}
9022
9023function classesToArray( value ) {
9024	if ( Array.isArray( value ) ) {
9025		return value;
9026	}
9027	if ( typeof value === "string" ) {
9028		return value.match( rnothtmlwhite ) || [];
9029	}
9030	return [];
9031}
9032
9033jQuery.fn.extend( {
9034	addClass: function( value ) {
9035		var classNames, cur, curValue, className, i, finalValue;
9036
9037		if ( isFunction( value ) ) {
9038			return this.each( function( j ) {
9039				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
9040			} );
9041		}
9042
9043		classNames = classesToArray( value );
9044
9045		if ( classNames.length ) {
9046			return this.each( function() {
9047				curValue = getClass( this );
9048				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
9049
9050				if ( cur ) {
9051					for ( i = 0; i < classNames.length; i++ ) {
9052						className = classNames[ i ];
9053						if ( cur.indexOf( " " + className + " " ) < 0 ) {
9054							cur += className + " ";
9055						}
9056					}
9057
9058					// Only assign if different to avoid unneeded rendering.
9059					finalValue = stripAndCollapse( cur );
9060					if ( curValue !== finalValue ) {
9061						this.setAttribute( "class", finalValue );
9062					}
9063				}
9064			} );
9065		}
9066
9067		return this;
9068	},
9069
9070	removeClass: function( value ) {
9071		var classNames, cur, curValue, className, i, finalValue;
9072
9073		if ( isFunction( value ) ) {
9074			return this.each( function( j ) {
9075				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
9076			} );
9077		}
9078
9079		if ( !arguments.length ) {
9080			return this.attr( "class", "" );
9081		}
9082
9083		classNames = classesToArray( value );
9084
9085		if ( classNames.length ) {
9086			return this.each( function() {
9087				curValue = getClass( this );
9088
9089				// This expression is here for better compressibility (see addClass)
9090				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
9091
9092				if ( cur ) {
9093					for ( i = 0; i < classNames.length; i++ ) {
9094						className = classNames[ i ];
9095
9096						// Remove *all* instances
9097						while ( cur.indexOf( " " + className + " " ) > -1 ) {
9098							cur = cur.replace( " " + className + " ", " " );
9099						}
9100					}
9101
9102					// Only assign if different to avoid unneeded rendering.
9103					finalValue = stripAndCollapse( cur );
9104					if ( curValue !== finalValue ) {
9105						this.setAttribute( "class", finalValue );
9106					}
9107				}
9108			} );
9109		}
9110
9111		return this;
9112	},
9113
9114	toggleClass: function( value, stateVal ) {
9115		var classNames, className, i, self,
9116			type = typeof value,
9117			isValidValue = type === "string" || Array.isArray( value );
9118
9119		if ( isFunction( value ) ) {
9120			return this.each( function( i ) {
9121				jQuery( this ).toggleClass(
9122					value.call( this, i, getClass( this ), stateVal ),
9123					stateVal
9124				);
9125			} );
9126		}
9127
9128		if ( typeof stateVal === "boolean" && isValidValue ) {
9129			return stateVal ? this.addClass( value ) : this.removeClass( value );
9130		}
9131
9132		classNames = classesToArray( value );
9133
9134		return this.each( function() {
9135			if ( isValidValue ) {
9136
9137				// Toggle individual class names
9138				self = jQuery( this );
9139
9140				for ( i = 0; i < classNames.length; i++ ) {
9141					className = classNames[ i ];
9142
9143					// Check each className given, space separated list
9144					if ( self.hasClass( className ) ) {
9145						self.removeClass( className );
9146					} else {
9147						self.addClass( className );
9148					}
9149				}
9150
9151			// Toggle whole class name
9152			} else if ( value === undefined || type === "boolean" ) {
9153				className = getClass( this );
9154				if ( className ) {
9155
9156					// Store className if set
9157					dataPriv.set( this, "__className__", className );
9158				}
9159
9160				// If the element has a class name or if we're passed `false`,
9161				// then remove the whole classname (if there was one, the above saved it).
9162				// Otherwise bring back whatever was previously saved (if anything),
9163				// falling back to the empty string if nothing was stored.
9164				if ( this.setAttribute ) {
9165					this.setAttribute( "class",
9166						className || value === false ?
9167							"" :
9168							dataPriv.get( this, "__className__" ) || ""
9169					);
9170				}
9171			}
9172		} );
9173	},
9174
9175	hasClass: function( selector ) {
9176		var className, elem,
9177			i = 0;
9178
9179		className = " " + selector + " ";
9180		while ( ( elem = this[ i++ ] ) ) {
9181			if ( elem.nodeType === 1 &&
9182				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
9183				return true;
9184			}
9185		}
9186
9187		return false;
9188	}
9189} );
9190
9191
9192
9193
9194var rreturn = /\r/g;
9195
9196jQuery.fn.extend( {
9197	val: function( value ) {
9198		var hooks, ret, valueIsFunction,
9199			elem = this[ 0 ];
9200
9201		if ( !arguments.length ) {
9202			if ( elem ) {
9203				hooks = jQuery.valHooks[ elem.type ] ||
9204					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
9205
9206				if ( hooks &&
9207					"get" in hooks &&
9208					( ret = hooks.get( elem, "value" ) ) !== undefined
9209				) {
9210					return ret;
9211				}
9212
9213				ret = elem.value;
9214
9215				// Handle most common string cases
9216				if ( typeof ret === "string" ) {
9217					return ret.replace( rreturn, "" );
9218				}
9219
9220				// Handle cases where value is null/undef or number
9221				return ret == null ? "" : ret;
9222			}
9223
9224			return;
9225		}
9226
9227		valueIsFunction = isFunction( value );
9228
9229		return this.each( function( i ) {
9230			var val;
9231
9232			if ( this.nodeType !== 1 ) {
9233				return;
9234			}
9235
9236			if ( valueIsFunction ) {
9237				val = value.call( this, i, jQuery( this ).val() );
9238			} else {
9239				val = value;
9240			}
9241
9242			// Treat null/undefined as ""; convert numbers to string
9243			if ( val == null ) {
9244				val = "";
9245
9246			} else if ( typeof val === "number" ) {
9247				val += "";
9248
9249			} else if ( Array.isArray( val ) ) {
9250				val = jQuery.map( val, function( value ) {
9251					return value == null ? "" : value + "";
9252				} );
9253			}
9254
9255			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
9256
9257			// If set returns undefined, fall back to normal setting
9258			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
9259				this.value = val;
9260			}
9261		} );
9262	}
9263} );
9264
9265jQuery.extend( {
9266	valHooks: {
9267		option: {
9268			get: function( elem ) {
9269
9270				var val = jQuery.find.attr( elem, "value" );
9271				return val != null ?
9272					val :
9273
9274					// Support: IE <=10 - 11 only
9275					// option.text throws exceptions (trac-14686, trac-14858)
9276					// Strip and collapse whitespace
9277					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
9278					stripAndCollapse( jQuery.text( elem ) );
9279			}
9280		},
9281		select: {
9282			get: function( elem ) {
9283				var value, option, i,
9284					options = elem.options,
9285					index = elem.selectedIndex,
9286					one = elem.type === "select-one",
9287					values = one ? null : [],
9288					max = one ? index + 1 : options.length;
9289
9290				if ( index < 0 ) {
9291					i = max;
9292
9293				} else {
9294					i = one ? index : 0;
9295				}
9296
9297				// Loop through all the selected options
9298				for ( ; i < max; i++ ) {
9299					option = options[ i ];
9300
9301					// Support: IE <=9 only
9302					// IE8-9 doesn't update selected after form reset (trac-2551)
9303					if ( ( option.selected || i === index ) &&
9304
9305							// Don't return options that are disabled or in a disabled optgroup
9306							!option.disabled &&
9307							( !option.parentNode.disabled ||
9308								!nodeName( option.parentNode, "optgroup" ) ) ) {
9309
9310						// Get the specific value for the option
9311						value = jQuery( option ).val();
9312
9313						// We don't need an array for one selects
9314						if ( one ) {
9315							return value;
9316						}
9317
9318						// Multi-Selects return an array
9319						values.push( value );
9320					}
9321				}
9322
9323				return values;
9324			},
9325
9326			set: function( elem, value ) {
9327				var optionSet, option,
9328					options = elem.options,
9329					values = jQuery.makeArray( value ),
9330					i = options.length;
9331
9332				while ( i-- ) {
9333					option = options[ i ];
9334
9335					/* eslint-disable no-cond-assign */
9336
9337					if ( option.selected =
9338						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
9339					) {
9340						optionSet = true;
9341					}
9342
9343					/* eslint-enable no-cond-assign */
9344				}
9345
9346				// Force browsers to behave consistently when non-matching value is set
9347				if ( !optionSet ) {
9348					elem.selectedIndex = -1;
9349				}
9350				return values;
9351			}
9352		}
9353	}
9354} );
9355
9356// Radios and checkboxes getter/setter
9357jQuery.each( [ "radio", "checkbox" ], function() {
9358	jQuery.valHooks[ this ] = {
9359		set: function( elem, value ) {
9360			if ( Array.isArray( value ) ) {
9361				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
9362			}
9363		}
9364	};
9365	if ( !support.checkOn ) {
9366		jQuery.valHooks[ this ].get = function( elem ) {
9367			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
9368		};
9369	}
9370} );
9371
9372
9373
9374
9375// Return jQuery for attributes-only inclusion
9376var location = window.location;
9377
9378var nonce = { guid: Date.now() };
9379
9380var rquery = ( /\?/ );
9381
9382
9383
9384// Cross-browser xml parsing
9385jQuery.parseXML = function( data ) {
9386	var xml, parserErrorElem;
9387	if ( !data || typeof data !== "string" ) {
9388		return null;
9389	}
9390
9391	// Support: IE 9 - 11 only
9392	// IE throws on parseFromString with invalid input.
9393	try {
9394		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
9395	} catch ( e ) {}
9396
9397	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
9398	if ( !xml || parserErrorElem ) {
9399		jQuery.error( "Invalid XML: " + (
9400			parserErrorElem ?
9401				jQuery.map( parserErrorElem.childNodes, function( el ) {
9402					return el.textContent;
9403				} ).join( "\n" ) :
9404				data
9405		) );
9406	}
9407	return xml;
9408};
9409
9410
9411var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
9412	stopPropagationCallback = function( e ) {
9413		e.stopPropagation();
9414	};
9415
9416jQuery.extend( jQuery.event, {
9417
9418	trigger: function( event, data, elem, onlyHandlers ) {
9419
9420		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
9421			eventPath = [ elem || document ],
9422			type = hasOwn.call( event, "type" ) ? event.type : event,
9423			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
9424
9425		cur = lastElement = tmp = elem = elem || document;
9426
9427		// Don't do events on text and comment nodes
9428		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
9429			return;
9430		}
9431
9432		// focus/blur morphs to focusin/out; ensure we're not firing them right now
9433		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
9434			return;
9435		}
9436
9437		if ( type.indexOf( "." ) > -1 ) {
9438
9439			// Namespaced trigger; create a regexp to match event type in handle()
9440			namespaces = type.split( "." );
9441			type = namespaces.shift();
9442			namespaces.sort();
9443		}
9444		ontype = type.indexOf( ":" ) < 0 && "on" + type;
9445
9446		// Caller can pass in a jQuery.Event object, Object, or just an event type string
9447		event = event[ jQuery.expando ] ?
9448			event :
9449			new jQuery.Event( type, typeof event === "object" && event );
9450
9451		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
9452		event.isTrigger = onlyHandlers ? 2 : 3;
9453		event.namespace = namespaces.join( "." );
9454		event.rnamespace = event.namespace ?
9455			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
9456			null;
9457
9458		// Clean up the event in case it is being reused
9459		event.result = undefined;
9460		if ( !event.target ) {
9461			event.target = elem;
9462		}
9463
9464		// Clone any incoming data and prepend the event, creating the handler arg list
9465		data = data == null ?
9466			[ event ] :
9467			jQuery.makeArray( data, [ event ] );
9468
9469		// Allow special events to draw outside the lines
9470		special = jQuery.event.special[ type ] || {};
9471		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
9472			return;
9473		}
9474
9475		// Determine event propagation path in advance, per W3C events spec (trac-9951)
9476		// Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
9477		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
9478
9479			bubbleType = special.delegateType || type;
9480			if ( !rfocusMorph.test( bubbleType + type ) ) {
9481				cur = cur.parentNode;
9482			}
9483			for ( ; cur; cur = cur.parentNode ) {
9484				eventPath.push( cur );
9485				tmp = cur;
9486			}
9487
9488			// Only add window if we got to document (e.g., not plain obj or detached DOM)
9489			if ( tmp === ( elem.ownerDocument || document ) ) {
9490				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
9491			}
9492		}
9493
9494		// Fire handlers on the event path
9495		i = 0;
9496		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
9497			lastElement = cur;
9498			event.type = i > 1 ?
9499				bubbleType :
9500				special.bindType || type;
9501
9502			// jQuery handler
9503			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
9504				dataPriv.get( cur, "handle" );
9505			if ( handle ) {
9506				handle.apply( cur, data );
9507			}
9508
9509			// Native handler
9510			handle = ontype && cur[ ontype ];
9511			if ( handle && handle.apply && acceptData( cur ) ) {
9512				event.result = handle.apply( cur, data );
9513				if ( event.result === false ) {
9514					event.preventDefault();
9515				}
9516			}
9517		}
9518		event.type = type;
9519
9520		// If nobody prevented the default action, do it now
9521		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
9522
9523			if ( ( !special._default ||
9524				special._default.apply( eventPath.pop(), data ) === false ) &&
9525				acceptData( elem ) ) {
9526
9527				// Call a native DOM method on the target with the same name as the event.
9528				// Don't do default actions on window, that's where global variables be (trac-6170)
9529				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
9530
9531					// Don't re-trigger an onFOO event when we call its FOO() method
9532					tmp = elem[ ontype ];
9533
9534					if ( tmp ) {
9535						elem[ ontype ] = null;
9536					}
9537
9538					// Prevent re-triggering of the same event, since we already bubbled it above
9539					jQuery.event.triggered = type;
9540
9541					if ( event.isPropagationStopped() ) {
9542						lastElement.addEventListener( type, stopPropagationCallback );
9543					}
9544
9545					elem[ type ]();
9546
9547					if ( event.isPropagationStopped() ) {
9548						lastElement.removeEventListener( type, stopPropagationCallback );
9549					}
9550
9551					jQuery.event.triggered = undefined;
9552
9553					if ( tmp ) {
9554						elem[ ontype ] = tmp;
9555					}
9556				}
9557			}
9558		}
9559
9560		return event.result;
9561	},
9562
9563	// Piggyback on a donor event to simulate a different one
9564	// Used only for `focus(in | out)` events
9565	simulate: function( type, elem, event ) {
9566		var e = jQuery.extend(
9567			new jQuery.Event(),
9568			event,
9569			{
9570				type: type,
9571				isSimulated: true
9572			}
9573		);
9574
9575		jQuery.event.trigger( e, null, elem );
9576	}
9577
9578} );
9579
9580jQuery.fn.extend( {
9581
9582	trigger: function( type, data ) {
9583		return this.each( function() {
9584			jQuery.event.trigger( type, data, this );
9585		} );
9586	},
9587	triggerHandler: function( type, data ) {
9588		var elem = this[ 0 ];
9589		if ( elem ) {
9590			return jQuery.event.trigger( type, data, elem, true );
9591		}
9592	}
9593} );
9594
9595
9596var
9597	rbracket = /\[\]$/,
9598	rCRLF = /\r?\n/g,
9599	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9600	rsubmittable = /^(?:input|select|textarea|keygen)/i;
9601
9602function buildParams( prefix, obj, traditional, add ) {
9603	var name;
9604
9605	if ( Array.isArray( obj ) ) {
9606
9607		// Serialize array item.
9608		jQuery.each( obj, function( i, v ) {
9609			if ( traditional || rbracket.test( prefix ) ) {
9610
9611				// Treat each array item as a scalar.
9612				add( prefix, v );
9613
9614			} else {
9615
9616				// Item is non-scalar (array or object), encode its numeric index.
9617				buildParams(
9618					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
9619					v,
9620					traditional,
9621					add
9622				);
9623			}
9624		} );
9625
9626	} else if ( !traditional && toType( obj ) === "object" ) {
9627
9628		// Serialize object item.
9629		for ( name in obj ) {
9630			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9631		}
9632
9633	} else {
9634
9635		// Serialize scalar item.
9636		add( prefix, obj );
9637	}
9638}
9639
9640// Serialize an array of form elements or a set of
9641// key/values into a query string
9642jQuery.param = function( a, traditional ) {
9643	var prefix,
9644		s = [],
9645		add = function( key, valueOrFunction ) {
9646
9647			// If value is a function, invoke it and use its return value
9648			var value = isFunction( valueOrFunction ) ?
9649				valueOrFunction() :
9650				valueOrFunction;
9651
9652			s[ s.length ] = encodeURIComponent( key ) + "=" +
9653				encodeURIComponent( value == null ? "" : value );
9654		};
9655
9656	if ( a == null ) {
9657		return "";
9658	}
9659
9660	// If an array was passed in, assume that it is an array of form elements.
9661	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9662
9663		// Serialize the form elements
9664		jQuery.each( a, function() {
9665			add( this.name, this.value );
9666		} );
9667
9668	} else {
9669
9670		// If traditional, encode the "old" way (the way 1.3.2 or older
9671		// did it), otherwise encode params recursively.
9672		for ( prefix in a ) {
9673			buildParams( prefix, a[ prefix ], traditional, add );
9674		}
9675	}
9676
9677	// Return the resulting serialization
9678	return s.join( "&" );
9679};
9680
9681jQuery.fn.extend( {
9682	serialize: function() {
9683		return jQuery.param( this.serializeArray() );
9684	},
9685	serializeArray: function() {
9686		return this.map( function() {
9687
9688			// Can add propHook for "elements" to filter or add form elements
9689			var elements = jQuery.prop( this, "elements" );
9690			return elements ? jQuery.makeArray( elements ) : this;
9691		} ).filter( function() {
9692			var type = this.type;
9693
9694			// Use .is( ":disabled" ) so that fieldset[disabled] works
9695			return this.name && !jQuery( this ).is( ":disabled" ) &&
9696				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9697				( this.checked || !rcheckableType.test( type ) );
9698		} ).map( function( _i, elem ) {
9699			var val = jQuery( this ).val();
9700
9701			if ( val == null ) {
9702				return null;
9703			}
9704
9705			if ( Array.isArray( val ) ) {
9706				return jQuery.map( val, function( val ) {
9707					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9708				} );
9709			}
9710
9711			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9712		} ).get();
9713	}
9714} );
9715
9716
9717var
9718	r20 = /%20/g,
9719	rhash = /#.*$/,
9720	rantiCache = /([?&])_=[^&]*/,
9721	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9722
9723	// trac-7653, trac-8125, trac-8152: local protocol detection
9724	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9725	rnoContent = /^(?:GET|HEAD)$/,
9726	rprotocol = /^\/\//,
9727
9728	/* Prefilters
9729	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9730	 * 2) These are called:
9731	 *    - BEFORE asking for a transport
9732	 *    - AFTER param serialization (s.data is a string if s.processData is true)
9733	 * 3) key is the dataType
9734	 * 4) the catchall symbol "*" can be used
9735	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9736	 */
9737	prefilters = {},
9738
9739	/* Transports bindings
9740	 * 1) key is the dataType
9741	 * 2) the catchall symbol "*" can be used
9742	 * 3) selection will start with transport dataType and THEN go to "*" if needed
9743	 */
9744	transports = {},
9745
9746	// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
9747	allTypes = "*/".concat( "*" ),
9748
9749	// Anchor tag for parsing the document origin
9750	originAnchor = document.createElement( "a" );
9751
9752originAnchor.href = location.href;
9753
9754// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9755function addToPrefiltersOrTransports( structure ) {
9756
9757	// dataTypeExpression is optional and defaults to "*"
9758	return function( dataTypeExpression, func ) {
9759
9760		if ( typeof dataTypeExpression !== "string" ) {
9761			func = dataTypeExpression;
9762			dataTypeExpression = "*";
9763		}
9764
9765		var dataType,
9766			i = 0,
9767			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9768
9769		if ( isFunction( func ) ) {
9770
9771			// For each dataType in the dataTypeExpression
9772			while ( ( dataType = dataTypes[ i++ ] ) ) {
9773
9774				// Prepend if requested
9775				if ( dataType[ 0 ] === "+" ) {
9776					dataType = dataType.slice( 1 ) || "*";
9777					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9778
9779				// Otherwise append
9780				} else {
9781					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9782				}
9783			}
9784		}
9785	};
9786}
9787
9788// Base inspection function for prefilters and transports
9789function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9790
9791	var inspected = {},
9792		seekingTransport = ( structure === transports );
9793
9794	function inspect( dataType ) {
9795		var selected;
9796		inspected[ dataType ] = true;
9797		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9798			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9799			if ( typeof dataTypeOrTransport === "string" &&
9800				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9801
9802				options.dataTypes.unshift( dataTypeOrTransport );
9803				inspect( dataTypeOrTransport );
9804				return false;
9805			} else if ( seekingTransport ) {
9806				return !( selected = dataTypeOrTransport );
9807			}
9808		} );
9809		return selected;
9810	}
9811
9812	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9813}
9814
9815// A special extend for ajax options
9816// that takes "flat" options (not to be deep extended)
9817// Fixes trac-9887
9818function ajaxExtend( target, src ) {
9819	var key, deep,
9820		flatOptions = jQuery.ajaxSettings.flatOptions || {};
9821
9822	for ( key in src ) {
9823		if ( src[ key ] !== undefined ) {
9824			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9825		}
9826	}
9827	if ( deep ) {
9828		jQuery.extend( true, target, deep );
9829	}
9830
9831	return target;
9832}
9833
9834/* Handles responses to an ajax request:
9835 * - finds the right dataType (mediates between content-type and expected dataType)
9836 * - returns the corresponding response
9837 */
9838function ajaxHandleResponses( s, jqXHR, responses ) {
9839
9840	var ct, type, finalDataType, firstDataType,
9841		contents = s.contents,
9842		dataTypes = s.dataTypes;
9843
9844	// Remove auto dataType and get content-type in the process
9845	while ( dataTypes[ 0 ] === "*" ) {
9846		dataTypes.shift();
9847		if ( ct === undefined ) {
9848			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9849		}
9850	}
9851
9852	// Check if we're dealing with a known content-type
9853	if ( ct ) {
9854		for ( type in contents ) {
9855			if ( contents[ type ] && contents[ type ].test( ct ) ) {
9856				dataTypes.unshift( type );
9857				break;
9858			}
9859		}
9860	}
9861
9862	// Check to see if we have a response for the expected dataType
9863	if ( dataTypes[ 0 ] in responses ) {
9864		finalDataType = dataTypes[ 0 ];
9865	} else {
9866
9867		// Try convertible dataTypes
9868		for ( type in responses ) {
9869			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9870				finalDataType = type;
9871				break;
9872			}
9873			if ( !firstDataType ) {
9874				firstDataType = type;
9875			}
9876		}
9877
9878		// Or just use first one
9879		finalDataType = finalDataType || firstDataType;
9880	}
9881
9882	// If we found a dataType
9883	// We add the dataType to the list if needed
9884	// and return the corresponding response
9885	if ( finalDataType ) {
9886		if ( finalDataType !== dataTypes[ 0 ] ) {
9887			dataTypes.unshift( finalDataType );
9888		}
9889		return responses[ finalDataType ];
9890	}
9891}
9892
9893/* Chain conversions given the request and the original response
9894 * Also sets the responseXXX fields on the jqXHR instance
9895 */
9896function ajaxConvert( s, response, jqXHR, isSuccess ) {
9897	var conv2, current, conv, tmp, prev,
9898		converters = {},
9899
9900		// Work with a copy of dataTypes in case we need to modify it for conversion
9901		dataTypes = s.dataTypes.slice();
9902
9903	// Create converters map with lowercased keys
9904	if ( dataTypes[ 1 ] ) {
9905		for ( conv in s.converters ) {
9906			converters[ conv.toLowerCase() ] = s.converters[ conv ];
9907		}
9908	}
9909
9910	current = dataTypes.shift();
9911
9912	// Convert to each sequential dataType
9913	while ( current ) {
9914
9915		if ( s.responseFields[ current ] ) {
9916			jqXHR[ s.responseFields[ current ] ] = response;
9917		}
9918
9919		// Apply the dataFilter if provided
9920		if ( !prev && isSuccess && s.dataFilter ) {
9921			response = s.dataFilter( response, s.dataType );
9922		}
9923
9924		prev = current;
9925		current = dataTypes.shift();
9926
9927		if ( current ) {
9928
9929			// There's only work to do if current dataType is non-auto
9930			if ( current === "*" ) {
9931
9932				current = prev;
9933
9934			// Convert response if prev dataType is non-auto and differs from current
9935			} else if ( prev !== "*" && prev !== current ) {
9936
9937				// Seek a direct converter
9938				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9939
9940				// If none found, seek a pair
9941				if ( !conv ) {
9942					for ( conv2 in converters ) {
9943
9944						// If conv2 outputs current
9945						tmp = conv2.split( " " );
9946						if ( tmp[ 1 ] === current ) {
9947
9948							// If prev can be converted to accepted input
9949							conv = converters[ prev + " " + tmp[ 0 ] ] ||
9950								converters[ "* " + tmp[ 0 ] ];
9951							if ( conv ) {
9952
9953								// Condense equivalence converters
9954								if ( conv === true ) {
9955									conv = converters[ conv2 ];
9956
9957								// Otherwise, insert the intermediate dataType
9958								} else if ( converters[ conv2 ] !== true ) {
9959									current = tmp[ 0 ];
9960									dataTypes.unshift( tmp[ 1 ] );
9961								}
9962								break;
9963							}
9964						}
9965					}
9966				}
9967
9968				// Apply converter (if not an equivalence)
9969				if ( conv !== true ) {
9970
9971					// Unless errors are allowed to bubble, catch and return them
9972					if ( conv && s.throws ) {
9973						response = conv( response );
9974					} else {
9975						try {
9976							response = conv( response );
9977						} catch ( e ) {
9978							return {
9979								state: "parsererror",
9980								error: conv ? e : "No conversion from " + prev + " to " + current
9981							};
9982						}
9983					}
9984				}
9985			}
9986		}
9987	}
9988
9989	return { state: "success", data: response };
9990}
9991
9992jQuery.extend( {
9993
9994	// Counter for holding the number of active queries
9995	active: 0,
9996
9997	// Last-Modified header cache for next request
9998	lastModified: {},
9999	etag: {},
10000
10001	ajaxSettings: {
10002		url: location.href,
10003		type: "GET",
10004		isLocal: rlocalProtocol.test( location.protocol ),
10005		global: true,
10006		processData: true,
10007		async: true,
10008		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
10009
10010		/*
10011		timeout: 0,
10012		data: null,
10013		dataType: null,
10014		username: null,
10015		password: null,
10016		cache: null,
10017		throws: false,
10018		traditional: false,
10019		headers: {},
10020		*/
10021
10022		accepts: {
10023			"*": allTypes,
10024			text: "text/plain",
10025			html: "text/html",
10026			xml: "application/xml, text/xml",
10027			json: "application/json, text/javascript"
10028		},
10029
10030		contents: {
10031			xml: /\bxml\b/,
10032			html: /\bhtml/,
10033			json: /\bjson\b/
10034		},
10035
10036		responseFields: {
10037			xml: "responseXML",
10038			text: "responseText",
10039			json: "responseJSON"
10040		},
10041
10042		// Data converters
10043		// Keys separate source (or catchall "*") and destination types with a single space
10044		converters: {
10045
10046			// Convert anything to text
10047			"* text": String,
10048
10049			// Text to html (true = no transformation)
10050			"text html": true,
10051
10052			// Evaluate text as a json expression
10053			"text json": JSON.parse,
10054
10055			// Parse text as xml
10056			"text xml": jQuery.parseXML
10057		},
10058
10059		// For options that shouldn't be deep extended:
10060		// you can add your own custom options here if
10061		// and when you create one that shouldn't be
10062		// deep extended (see ajaxExtend)
10063		flatOptions: {
10064			url: true,
10065			context: true
10066		}
10067	},
10068
10069	// Creates a full fledged settings object into target
10070	// with both ajaxSettings and settings fields.
10071	// If target is omitted, writes into ajaxSettings.
10072	ajaxSetup: function( target, settings ) {
10073		return settings ?
10074
10075			// Building a settings object
10076			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
10077
10078			// Extending ajaxSettings
10079			ajaxExtend( jQuery.ajaxSettings, target );
10080	},
10081
10082	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
10083	ajaxTransport: addToPrefiltersOrTransports( transports ),
10084
10085	// Main method
10086	ajax: function( url, options ) {
10087
10088		// If url is an object, simulate pre-1.5 signature
10089		if ( typeof url === "object" ) {
10090			options = url;
10091			url = undefined;
10092		}
10093
10094		// Force options to be an object
10095		options = options || {};
10096
10097		var transport,
10098
10099			// URL without anti-cache param
10100			cacheURL,
10101
10102			// Response headers
10103			responseHeadersString,
10104			responseHeaders,
10105
10106			// timeout handle
10107			timeoutTimer,
10108
10109			// Url cleanup var
10110			urlAnchor,
10111
10112			// Request state (becomes false upon send and true upon completion)
10113			completed,
10114
10115			// To know if global events are to be dispatched
10116			fireGlobals,
10117
10118			// Loop variable
10119			i,
10120
10121			// uncached part of the url
10122			uncached,
10123
10124			// Create the final options object
10125			s = jQuery.ajaxSetup( {}, options ),
10126
10127			// Callbacks context
10128			callbackContext = s.context || s,
10129
10130			// Context for global events is callbackContext if it is a DOM node or jQuery collection
10131			globalEventContext = s.context &&
10132				( callbackContext.nodeType || callbackContext.jquery ) ?
10133				jQuery( callbackContext ) :
10134				jQuery.event,
10135
10136			// Deferreds
10137			deferred = jQuery.Deferred(),
10138			completeDeferred = jQuery.Callbacks( "once memory" ),
10139
10140			// Status-dependent callbacks
10141			statusCode = s.statusCode || {},
10142
10143			// Headers (they are sent all at once)
10144			requestHeaders = {},
10145			requestHeadersNames = {},
10146
10147			// Default abort message
10148			strAbort = "canceled",
10149
10150			// Fake xhr
10151			jqXHR = {
10152				readyState: 0,
10153
10154				// Builds headers hashtable if needed
10155				getResponseHeader: function( key ) {
10156					var match;
10157					if ( completed ) {
10158						if ( !responseHeaders ) {
10159							responseHeaders = {};
10160							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
10161								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
10162									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
10163										.concat( match[ 2 ] );
10164							}
10165						}
10166						match = responseHeaders[ key.toLowerCase() + " " ];
10167					}
10168					return match == null ? null : match.join( ", " );
10169				},
10170
10171				// Raw string
10172				getAllResponseHeaders: function() {
10173					return completed ? responseHeadersString : null;
10174				},
10175
10176				// Caches the header
10177				setRequestHeader: function( name, value ) {
10178					if ( completed == null ) {
10179						name = requestHeadersNames[ name.toLowerCase() ] =
10180							requestHeadersNames[ name.toLowerCase() ] || name;
10181						requestHeaders[ name ] = value;
10182					}
10183					return this;
10184				},
10185
10186				// Overrides response content-type header
10187				overrideMimeType: function( type ) {
10188					if ( completed == null ) {
10189						s.mimeType = type;
10190					}
10191					return this;
10192				},
10193
10194				// Status-dependent callbacks
10195				statusCode: function( map ) {
10196					var code;
10197					if ( map ) {
10198						if ( completed ) {
10199
10200							// Execute the appropriate callbacks
10201							jqXHR.always( map[ jqXHR.status ] );
10202						} else {
10203
10204							// Lazy-add the new callbacks in a way that preserves old ones
10205							for ( code in map ) {
10206								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
10207							}
10208						}
10209					}
10210					return this;
10211				},
10212
10213				// Cancel the request
10214				abort: function( statusText ) {
10215					var finalText = statusText || strAbort;
10216					if ( transport ) {
10217						transport.abort( finalText );
10218					}
10219					done( 0, finalText );
10220					return this;
10221				}
10222			};
10223
10224		// Attach deferreds
10225		deferred.promise( jqXHR );
10226
10227		// Add protocol if not provided (prefilters might expect it)
10228		// Handle falsy url in the settings object (trac-10093: consistency with old signature)
10229		// We also use the url parameter if available
10230		s.url = ( ( url || s.url || location.href ) + "" )
10231			.replace( rprotocol, location.protocol + "//" );
10232
10233		// Alias method option to type as per ticket trac-12004
10234		s.type = options.method || options.type || s.method || s.type;
10235
10236		// Extract dataTypes list
10237		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
10238
10239		// A cross-domain request is in order when the origin doesn't match the current origin.
10240		if ( s.crossDomain == null ) {
10241			urlAnchor = document.createElement( "a" );
10242
10243			// Support: IE <=8 - 11, Edge 12 - 15
10244			// IE throws exception on accessing the href property if url is malformed,
10245			// e.g. http://example.com:80x/
10246			try {
10247				urlAnchor.href = s.url;
10248
10249				// Support: IE <=8 - 11 only
10250				// Anchor's host property isn't correctly set when s.url is relative
10251				urlAnchor.href = urlAnchor.href;
10252				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
10253					urlAnchor.protocol + "//" + urlAnchor.host;
10254			} catch ( e ) {
10255
10256				// If there is an error parsing the URL, assume it is crossDomain,
10257				// it can be rejected by the transport if it is invalid
10258				s.crossDomain = true;
10259			}
10260		}
10261
10262		// Convert data if not already a string
10263		if ( s.data && s.processData && typeof s.data !== "string" ) {
10264			s.data = jQuery.param( s.data, s.traditional );
10265		}
10266
10267		// Apply prefilters
10268		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
10269
10270		// If request was aborted inside a prefilter, stop there
10271		if ( completed ) {
10272			return jqXHR;
10273		}
10274
10275		// We can fire global events as of now if asked to
10276		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
10277		fireGlobals = jQuery.event && s.global;
10278
10279		// Watch for a new set of requests
10280		if ( fireGlobals && jQuery.active++ === 0 ) {
10281			jQuery.event.trigger( "ajaxStart" );
10282		}
10283
10284		// Uppercase the type
10285		s.type = s.type.toUpperCase();
10286
10287		// Determine if request has content
10288		s.hasContent = !rnoContent.test( s.type );
10289
10290		// Save the URL in case we're toying with the If-Modified-Since
10291		// and/or If-None-Match header later on
10292		// Remove hash to simplify url manipulation
10293		cacheURL = s.url.replace( rhash, "" );
10294
10295		// More options handling for requests with no content
10296		if ( !s.hasContent ) {
10297
10298			// Remember the hash so we can put it back
10299			uncached = s.url.slice( cacheURL.length );
10300
10301			// If data is available and should be processed, append data to url
10302			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
10303				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
10304
10305				// trac-9682: remove data so that it's not used in an eventual retry
10306				delete s.data;
10307			}
10308
10309			// Add or update anti-cache param if needed
10310			if ( s.cache === false ) {
10311				cacheURL = cacheURL.replace( rantiCache, "$1" );
10312				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
10313					uncached;
10314			}
10315
10316			// Put hash and anti-cache on the URL that will be requested (gh-1732)
10317			s.url = cacheURL + uncached;
10318
10319		// Change '%20' to '+' if this is encoded form body content (gh-2658)
10320		} else if ( s.data && s.processData &&
10321			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
10322			s.data = s.data.replace( r20, "+" );
10323		}
10324
10325		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
10326		if ( s.ifModified ) {
10327			if ( jQuery.lastModified[ cacheURL ] ) {
10328				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
10329			}
10330			if ( jQuery.etag[ cacheURL ] ) {
10331				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
10332			}
10333		}
10334
10335		// Set the correct header, if data is being sent
10336		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
10337			jqXHR.setRequestHeader( "Content-Type", s.contentType );
10338		}
10339
10340		// Set the Accepts header for the server, depending on the dataType
10341		jqXHR.setRequestHeader(
10342			"Accept",
10343			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
10344				s.accepts[ s.dataTypes[ 0 ] ] +
10345					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
10346				s.accepts[ "*" ]
10347		);
10348
10349		// Check for headers option
10350		for ( i in s.headers ) {
10351			jqXHR.setRequestHeader( i, s.headers[ i ] );
10352		}
10353
10354		// Allow custom headers/mimetypes and early abort
10355		if ( s.beforeSend &&
10356			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
10357
10358			// Abort if not done already and return
10359			return jqXHR.abort();
10360		}
10361
10362		// Aborting is no longer a cancellation
10363		strAbort = "abort";
10364
10365		// Install callbacks on deferreds
10366		completeDeferred.add( s.complete );
10367		jqXHR.done( s.success );
10368		jqXHR.fail( s.error );
10369
10370		// Get transport
10371		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
10372
10373		// If no transport, we auto-abort
10374		if ( !transport ) {
10375			done( -1, "No Transport" );
10376		} else {
10377			jqXHR.readyState = 1;
10378
10379			// Send global event
10380			if ( fireGlobals ) {
10381				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
10382			}
10383
10384			// If request was aborted inside ajaxSend, stop there
10385			if ( completed ) {
10386				return jqXHR;
10387			}
10388
10389			// Timeout
10390			if ( s.async && s.timeout > 0 ) {
10391				timeoutTimer = window.setTimeout( function() {
10392					jqXHR.abort( "timeout" );
10393				}, s.timeout );
10394			}
10395
10396			try {
10397				completed = false;
10398				transport.send( requestHeaders, done );
10399			} catch ( e ) {
10400
10401				// Rethrow post-completion exceptions
10402				if ( completed ) {
10403					throw e;
10404				}
10405
10406				// Propagate others as results
10407				done( -1, e );
10408			}
10409		}
10410
10411		// Callback for when everything is done
10412		function done( status, nativeStatusText, responses, headers ) {
10413			var isSuccess, success, error, response, modified,
10414				statusText = nativeStatusText;
10415
10416			// Ignore repeat invocations
10417			if ( completed ) {
10418				return;
10419			}
10420
10421			completed = true;
10422
10423			// Clear timeout if it exists
10424			if ( timeoutTimer ) {
10425				window.clearTimeout( timeoutTimer );
10426			}
10427
10428			// Dereference transport for early garbage collection
10429			// (no matter how long the jqXHR object will be used)
10430			transport = undefined;
10431
10432			// Cache response headers
10433			responseHeadersString = headers || "";
10434
10435			// Set readyState
10436			jqXHR.readyState = status > 0 ? 4 : 0;
10437
10438			// Determine if successful
10439			isSuccess = status >= 200 && status < 300 || status === 304;
10440
10441			// Get response data
10442			if ( responses ) {
10443				response = ajaxHandleResponses( s, jqXHR, responses );
10444			}
10445
10446			// Use a noop converter for missing script but not if jsonp
10447			if ( !isSuccess &&
10448				jQuery.inArray( "script", s.dataTypes ) > -1 &&
10449				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
10450				s.converters[ "text script" ] = function() {};
10451			}
10452
10453			// Convert no matter what (that way responseXXX fields are always set)
10454			response = ajaxConvert( s, response, jqXHR, isSuccess );
10455
10456			// If successful, handle type chaining
10457			if ( isSuccess ) {
10458
10459				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
10460				if ( s.ifModified ) {
10461					modified = jqXHR.getResponseHeader( "Last-Modified" );
10462					if ( modified ) {
10463						jQuery.lastModified[ cacheURL ] = modified;
10464					}
10465					modified = jqXHR.getResponseHeader( "etag" );
10466					if ( modified ) {
10467						jQuery.etag[ cacheURL ] = modified;
10468					}
10469				}
10470
10471				// if no content
10472				if ( status === 204 || s.type === "HEAD" ) {
10473					statusText = "nocontent";
10474
10475				// if not modified
10476				} else if ( status === 304 ) {
10477					statusText = "notmodified";
10478
10479				// If we have data, let's convert it
10480				} else {
10481					statusText = response.state;
10482					success = response.data;
10483					error = response.error;
10484					isSuccess = !error;
10485				}
10486			} else {
10487
10488				// Extract error from statusText and normalize for non-aborts
10489				error = statusText;
10490				if ( status || !statusText ) {
10491					statusText = "error";
10492					if ( status < 0 ) {
10493						status = 0;
10494					}
10495				}
10496			}
10497
10498			// Set data for the fake xhr object
10499			jqXHR.status = status;
10500			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
10501
10502			// Success/Error
10503			if ( isSuccess ) {
10504				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
10505			} else {
10506				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
10507			}
10508
10509			// Status-dependent callbacks
10510			jqXHR.statusCode( statusCode );
10511			statusCode = undefined;
10512
10513			if ( fireGlobals ) {
10514				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
10515					[ jqXHR, s, isSuccess ? success : error ] );
10516			}
10517
10518			// Complete
10519			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
10520
10521			if ( fireGlobals ) {
10522				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
10523
10524				// Handle the global AJAX counter
10525				if ( !( --jQuery.active ) ) {
10526					jQuery.event.trigger( "ajaxStop" );
10527				}
10528			}
10529		}
10530
10531		return jqXHR;
10532	},
10533
10534	getJSON: function( url, data, callback ) {
10535		return jQuery.get( url, data, callback, "json" );
10536	},
10537
10538	getScript: function( url, callback ) {
10539		return jQuery.get( url, undefined, callback, "script" );
10540	}
10541} );
10542
10543jQuery.each( [ "get", "post" ], function( _i, method ) {
10544	jQuery[ method ] = function( url, data, callback, type ) {
10545
10546		// Shift arguments if data argument was omitted
10547		if ( isFunction( data ) ) {
10548			type = type || callback;
10549			callback = data;
10550			data = undefined;
10551		}
10552
10553		// The url can be an options object (which then must have .url)
10554		return jQuery.ajax( jQuery.extend( {
10555			url: url,
10556			type: method,
10557			dataType: type,
10558			data: data,
10559			success: callback
10560		}, jQuery.isPlainObject( url ) && url ) );
10561	};
10562} );
10563
10564jQuery.ajaxPrefilter( function( s ) {
10565	var i;
10566	for ( i in s.headers ) {
10567		if ( i.toLowerCase() === "content-type" ) {
10568			s.contentType = s.headers[ i ] || "";
10569		}
10570	}
10571} );
10572
10573
10574jQuery._evalUrl = function( url, options, doc ) {
10575	return jQuery.ajax( {
10576		url: url,
10577
10578		// Make this explicit, since user can override this through ajaxSetup (trac-11264)
10579		type: "GET",
10580		dataType: "script",
10581		cache: true,
10582		async: false,
10583		global: false,
10584
10585		// Only evaluate the response if it is successful (gh-4126)
10586		// dataFilter is not invoked for failure responses, so using it instead
10587		// of the default converter is kludgy but it works.
10588		converters: {
10589			"text script": function() {}
10590		},
10591		dataFilter: function( response ) {
10592			jQuery.globalEval( response, options, doc );
10593		}
10594	} );
10595};
10596
10597
10598jQuery.fn.extend( {
10599	wrapAll: function( html ) {
10600		var wrap;
10601
10602		if ( this[ 0 ] ) {
10603			if ( isFunction( html ) ) {
10604				html = html.call( this[ 0 ] );
10605			}
10606
10607			// The elements to wrap the target around
10608			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
10609
10610			if ( this[ 0 ].parentNode ) {
10611				wrap.insertBefore( this[ 0 ] );
10612			}
10613
10614			wrap.map( function() {
10615				var elem = this;
10616
10617				while ( elem.firstElementChild ) {
10618					elem = elem.firstElementChild;
10619				}
10620
10621				return elem;
10622			} ).append( this );
10623		}
10624
10625		return this;
10626	},
10627
10628	wrapInner: function( html ) {
10629		if ( isFunction( html ) ) {
10630			return this.each( function( i ) {
10631				jQuery( this ).wrapInner( html.call( this, i ) );
10632			} );
10633		}
10634
10635		return this.each( function() {
10636			var self = jQuery( this ),
10637				contents = self.contents();
10638
10639			if ( contents.length ) {
10640				contents.wrapAll( html );
10641
10642			} else {
10643				self.append( html );
10644			}
10645		} );
10646	},
10647
10648	wrap: function( html ) {
10649		var htmlIsFunction = isFunction( html );
10650
10651		return this.each( function( i ) {
10652			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
10653		} );
10654	},
10655
10656	unwrap: function( selector ) {
10657		this.parent( selector ).not( "body" ).each( function() {
10658			jQuery( this ).replaceWith( this.childNodes );
10659		} );
10660		return this;
10661	}
10662} );
10663
10664
10665jQuery.expr.pseudos.hidden = function( elem ) {
10666	return !jQuery.expr.pseudos.visible( elem );
10667};
10668jQuery.expr.pseudos.visible = function( elem ) {
10669	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
10670};
10671
10672
10673
10674
10675jQuery.ajaxSettings.xhr = function() {
10676	try {
10677		return new window.XMLHttpRequest();
10678	} catch ( e ) {}
10679};
10680
10681var xhrSuccessStatus = {
10682
10683		// File protocol always yields status code 0, assume 200
10684		0: 200,
10685
10686		// Support: IE <=9 only
10687		// trac-1450: sometimes IE returns 1223 when it should be 204
10688		1223: 204
10689	},
10690	xhrSupported = jQuery.ajaxSettings.xhr();
10691
10692support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10693support.ajax = xhrSupported = !!xhrSupported;
10694
10695jQuery.ajaxTransport( function( options ) {
10696	var callback, errorCallback;
10697
10698	// Cross domain only allowed if supported through XMLHttpRequest
10699	if ( support.cors || xhrSupported && !options.crossDomain ) {
10700		return {
10701			send: function( headers, complete ) {
10702				var i,
10703					xhr = options.xhr();
10704
10705				xhr.open(
10706					options.type,
10707					options.url,
10708					options.async,
10709					options.username,
10710					options.password
10711				);
10712
10713				// Apply custom fields if provided
10714				if ( options.xhrFields ) {
10715					for ( i in options.xhrFields ) {
10716						xhr[ i ] = options.xhrFields[ i ];
10717					}
10718				}
10719
10720				// Override mime type if needed
10721				if ( options.mimeType && xhr.overrideMimeType ) {
10722					xhr.overrideMimeType( options.mimeType );
10723				}
10724
10725				// X-Requested-With header
10726				// For cross-domain requests, seeing as conditions for a preflight are
10727				// akin to a jigsaw puzzle, we simply never set it to be sure.
10728				// (it can always be set on a per-request basis or even using ajaxSetup)
10729				// For same-domain requests, won't change header if already provided.
10730				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10731					headers[ "X-Requested-With" ] = "XMLHttpRequest";
10732				}
10733
10734				// Set headers
10735				for ( i in headers ) {
10736					xhr.setRequestHeader( i, headers[ i ] );
10737				}
10738
10739				// Callback
10740				callback = function( type ) {
10741					return function() {
10742						if ( callback ) {
10743							callback = errorCallback = xhr.onload =
10744								xhr.onerror = xhr.onabort = xhr.ontimeout =
10745									xhr.onreadystatechange = null;
10746
10747							if ( type === "abort" ) {
10748								xhr.abort();
10749							} else if ( type === "error" ) {
10750
10751								// Support: IE <=9 only
10752								// On a manual native abort, IE9 throws
10753								// errors on any property access that is not readyState
10754								if ( typeof xhr.status !== "number" ) {
10755									complete( 0, "error" );
10756								} else {
10757									complete(
10758
10759										// File: protocol always yields status 0; see trac-8605, trac-14207
10760										xhr.status,
10761										xhr.statusText
10762									);
10763								}
10764							} else {
10765								complete(
10766									xhrSuccessStatus[ xhr.status ] || xhr.status,
10767									xhr.statusText,
10768
10769									// Support: IE <=9 only
10770									// IE9 has no XHR2 but throws on binary (trac-11426)
10771									// For XHR2 non-text, let the caller handle it (gh-2498)
10772									( xhr.responseType || "text" ) !== "text"  ||
10773									typeof xhr.responseText !== "string" ?
10774										{ binary: xhr.response } :
10775										{ text: xhr.responseText },
10776									xhr.getAllResponseHeaders()
10777								);
10778							}
10779						}
10780					};
10781				};
10782
10783				// Listen to events
10784				xhr.onload = callback();
10785				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10786
10787				// Support: IE 9 only
10788				// Use onreadystatechange to replace onabort
10789				// to handle uncaught aborts
10790				if ( xhr.onabort !== undefined ) {
10791					xhr.onabort = errorCallback;
10792				} else {
10793					xhr.onreadystatechange = function() {
10794
10795						// Check readyState before timeout as it changes
10796						if ( xhr.readyState === 4 ) {
10797
10798							// Allow onerror to be called first,
10799							// but that will not handle a native abort
10800							// Also, save errorCallback to a variable
10801							// as xhr.onerror cannot be accessed
10802							window.setTimeout( function() {
10803								if ( callback ) {
10804									errorCallback();
10805								}
10806							} );
10807						}
10808					};
10809				}
10810
10811				// Create the abort callback
10812				callback = callback( "abort" );
10813
10814				try {
10815
10816					// Do send the request (this may raise an exception)
10817					xhr.send( options.hasContent && options.data || null );
10818				} catch ( e ) {
10819
10820					// trac-14683: Only rethrow if this hasn't been notified as an error yet
10821					if ( callback ) {
10822						throw e;
10823					}
10824				}
10825			},
10826
10827			abort: function() {
10828				if ( callback ) {
10829					callback();
10830				}
10831			}
10832		};
10833	}
10834} );
10835
10836
10837
10838
10839// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10840jQuery.ajaxPrefilter( function( s ) {
10841	if ( s.crossDomain ) {
10842		s.contents.script = false;
10843	}
10844} );
10845
10846// Install script dataType
10847jQuery.ajaxSetup( {
10848	accepts: {
10849		script: "text/javascript, application/javascript, " +
10850			"application/ecmascript, application/x-ecmascript"
10851	},
10852	contents: {
10853		script: /\b(?:java|ecma)script\b/
10854	},
10855	converters: {
10856		"text script": function( text ) {
10857			jQuery.globalEval( text );
10858			return text;
10859		}
10860	}
10861} );
10862
10863// Handle cache's special case and crossDomain
10864jQuery.ajaxPrefilter( "script", function( s ) {
10865	if ( s.cache === undefined ) {
10866		s.cache = false;
10867	}
10868	if ( s.crossDomain ) {
10869		s.type = "GET";
10870	}
10871} );
10872
10873// Bind script tag hack transport
10874jQuery.ajaxTransport( "script", function( s ) {
10875
10876	// This transport only deals with cross domain or forced-by-attrs requests
10877	if ( s.crossDomain || s.scriptAttrs ) {
10878		var script, callback;
10879		return {
10880			send: function( _, complete ) {
10881				script = jQuery( "<script>" )
10882					.attr( s.scriptAttrs || {} )
10883					.prop( { charset: s.scriptCharset, src: s.url } )
10884					.on( "load error", callback = function( evt ) {
10885						script.remove();
10886						callback = null;
10887						if ( evt ) {
10888							complete( evt.type === "error" ? 404 : 200, evt.type );
10889						}
10890					} );
10891
10892				// Use native DOM manipulation to avoid our domManip AJAX trickery
10893				document.head.appendChild( script[ 0 ] );
10894			},
10895			abort: function() {
10896				if ( callback ) {
10897					callback();
10898				}
10899			}
10900		};
10901	}
10902} );
10903
10904
10905
10906
10907var oldCallbacks = [],
10908	rjsonp = /(=)\?(?=&|$)|\?\?/;
10909
10910// Default jsonp settings
10911jQuery.ajaxSetup( {
10912	jsonp: "callback",
10913	jsonpCallback: function() {
10914		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10915		this[ callback ] = true;
10916		return callback;
10917	}
10918} );
10919
10920// Detect, normalize options and install callbacks for jsonp requests
10921jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10922
10923	var callbackName, overwritten, responseContainer,
10924		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10925			"url" :
10926			typeof s.data === "string" &&
10927				( s.contentType || "" )
10928					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10929				rjsonp.test( s.data ) && "data"
10930		);
10931
10932	// Handle iff the expected data type is "jsonp" or we have a parameter to set
10933	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10934
10935		// Get callback name, remembering preexisting value associated with it
10936		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10937			s.jsonpCallback() :
10938			s.jsonpCallback;
10939
10940		// Insert callback into url or form data
10941		if ( jsonProp ) {
10942			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10943		} else if ( s.jsonp !== false ) {
10944			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10945		}
10946
10947		// Use data converter to retrieve json after script execution
10948		s.converters[ "script json" ] = function() {
10949			if ( !responseContainer ) {
10950				jQuery.error( callbackName + " was not called" );
10951			}
10952			return responseContainer[ 0 ];
10953		};
10954
10955		// Force json dataType
10956		s.dataTypes[ 0 ] = "json";
10957
10958		// Install callback
10959		overwritten = window[ callbackName ];
10960		window[ callbackName ] = function() {
10961			responseContainer = arguments;
10962		};
10963
10964		// Clean-up function (fires after converters)
10965		jqXHR.always( function() {
10966
10967			// If previous value didn't exist - remove it
10968			if ( overwritten === undefined ) {
10969				jQuery( window ).removeProp( callbackName );
10970
10971			// Otherwise restore preexisting value
10972			} else {
10973				window[ callbackName ] = overwritten;
10974			}
10975
10976			// Save back as free
10977			if ( s[ callbackName ] ) {
10978
10979				// Make sure that re-using the options doesn't screw things around
10980				s.jsonpCallback = originalSettings.jsonpCallback;
10981
10982				// Save the callback name for future use
10983				oldCallbacks.push( callbackName );
10984			}
10985
10986			// Call if it was a function and we have a response
10987			if ( responseContainer && isFunction( overwritten ) ) {
10988				overwritten( responseContainer[ 0 ] );
10989			}
10990
10991			responseContainer = overwritten = undefined;
10992		} );
10993
10994		// Delegate to script
10995		return "script";
10996	}
10997} );
10998
10999
11000
11001
11002// Support: Safari 8 only
11003// In Safari 8 documents created via document.implementation.createHTMLDocument
11004// collapse sibling forms: the second one becomes a child of the first one.
11005// Because of that, this security measure has to be disabled in Safari 8.
11006// https://bugs.webkit.org/show_bug.cgi?id=137337
11007support.createHTMLDocument = ( function() {
11008	var body = document.implementation.createHTMLDocument( "" ).body;
11009	body.innerHTML = "<form></form><form></form>";
11010	return body.childNodes.length === 2;
11011} )();
11012
11013
11014// Argument "data" should be string of html
11015// context (optional): If specified, the fragment will be created in this context,
11016// defaults to document
11017// keepScripts (optional): If true, will include scripts passed in the html string
11018jQuery.parseHTML = function( data, context, keepScripts ) {
11019	if ( typeof data !== "string" ) {
11020		return [];
11021	}
11022	if ( typeof context === "boolean" ) {
11023		keepScripts = context;
11024		context = false;
11025	}
11026
11027	var base, parsed, scripts;
11028
11029	if ( !context ) {
11030
11031		// Stop scripts or inline event handlers from being executed immediately
11032		// by using document.implementation
11033		if ( support.createHTMLDocument ) {
11034			context = document.implementation.createHTMLDocument( "" );
11035
11036			// Set the base href for the created document
11037			// so any parsed elements with URLs
11038			// are based on the document's URL (gh-2965)
11039			base = context.createElement( "base" );
11040			base.href = document.location.href;
11041			context.head.appendChild( base );
11042		} else {
11043			context = document;
11044		}
11045	}
11046
11047	parsed = rsingleTag.exec( data );
11048	scripts = !keepScripts && [];
11049
11050	// Single tag
11051	if ( parsed ) {
11052		return [ context.createElement( parsed[ 1 ] ) ];
11053	}
11054
11055	parsed = buildFragment( [ data ], context, scripts );
11056
11057	if ( scripts && scripts.length ) {
11058		jQuery( scripts ).remove();
11059	}
11060
11061	return jQuery.merge( [], parsed.childNodes );
11062};
11063
11064
11065/**
11066 * Load a url into a page
11067 */
11068jQuery.fn.load = function( url, params, callback ) {
11069	var selector, type, response,
11070		self = this,
11071		off = url.indexOf( " " );
11072
11073	if ( off > -1 ) {
11074		selector = stripAndCollapse( url.slice( off ) );
11075		url = url.slice( 0, off );
11076	}
11077
11078	// If it's a function
11079	if ( isFunction( params ) ) {
11080
11081		// We assume that it's the callback
11082		callback = params;
11083		params = undefined;
11084
11085	// Otherwise, build a param string
11086	} else if ( params && typeof params === "object" ) {
11087		type = "POST";
11088	}
11089
11090	// If we have elements to modify, make the request
11091	if ( self.length > 0 ) {
11092		jQuery.ajax( {
11093			url: url,
11094
11095			// If "type" variable is undefined, then "GET" method will be used.
11096			// Make value of this field explicit since
11097			// user can override it through ajaxSetup method
11098			type: type || "GET",
11099			dataType: "html",
11100			data: params
11101		} ).done( function( responseText ) {
11102
11103			// Save response for use in complete callback
11104			response = arguments;
11105
11106			self.html( selector ?
11107
11108				// If a selector was specified, locate the right elements in a dummy div
11109				// Exclude scripts to avoid IE 'Permission Denied' errors
11110				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
11111
11112				// Otherwise use the full result
11113				responseText );
11114
11115		// If the request succeeds, this function gets "data", "status", "jqXHR"
11116		// but they are ignored because response was set above.
11117		// If it fails, this function gets "jqXHR", "status", "error"
11118		} ).always( callback && function( jqXHR, status ) {
11119			self.each( function() {
11120				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
11121			} );
11122		} );
11123	}
11124
11125	return this;
11126};
11127
11128
11129
11130
11131jQuery.expr.pseudos.animated = function( elem ) {
11132	return jQuery.grep( jQuery.timers, function( fn ) {
11133		return elem === fn.elem;
11134	} ).length;
11135};
11136
11137
11138
11139
11140jQuery.offset = {
11141	setOffset: function( elem, options, i ) {
11142		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
11143			position = jQuery.css( elem, "position" ),
11144			curElem = jQuery( elem ),
11145			props = {};
11146
11147		// Set position first, in-case top/left are set even on static elem
11148		if ( position === "static" ) {
11149			elem.style.position = "relative";
11150		}
11151
11152		curOffset = curElem.offset();
11153		curCSSTop = jQuery.css( elem, "top" );
11154		curCSSLeft = jQuery.css( elem, "left" );
11155		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
11156			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
11157
11158		// Need to be able to calculate position if either
11159		// top or left is auto and position is either absolute or fixed
11160		if ( calculatePosition ) {
11161			curPosition = curElem.position();
11162			curTop = curPosition.top;
11163			curLeft = curPosition.left;
11164
11165		} else {
11166			curTop = parseFloat( curCSSTop ) || 0;
11167			curLeft = parseFloat( curCSSLeft ) || 0;
11168		}
11169
11170		if ( isFunction( options ) ) {
11171
11172			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
11173			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
11174		}
11175
11176		if ( options.top != null ) {
11177			props.top = ( options.top - curOffset.top ) + curTop;
11178		}
11179		if ( options.left != null ) {
11180			props.left = ( options.left - curOffset.left ) + curLeft;
11181		}
11182
11183		if ( "using" in options ) {
11184			options.using.call( elem, props );
11185
11186		} else {
11187			curElem.css( props );
11188		}
11189	}
11190};
11191
11192jQuery.fn.extend( {
11193
11194	// offset() relates an element's border box to the document origin
11195	offset: function( options ) {
11196
11197		// Preserve chaining for setter
11198		if ( arguments.length ) {
11199			return options === undefined ?
11200				this :
11201				this.each( function( i ) {
11202					jQuery.offset.setOffset( this, options, i );
11203				} );
11204		}
11205
11206		var rect, win,
11207			elem = this[ 0 ];
11208
11209		if ( !elem ) {
11210			return;
11211		}
11212
11213		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
11214		// Support: IE <=11 only
11215		// Running getBoundingClientRect on a
11216		// disconnected node in IE throws an error
11217		if ( !elem.getClientRects().length ) {
11218			return { top: 0, left: 0 };
11219		}
11220
11221		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
11222		rect = elem.getBoundingClientRect();
11223		win = elem.ownerDocument.defaultView;
11224		return {
11225			top: rect.top + win.pageYOffset,
11226			left: rect.left + win.pageXOffset
11227		};
11228	},
11229
11230	// position() relates an element's margin box to its offset parent's padding box
11231	// This corresponds to the behavior of CSS absolute positioning
11232	position: function() {
11233		if ( !this[ 0 ] ) {
11234			return;
11235		}
11236
11237		var offsetParent, offset, doc,
11238			elem = this[ 0 ],
11239			parentOffset = { top: 0, left: 0 };
11240
11241		// position:fixed elements are offset from the viewport, which itself always has zero offset
11242		if ( jQuery.css( elem, "position" ) === "fixed" ) {
11243
11244			// Assume position:fixed implies availability of getBoundingClientRect
11245			offset = elem.getBoundingClientRect();
11246
11247		} else {
11248			offset = this.offset();
11249
11250			// Account for the *real* offset parent, which can be the document or its root element
11251			// when a statically positioned element is identified
11252			doc = elem.ownerDocument;
11253			offsetParent = elem.offsetParent || doc.documentElement;
11254			while ( offsetParent &&
11255				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
11256				jQuery.css( offsetParent, "position" ) === "static" ) {
11257
11258				offsetParent = offsetParent.parentNode;
11259			}
11260			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
11261
11262				// Incorporate borders into its offset, since they are outside its content origin
11263				parentOffset = jQuery( offsetParent ).offset();
11264				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
11265				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
11266			}
11267		}
11268
11269		// Subtract parent offsets and element margins
11270		return {
11271			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
11272			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
11273		};
11274	},
11275
11276	// This method will return documentElement in the following cases:
11277	// 1) For the element inside the iframe without offsetParent, this method will return
11278	//    documentElement of the parent window
11279	// 2) For the hidden or detached element
11280	// 3) For body or html element, i.e. in case of the html node - it will return itself
11281	//
11282	// but those exceptions were never presented as a real life use-cases
11283	// and might be considered as more preferable results.
11284	//
11285	// This logic, however, is not guaranteed and can change at any point in the future
11286	offsetParent: function() {
11287		return this.map( function() {
11288			var offsetParent = this.offsetParent;
11289
11290			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
11291				offsetParent = offsetParent.offsetParent;
11292			}
11293
11294			return offsetParent || documentElement;
11295		} );
11296	}
11297} );
11298
11299// Create scrollLeft and scrollTop methods
11300jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
11301	var top = "pageYOffset" === prop;
11302
11303	jQuery.fn[ method ] = function( val ) {
11304		return access( this, function( elem, method, val ) {
11305
11306			// Coalesce documents and windows
11307			var win;
11308			if ( isWindow( elem ) ) {
11309				win = elem;
11310			} else if ( elem.nodeType === 9 ) {
11311				win = elem.defaultView;
11312			}
11313
11314			if ( val === undefined ) {
11315				return win ? win[ prop ] : elem[ method ];
11316			}
11317
11318			if ( win ) {
11319				win.scrollTo(
11320					!top ? val : win.pageXOffset,
11321					top ? val : win.pageYOffset
11322				);
11323
11324			} else {
11325				elem[ method ] = val;
11326			}
11327		}, method, val, arguments.length );
11328	};
11329} );
11330
11331// Support: Safari <=7 - 9.1, Chrome <=37 - 49
11332// Add the top/left cssHooks using jQuery.fn.position
11333// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
11334// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
11335// getComputedStyle returns percent when specified for top/left/bottom/right;
11336// rather than make the css module depend on the offset module, just check for it here
11337jQuery.each( [ "top", "left" ], function( _i, prop ) {
11338	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
11339		function( elem, computed ) {
11340			if ( computed ) {
11341				computed = curCSS( elem, prop );
11342
11343				// If curCSS returns percentage, fallback to offset
11344				return rnumnonpx.test( computed ) ?
11345					jQuery( elem ).position()[ prop ] + "px" :
11346					computed;
11347			}
11348		}
11349	);
11350} );
11351
11352
11353// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
11354jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
11355	jQuery.each( {
11356		padding: "inner" + name,
11357		content: type,
11358		"": "outer" + name
11359	}, function( defaultExtra, funcName ) {
11360
11361		// Margin is only for outerHeight, outerWidth
11362		jQuery.fn[ funcName ] = function( margin, value ) {
11363			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
11364				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
11365
11366			return access( this, function( elem, type, value ) {
11367				var doc;
11368
11369				if ( isWindow( elem ) ) {
11370
11371					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
11372					return funcName.indexOf( "outer" ) === 0 ?
11373						elem[ "inner" + name ] :
11374						elem.document.documentElement[ "client" + name ];
11375				}
11376
11377				// Get document width or height
11378				if ( elem.nodeType === 9 ) {
11379					doc = elem.documentElement;
11380
11381					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
11382					// whichever is greatest
11383					return Math.max(
11384						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
11385						elem.body[ "offset" + name ], doc[ "offset" + name ],
11386						doc[ "client" + name ]
11387					);
11388				}
11389
11390				return value === undefined ?
11391
11392					// Get width or height on the element, requesting but not forcing parseFloat
11393					jQuery.css( elem, type, extra ) :
11394
11395					// Set width or height on the element
11396					jQuery.style( elem, type, value, extra );
11397			}, type, chainable ? margin : undefined, chainable );
11398		};
11399	} );
11400} );
11401
11402
11403jQuery.each( [
11404	"ajaxStart",
11405	"ajaxStop",
11406	"ajaxComplete",
11407	"ajaxError",
11408	"ajaxSuccess",
11409	"ajaxSend"
11410], function( _i, type ) {
11411	jQuery.fn[ type ] = function( fn ) {
11412		return this.on( type, fn );
11413	};
11414} );
11415
11416
11417
11418
11419jQuery.fn.extend( {
11420
11421	bind: function( types, data, fn ) {
11422		return this.on( types, null, data, fn );
11423	},
11424	unbind: function( types, fn ) {
11425		return this.off( types, null, fn );
11426	},
11427
11428	delegate: function( selector, types, data, fn ) {
11429		return this.on( types, selector, data, fn );
11430	},
11431	undelegate: function( selector, types, fn ) {
11432
11433		// ( namespace ) or ( selector, types [, fn] )
11434		return arguments.length === 1 ?
11435			this.off( selector, "**" ) :
11436			this.off( types, selector || "**", fn );
11437	},
11438
11439	hover: function( fnOver, fnOut ) {
11440		return this
11441			.on( "mouseenter", fnOver )
11442			.on( "mouseleave", fnOut || fnOver );
11443	}
11444} );
11445
11446jQuery.each(
11447	( "blur focus focusin focusout resize scroll click dblclick " +
11448	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
11449	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
11450	function( _i, name ) {
11451
11452		// Handle event binding
11453		jQuery.fn[ name ] = function( data, fn ) {
11454			return arguments.length > 0 ?
11455				this.on( name, null, data, fn ) :
11456				this.trigger( name );
11457		};
11458	}
11459);
11460
11461
11462
11463
11464// Support: Android <=4.0 only
11465// Make sure we trim BOM and NBSP
11466// Require that the "whitespace run" starts from a non-whitespace
11467// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
11468var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
11469
11470// Bind a function to a context, optionally partially applying any
11471// arguments.
11472// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
11473// However, it is not slated for removal any time soon
11474jQuery.proxy = function( fn, context ) {
11475	var tmp, args, proxy;
11476
11477	if ( typeof context === "string" ) {
11478		tmp = fn[ context ];
11479		context = fn;
11480		fn = tmp;
11481	}
11482
11483	// Quick check to determine if target is callable, in the spec
11484	// this throws a TypeError, but we will just return undefined.
11485	if ( !isFunction( fn ) ) {
11486		return undefined;
11487	}
11488
11489	// Simulated bind
11490	args = slice.call( arguments, 2 );
11491	proxy = function() {
11492		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
11493	};
11494
11495	// Set the guid of unique handler to the same of original handler, so it can be removed
11496	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
11497
11498	return proxy;
11499};
11500
11501jQuery.holdReady = function( hold ) {
11502	if ( hold ) {
11503		jQuery.readyWait++;
11504	} else {
11505		jQuery.ready( true );
11506	}
11507};
11508jQuery.isArray = Array.isArray;
11509jQuery.parseJSON = JSON.parse;
11510jQuery.nodeName = nodeName;
11511jQuery.isFunction = isFunction;
11512jQuery.isWindow = isWindow;
11513jQuery.camelCase = camelCase;
11514jQuery.type = toType;
11515
11516jQuery.now = Date.now;
11517
11518jQuery.isNumeric = function( obj ) {
11519
11520	// As of jQuery 3.0, isNumeric is limited to
11521	// strings and numbers (primitives or objects)
11522	// that can be coerced to finite numbers (gh-2662)
11523	var type = jQuery.type( obj );
11524	return ( type === "number" || type === "string" ) &&
11525
11526		// parseFloat NaNs numeric-cast false positives ("")
11527		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
11528		// subtraction forces infinities to NaN
11529		!isNaN( obj - parseFloat( obj ) );
11530};
11531
11532jQuery.trim = function( text ) {
11533	return text == null ?
11534		"" :
11535		( text + "" ).replace( rtrim, "$1" );
11536};
11537
11538
11539
11540// Register as a named AMD module, since jQuery can be concatenated with other
11541// files that may use define, but not via a proper concatenation script that
11542// understands anonymous AMD modules. A named AMD is safest and most robust
11543// way to register. Lowercase jquery is used because AMD module names are
11544// derived from file names, and jQuery is normally delivered in a lowercase
11545// file name. Do this after creating the global so that if an AMD module wants
11546// to call noConflict to hide this version of jQuery, it will work.
11547
11548// Note that for maximum portability, libraries that are not jQuery should
11549// declare themselves as anonymous modules, and avoid setting a global if an
11550// AMD loader is present. jQuery is a special case. For more information, see
11551// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
11552
11553if ( t
11553rue ) {
11554	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
11555		return jQuery;
11556	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
11557		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11558}
11559
11560
11561
11562
11563var
11564
11565	// Map over jQuery in case of overwrite
11566	_jQuery = window.jQuery,
11567
11568	// Map over the $ in case of overwrite
11569	_$ = window.$;
11570
11571jQuery.noConflict = function( deep ) {
11572	if ( window.$ === jQuery ) {
11573		window.$ = _$;
11574	}
11575
11576	if ( deep && window.jQuery === jQuery ) {
11577		window.jQuery = _jQuery;
11578	}
11579
11580	return jQuery;
11581};
11582
11583// Expose jQuery and $ identifiers, even in AMD
11584// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
11585// and CommonJS for browser emulators (trac-13566)
11586if ( typeof noGlobal === "undefined" ) {
11587	window.jQuery = window.$ = jQuery;
11588}
11589
11590
11591
11592
11593return jQuery;
11594} );
11595
11596
11597/***/ })
11598
11599/******/ 	});
11600/************************************************************************/
11601/******/ 	// The module cache
11602/******/ 	var __webpack_module_cache__ = {};
11603/******/ 	
11604/******/ 	// The require function
11605/******/ 	function __webpack_require__(moduleId) {
11606/******/ 		// Check if module is in cache
11607/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
11608/******/ 		if (cachedModule !== undefined) {
11609/******/ 			return cachedModule.exports;
11610/******/ 		}
11611/******/ 		// Create a new module (and put it into the cache)
11612/******/ 		var module = __webpack_module_cache__[moduleId] = {
11613/******/ 			// no module.id needed
11614/******/ 			// no module.loaded needed
11615/******/ 			exports: {}
11616/******/ 		};
11617/******/ 	
11618/******/ 		// Execute the module function
11619/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11620/******/ 	
11621/******/ 		// Return the exports of the module
11622/******/ 		return module.exports;
11623/******/ 	}
11624/******/ 	
11625/************************************************************************/
11626/******/ 	/* webpack/runtime/compat get default export */
11627/******/ 	(() => {
11628/******/ 		// getDefaultExport function for compatibility with non-harmony modules
11629/******/ 		__webpack_require__.n = (module) => {
11630/******/ 			var getter = module && module.__esModule ?
11631/******/ 				() => (module['default']) :
11632/******/ 				() => (module);
11633/******/ 			__webpack_require__.d(getter, { a: getter });
11634/******/ 			return getter;
11635/******/ 		};
11636/******/ 	})();
11637/******/ 	
11638/******/ 	/* webpack/runtime/define property getters */
11639/******/ 	(() => {
11640/******/ 		// define getter functions for harmony exports
11641/******/ 		__webpack_require__.d = (exports, definition) => {
11642/******/ 			for(var key in definition) {
11643/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11644/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11645/******/ 				}
11646/******/ 			}
11647/******/ 		};
11648/******/ 	})();
11649/******/ 	
11650/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
11651/******/ 	(() => {
11652/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11653/******/ 	})();
11654/******/ 	
11655/************************************************************************/
11656var __webpack_exports__ = {};
11657// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11658(() => {
11659"use strict";
11660
11661// EXTERNAL MODULE: ./node_modules/jquery/dist/jquery.js
11662var jquery = __webpack_require__(692);
11663var jquery_default = /*#__PURE__*/__webpack_require__.n(jquery);
11664// EXTERNAL MODULE: ./wp-content/themes/sfrtheme/assets/js/css_browser_selector.js
11665var css_browser_selector = __webpack_require__(360);
11666;// ./wp-content/themes/sfrtheme/assets/js/input-address.js
11667
11668jquery_default()(document).ready(function () {
11669  ajaxEligibiliteAddress();
11670  jquery_default()('#input-city').change(function () {
11671    jquery_default()('#input-street').val('').prop("disabled", true);
11672    jquery_default()('#input-number').val('').prop("disabled", true);
11673    jquery_default()('#input-lat').val('');
11674    jquery_default()('#input-lon').val('');
11675    jquery_default()('#button-submit').prop("disabled", true);
11676    if (!jquery_default()(this).val()) {
11677      return;
11678    }
11679    jquery_default()('#input-street').parents('.reverse').addClass('loading');
11680    var params = {
11681      'postal_code': jquery_default()(this).val().split(',')[1]
11682    };
11683    jquery_default().ajax({
11684      url: sfrJSVars.ajaxurl,
11685      method: 'POST',
11686      data: {
11687        'action': 'ajaxGetStreetNames',
11688        'params': params
11689      },
11690      success: function (data) {
11691        var streetNames = JSON.parse(data);
11692        jquery_default()('#input-street').parents('.reverse').removeClass('loading');
11693        jquery_default()("#input-street").prop("disabled", false);
11694        jquery_default()("#input-street").easyAutocomplete({
11695          data: streetNames,
11696          requestDelay: 500,
11697          list: {
11698            match: {
11699              enabled: true
11700            },
11701            onClickEvent: getStreetNumbers
11702          },
11703          theme: "square"
11704        });
11705      },
11706      error: function (request, error) {
11707        console.log(error);
11708      }
11709    });
11710  });
11711  function getStreetNumbers() {
11712    jquery_default()('#input-number').val('').prop("disabled", true);
11713    jquery_default()('#input-lat').val('');
11714    jquery_default()('#input-lon').val('');
11715    jquery_default()('#button-submit').prop("disabled", true);
11716    if (!jquery_default()("#input-street").val()) {
11717      return;
11718    }
11719    jquery_default()('#input-number').parents('.reverse').addClass('loading');
11720    var params = {
11721      'postal_code': jquery_default()("#input-city").val().split(',')[1],
11722      'street_name': jquery_default()("#input-street").val()
11723    };
11724    jquery_default().ajax({
11725      url: sfrJSVars.ajaxurl,
11726      method: 'POST',
11727      data: {
11728        'action': 'ajaxGetStreetNumbers',
11729        'params': params
11730      },
11731      success: function (data) {
11732        var streetNumbers = JSON.parse(data);
11733        jquery_default()('#input-number').parents('.reverse').removeClass('loading');
11734        jquery_default()("#input-number").prop("disabled", false);
11735        jquery_default()("#input-number").data('defaultval', streetNumbers[
117350]);
11736        jquery_default()('#button-submit').prop("disabled", false);
11737        jquery_default()("#input-number").easyAutocomplete({
11738          data: streetNumbers,
11739          requestDelay: 500,
11740          list: {
11741            match: {
11742              enabled: true
11743            }
11744          },
11745          theme: "square"
11746        });
11747      },
11748      error: function (request, error) {
11749        console.log(error);
11750      }
11751    });
11752  }
11753});
11754function ajaxEligibiliteAddress() {
11755  /* Eligibilité - Appel AJAX pour formulaire adresse - géolocalisation */
11756  jquery_default()('#eligibilite-address-form input, #eligibilite-address-form select').change(function () {
11757    jquery_default()('#eligibilite-address-form').removeClass('error_addr, error_fields');
11758  });
11759  //carrouselInit();
11760  if (document.getElementById('eligibilite-address-form')) {
11761    document.getElementById('eligibilite-address-form').addEventListener('submit', function (e) {
11762      e.preventDefault();
11763      var number = jquery_default()("#input-number").data('defaultval');
11764      if (jquery_default()('#input-number').val() != '') {
11765        jquery_default()('#eac-container-input-number ul li').each(function () {
11766          if (jquery_default()(this).text() == jquery_default()('#input-number').val()) {
11767            number = jquery_default()('#input-number').val();
11768          }
11769        });
11770      }
11771      if (jquery_default()('#input-street').val() != '' && jquery_default()('option:selected', '#input-city').text() != '') {
11772        jquery_default()('#input-lat').val('');
11773        jquery_default()('#input-lon').val('');
11774        jquery_default()('#eligibilite-address-form .button').addClass('loading');
11775        var params = {
11776          'postal_code': jquery_default()("#input-city").val().split(',')[1],
11777          'street_name': jquery_default()("#input-street").val(),
11778          'street_number': number
11779        };
11780        jquery_default().ajax({
11781          url: sfrJSVars.ajaxurl,
11782          method: 'POST',
11783          data: {
11784            'action': 'ajaxGetLatLon',
11785            'params': params
11786          },
11787          success: function (data) {
11788            var streetLatLong = JSON.parse(data);
11789            //console.log(streetLatLong);
11790            jquery_default()('#eligibilite-address-form .button').removeClass('loading');
11791            jquery_default()('#eligibilite-input-address').hide();
11792            jquery_default()('#eligibilite .back').removeClass('masked');
11793            jquery_default()('#eligibilite-map').css('display', 'flex');
11794            eligibiliteMap(streetLatLong.lat, streetLatLong.lon, jquery_default()('#input-number').val(), jquery_default()('#input-street').val(), jquery_default()('option:selected', '#input-city').text());
11795          },
11796          error: function (request, error) {
11797            console.log(error);
11798          }
11799        });
11800      } else {
11801        jquery_default()('#eligibilite-address-form').addClass('error_fields');
11802      }
11803    }, {
11804      passive: false
11805    });
11806  }
11807}
11808function eligibiliteMap(lat, lng, number, street, city) {
11809  var mymap = L.map('eligibilite-mapbox').setView([lat, lng], 17);
11810  L.tileLayer("https://data.geopf.fr/wmts?" + "&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0" + "&STYLE=normal" + "&TILEMATRIXSET=PM" + "&FORMAT=image/jpeg" + "&LAYER=ORTHOIMAGERY.ORTHOPHOTOS" + "&TILEMATRIX={z}" + "&TILEROW={y}" + "&TILECOL={x}", {
11811    minZoom: 12,
11812    maxZoom: 19,
11813    attribution: "IGN-F/Geoportail",
11814    tileSize: 256 // les tuiles du Géooportail font 256x256px
11815  }).addTo(mymap);
11816  var myIcon = L.icon({
11817    iconUrl: sfrJSVars.mapmarker.sizes.large,
11818    iconAnchor: [sfrJSVars.mapmarker.sizes['large-width'] / 2, sfrJSVars.mapmarker.sizes['large-height']]
11819  });
11820  var myMarker = L.marker([lat, lng], {
11821    icon: myIcon
11822  });
11823  myMarker.addTo(mymap);
11824  jquery_default()('#elegibilite-geo-lat').val(lat);
11825  jquery_default()('#elegibilite-geo-lng').val(lng);
11826  mymap.on('click', function (e) {
11827    jquery_default()('#elegibilite-geo-lat').val(e.latlng.lat);
11828    jquery_default()('#elegibilite-geo-lng').val(e.latlng.lng);
11829    myMarker.setLatLng([e.latlng.lat, e.latlng.lng]).update();
11830  });
11831  jquery_default()('#eligibilite .back').unbind().on('click', function () {
11832    mymap.off();
11833    mymap.remove();
11834    jquery_default()('#eligibilite-input-address').css('display', 'flex');
11835    ;
11836    jquery_default()('#eligibilite .back').addClass('masked');
11837    jquery_default()('#eligibilite-map').hide();
11838  });
11839  document.getElementById('form-elegibilite-geo').addEventListener('submit', function (e) {
11840    e.preventDefault();
11841    ajaxEligibiliteResults(jquery_default()('#elegibilite-geo-lat').val(), jquery_default()('#elegibilite-geo-lng').val(), number, street, city);
11842  }, {
11843    passive: false
11844  });
11845}
11846function ajaxEligibiliteResults(lat, lng, number, street, city) {
11847  jquery_default()('#eligibilite-map .button').addClass('loading');
11848  jquery_default().ajax({
11849    url: sfrJSVars.ajaxurl,
11850    method: 'POST',
11851    data: {
11852      'action': 'ajaxEligibiliteResults',
11853      'params': {
11854        lat: lat,
11855        lng: lng,
11856        number: number,
11857        street: street,
11858        city: city
11859      }
11860    },
11861    success: function (data) {
11862      //$('#eligibilite-map .button').removeClass('loading');
11863      if (data == "done") {
11864        window.location.href = sfrJSVars.box_ff_page_link + '#ff';
11865        //console.log(data);
11866      } else {
11867        jquery_default()('#eligibilite-map .button').removeClass('loading');
11868        alert(data);
11869      }
11870    },
11871    error: function (request, error) {
11872      //$('#eligibilite-map .button').removeClass('loading');
11873      console.log(request, error);
11874    }
11875  });
11876}
11877;// ./wp-content/themes/sfrtheme/assets/js/axeptio.js
11878
11879const axeptioOpenSettings = {
11880  automatic: true,
11881  currentStepIndex: 0
11882};
11883const maxOpenAttempts = 40;
11884const openRetryDelayMs = 250;
11885const maxShowButtonAttempts = 6;
11886const showButtonRetryDelayMs = 400;
11887function getAxeptioShadowRoot() {
11888  const host = document.querySelector('.axeptio_mount .needsclick');
11889  return host?.shadowRoot ?? null;
11890}
11891function isAxeptioWidgetVisible() {
11892  const root = getAxeptioShadowRoot();
11893  if (!root) {
11894    return false;
11895  }
11896  return Boolean(root.querySelector('[data-testid="modal-container"], [data-testid="widget-container"], .axeptio_widget'));
11897}
11898function hasDuplicateAxeptioWidgets() {
11899  const root = getAxeptioShadowRoot();
11900  if (!root) {
11901    return false;
11902  }
11903  return root.querySelectorAll('#axeptio_btn_acceptAll').length > 1;
11904}
11905function isAxeptioSdkReady() {
11906  return typeof window.openAxeptioCookies === 'function' || window.axeptioSDK && typeof window.axeptioSDK.openCookies === 'function';
11907}
11908function isAxeptioAutoOpenPending() {
11909  if (window.__axeptioConsentCompleted) {
11910    return false;
11911  }
11912  if (!document.querySelector('.axeptio_mount') || isAxeptioWidgetVisible()) {
11913    return false;
11914  }
11915  return true;
11916}
11917function forceShowAxeptioButton(attempt = 0) {
11918  if (typeof window.showAxeptioButton === 'function') {
11919    window.showAxeptioButton();
11920  }
11921  if (attempt < maxShowButtonAttempts) {
11922    window.setTimeout(() => forceShowAxeptioButton(attempt + 1), showButtonRetryDelayMs);
11923  }
11924}
11925function registerAxeptioConsentTracking() {
11926  window._axcb = window._axcb || [];
11927  window._axcb.push(function (sdk) {
11928    if (!sdk || typeof sdk.on !== 'function') {
11929      return;
11930    }
11931    sdk.on('cookies:complete', function () {
11932      window.__axeptioConsentCompleted = true;
11933      forceShowAxeptioButton();
11934    }, {
11935      replay: true
11936    });
11937  });
11938}
11939function getAxeptioOpenSettings() {
11940  if (window.__axeptioConsentCompleted) {
11941    return {
11942      automatic: true,
11943      currentStepIndex: 1
11944    };
11945  }
11946  return axeptioOpenSettings;
11947}
11948function openAxeptioViaSdk() {
11949  const settings = getAxeptioOpenSettings();
11950  if (typeof window.hideAxeptioButton === 'function') {
11951    window.hideAxeptioButton();
11952  }
11953  if (typeof window.openAxeptioCookies === 'function') {
11954    window.openAxeptioCookies(settings);
11955    return;
11956  }
11957  if (window.axeptioSDK?.openCookies) {
11958    window.axeptioSDK.openCookies(settings);
11959  }
11960}
11961function tryOpenAxeptioPanel(attempt = 0) {
11962  if (isAxeptioWidgetVisible() || hasDuplicateAxeptioWidgets()) {
11963    return;
11964  }
11965  if (!isAxeptioSdkReady()) {
11966    window._axcb = window._axcb || [];
11967    window._axcb.push(() => tryOpenAxeptioPanel(0));
11968    return;
11969  }
11970  if (isAxeptioAutoOpenPending() && attempt < maxOpenAttempts) {
11971    window.setTimeout(() => tryOpenAxeptioPanel(attempt + 1), openRetryDelayMs);
11972    return;
11973  }
11974  if (isAxeptioWidgetVisible() || hasDuplicateAxeptioWidgets()) {
11975    return;
11976  }
11977  openAxeptioViaSdk();
11978}
11979function openAxeptioPanel(event) {
11980  if (event) {
11981    event.preventDefault();
11982  }
11983  tryOpenAxeptioPanel();
11984}
11985registerAxeptioConsentTracking();
11986jquery_default()(document).on('click', '.open-axeptio-cookies', openAxeptioPanel);
11987;// ./node_modules/swiper/shared/ssr-window.esm.mjs
11988/**
11989 * SSR Window 5.0.1
11990 * Better handling for window object in SSR environment
11991 * https://github.com/nolimits4web/ssr-window
11992 *
11993 * Copyright 2025, Vladimir Kharlampidi
11994 *
11995 * Licensed under MIT
11996 *
11997 * Released on: June 27, 2025
11998 */
11999/* eslint-disable no-param-reassign */
12000function ssr_window_esm_isObject(obj) {
12001  return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
12002}
12003function extend(target, src) {
12004  if (target === void 0) {
12005    target = {};
12006  }
12007  if (src === void 0) {
12008    src = {};
12009  }
12010  const noExtend = ['__proto__', 'constructor', 'prototype'];
12011  Object.keys(src).filter(key => noExtend.indexOf(key) < 0).forEach(key => {
12012    if (typeof target[key] === 'undefined') target[key] = src[key];else if (ssr_window_esm_isObject(src[key]) && ssr_window_esm_isObject(target[key]) && Object.keys(src[key]).length > 0) {
12013      extend(target[key], src[key]);
12014    }
12015  });
12016}
12017const ssrDocument = {
12018  body: {},
12019  addEventListener() {},
12020  removeEventListener() {},
12021  activeElement: {
12022    blur() {},
12023    nodeName: ''
12024  },
12025  querySelector() {
12026    return null;
12027  },
12028  querySelectorAll() {
12029    return [];
12030  },
12031  getElementById() {
12032    return null;
12033  },
12034  createEvent() {
12035    return {
12036      initEvent() {}
12037    };
12038  },
12039  createElement() {
12040    return {
12041      children: [],
12042      childNodes: [],
12043      style: {},
12044      setAttribute() {},
12045      getElementsByTagName() {
12046        return [];
12047      }
12048    };
12049  },
12050  createElementNS() {
12051    return {};
12052  },
12053  importNode() {
12054    return null;
12055  },
12056  location: {
12057    hash: '',
12058    host: '',
12059    hostname: '',
12060    href: '',
12061    origin: '',
12062    pathname: '',
12063    protocol: '',
12064    search: ''
12065  }
12066};
12067function ssr_window_esm_getDocument() {
12068  const doc = typeof document !== 'undefined' ? document : {};
12069  extend(doc, ssrDocument);
12070  return doc;
12071}
12072const ssrWindow = {
12073  document: ssrDocument,
12074  navigator: {
12075    userAgent: ''
12076  },
12077  location: {
12078    hash: '',
12079    host: '',
12080    hostname: '',
12081    href: '',
12082    origin: '',
12083    pathname: '',
12084    protocol: '',
12085    search: ''
12086  },
12087  history: {
12088    replaceState() {},
12089    pushState() {},
12090    go() {},
12091    back() {}
12092  },
12093  CustomEvent: function CustomEvent() {
12094    return this;
12095  },
12096  addEventListener() {},
12097  removeEventListener() {},
12098  getComputedStyle() {
12099    return {
12100      getPropertyValue() {
12101        return '';
12102      }
12103    };
12104  },
12105  Image() {},
12106  Date() {},
12107  screen: {},
12108  setTimeout() {},
vendor: 1,033 bytes, lines 12109-12161
12109  clearTimeout() {},
12110  matchMedia() {
12111    return {};
12112  },
12113  requestAnimationFrame(callback) {
12114    if (typeof setTimeout === 'undefined') {
12115      callback();
12116      return null;
12117    }
12118    return setTimeout(callback, 0);
12119  },
12120  cancelAnimationFrame(id) {
12121    if (typeof setTimeout === 'undefined') {
12122      return;
12123    }
12124    clearTimeout(id);
12125  }
12126};
12127function ssr_window_esm_getWindow() {
12128  const win = typeof window !== 'undefined' ? window : {};
12129  extend(win, ssrWindow);
12130  return win;
12131}
12132
12133
12134
12135;// ./node_modules/swiper/shared/utils.mjs
12136
12137
12138function utils_classesToTokens(classes) {
12139  if (classes === void 0) {
12140    classes = '';
12141  }
12142  return classes.trim().split(' ').filter(c => !!c.trim());
12143}
12144
12145function deleteProps(obj) {
12146  const object = obj;
12147  Object.keys(object).forEach(key => {
12148    try {
12149      object[key] = null;
12150    } catch (e) {
12151      // no getter for object
12152    }
12153    try {
12154      delete object[key];
12155    } catch (e) {
12156      // something got wrong
12157    }
12158  });
12159}
12160function utils_nextTick(callback, delay) {
12161  if (delay === void 0) {
vendor: 4,801 bytes, lines 12162-12291
12162    delay = 0;
12163  }
12164  return setTimeout(callback, delay);
12165}
12166function utils_now() {
12167  return Date.now();
12168}
12169function utils_getComputedStyle(el) {
12170  const window = ssr_window_esm_getWindow();
12171  let style;
12172  if (window.getComputedStyle) {
12173    style = window.getComputedStyle(el, null);
12174  }
12175  if (!style && el.currentStyle) {
12176    style = el.currentStyle;
12177  }
12178  if (!style) {
12179    style = el.style;
12180  }
12181  return style;
12182}
12183function utils_getTranslate(el, axis) {
12184  if (axis === void 0) {
12185    axis = 'x';
12186  }
12187  const window = ssr_window_esm_getWindow();
12188  let matrix;
12189  let curTransform;
12190  let transformMatrix;
12191  const curStyle = utils_getComputedStyle(el);
12192  if (window.WebKitCSSMatrix) {
12193    curTransform = curStyle.transform || curStyle.webkitTransform;
12194    if (curTransform.split(',').length > 6) {
12195      curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
12196    }
12197    // Some old versions of Webkit choke when 'none' is passed; pass
12198    // empty string instead in this case
12199    transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
12200  } else {
12201    transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
12202    matrix = transformMatrix.toString().split(',');
12203  }
12204  if (axis === 'x') {
12205    // Latest Chrome and webkits Fix
12206    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
12207    // Crazy IE10 Matrix
12208    else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
12209    // Normal Browsers
12210    else curTransform = parseFloat(matrix[4]);
12211  }
12212  if (axis === 'y') {
12213    // Latest Chrome and webkits Fix
12214    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
12215    // Crazy IE10 Matrix
12216    else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
12217    // Normal Browsers
12218    else curTransform = parseFloat(matrix[5]);
12219  }
12220  return curTransform || 0;
12221}
12222function utils_isObject(o) {
12223  return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
12224}
12225function isNode(node) {
12226  // eslint-disable-next-line
12227  if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
12228    return node instanceof HTMLElement;
12229  }
12230  return node && (node.nodeType === 1 || node.nodeType === 11);
12231}
12232function utils_extend() {
12233  const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
12234  const noExtend = ['__proto__', 'constructor', 'prototype'];
12235  for (let i = 1; i < arguments.length; i += 1) {
12236    const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
12237    if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
12238      const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
12239      for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
12240        const nextKey = keysArray[nextIndex];
12241        const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
12242        if (desc !== undefined && desc.enumerable) {
12243          if (utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) {
12244            if (nextSource[nextKey].__swiper__) {
12245              to[nextKey] = nextSource[nextKey];
12246            } else {
12247              utils_extend(to[nextKey], nextSource[nextKey]);
12248            }
12249          } else if (!utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) {
12250            to[nextKey] = {};
12251            if (nextSource[nextKey].__swiper__) {
12252              to[nextKey] = nextSource[nextKey];
12253            } else {
12254              utils_extend(to[nextKey], nextSource[nextKey]);
12255            }
12256          } else {
12257            to[nextKey] = nextSource[nextKey];
12258          }
12259        }
12260      }
12261    }
12262  }
12263  return to;
12264}
12265function utils_setCSSProperty(el, varName, varValue) {
12266  el.style.setProperty(varName, varValue);
12267}
12268function animateCSSModeScroll(_ref) {
12269  let {
12270    swiper,
12271    targetPosition,
12272    side
12273  } = _ref;
12274  const window = ssr_window_esm_getWindow();
12275  const startPosition = -swiper.translate;
12276  let startTime = null;
12277  let time;
12278  const duration = swiper.params.speed;
12279  swiper.wrapperEl.style.scrollSnapType = 'none';
12280  window.cancelAnimationFrame(swiper.cssModeFrameID);
12281  const dir = targetPosition > startPosition ? 'next' : 'prev';
12282  const isOutOfBound = (current, target) => {
12283    return dir === 'next' && current >= target || dir === 'prev' && current <= target;
12284  };
12285  const animate = () => {
12286    time = new Date().getTime();
12287    if (startTime === null) {
12288      startTime = time;
12289    }
12290    const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
12291    const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
vendor: 6,281 bytes, lines 12292-12492
12292    let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
12293    if (isOutOfBound(currentPosition, targetPosition)) {
12294      currentPosition = targetPosition;
12295    }
12296    swiper.wrapperEl.scrollTo({
12297      [side]: currentPosition
12298    });
12299    if (isOutOfBound(currentPosition, targetPosition)) {
12300      swiper.wrapperEl.style.overflow = 'hidden';
12301      swiper.wrapperEl.style.scrollSnapType = '';
12302      setTimeout(() => {
12303        swiper.wrapperEl.style.overflow = '';
12304        swiper.wrapperEl.scrollTo({
12305          [side]: currentPosition
12306        });
12307      });
12308      window.cancelAnimationFrame(swiper.cssModeFrameID);
12309      return;
12310    }
12311    swiper.cssModeFrameID = window.requestAnimationFrame(animate);
12312  };
12313  animate();
12314}
12315function utils_getSlideTransformEl(slideEl) {
12316  return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl;
12317}
12318function utils_elementChildren(element, selector) {
12319  if (selector === void 0) {
12320    selector = '';
12321  }
12322  const window = ssr_window_esm_getWindow();
12323  const children = [...element.children];
12324  if (window.HTMLSlotElement && element instanceof HTMLSlotElement) {
12325    children.push(...element.assignedElements());
12326  }
12327  if (!selector) {
12328    return children;
12329  }
12330  return children.filter(el => el.matches(selector));
12331}
12332function elementIsChildOfSlot(el, slot) {
12333  // Breadth-first search through all parent's children and assigned elements
12334  const elementsQueue = [slot];
12335  while (elementsQueue.length > 0) {
12336    const elementToCheck = elementsQueue.shift();
12337    if (el === elementToCheck) {
12338      return true;
12339    }
12340    elementsQueue.push(...elementToCheck.children, ...(elementToCheck.shadowRoot ? elementToCheck.shadowRoot.children : []), ...(elementToCheck.assignedElements ? elementToCheck.assignedElements() : []));
12341  }
12342}
12343function elementIsChildOf(el, parent) {
12344  const window = ssr_window_esm_getWindow();
12345  let isChild = parent.contains(el);
12346  if (!isChild && window.HTMLSlotElement && parent instanceof HTMLSlotElement) {
12347    const children = [...parent.assignedElements()];
12348    isChild = children.includes(el);
12349    if (!isChild) {
12350      isChild = elementIsChildOfSlot(el, parent);
12351    }
12352  }
12353  return isChild;
12354}
12355function showWarning(text) {
12356  try {
12357    console.warn(text);
12358    return;
12359  } catch (err) {
12360    // err
12361  }
12362}
12363function utils_createElement(tag, classes) {
12364  if (classes === void 0) {
12365    classes = [];
12366  }
12367  const el = document.createElement(tag);
12368  el.classList.add(...(Array.isArray(classes) ? classes : utils_classesToTokens(classes)));
12369  return el;
12370}
12371function utils_elementOffset(el) {
12372  const window = getWindow();
12373  const document = getDocument();
12374  const box = el.getBoundingClientRect();
12375  const body = document.body;
12376  const clientTop = el.clientTop || body.clientTop || 0;
12377  const clientLeft = el.clientLeft || body.clientLeft || 0;
12378  const scrollTop = el === window ? window.scrollY : el.scrollTop;
12379  const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
12380  return {
12381    top: box.top + scrollTop - clientTop,
12382    left: box.left + scrollLeft - clientLeft
12383  };
12384}
12385function elementPrevAll(el, selector) {
12386  const prevEls = [];
12387  while (el.previousElementSibling) {
12388    const prev = el.previousElementSibling; // eslint-disable-line
12389    if (selector) {
12390      if (prev.matches(selector)) prevEls.push(prev);
12391    } else prevEls.push(prev);
12392    el = prev;
12393  }
12394  return prevEls;
12395}
12396function elementNextAll(el, selector) {
12397  const nextEls = [];
12398  while (el.nextElementSibling) {
12399    const next = el.nextElementSibling; // eslint-disable-line
12400    if (selector) {
12401      if (next.matches(selector)) nextEls.push(next);
12402    } else nextEls.push(next);
12403    el = next;
12404  }
12405  return nextEls;
12406}
12407function elementStyle(el, prop) {
12408  const window = ssr_window_esm_getWindow();
12409  return window.getComputedStyle(el, null).getPropertyValue(prop);
12410}
12411function utils_elementIndex(el) {
12412  let child = el;
12413  let i;
12414  if (child) {
12415    i = 0;
12416    // eslint-disable-next-line
12417    while ((child = child.previousSibling) !== null) {
12418      if (child.nodeType === 1) i += 1;
12419    }
12420    return i;
12421  }
12422  return undefined;
12423}
12424function utils_elementParents(el, selector) {
12425  const parents = []; // eslint-disable-line
12426  let parent = el.parentElement; // eslint-disable-line
12427  while (parent) {
12428    if (selector) {
12429      if (parent.matches(selector)) parents.push(parent);
12430    } else {
12431      parents.push(parent);
12432    }
12433    parent = parent.parentElement;
12434  }
12435  return parents;
12436}
12437function utils_elementTransitionEnd(el, callback) {
12438  function fireCallBack(e) {
12439    if (e.target !== el) return;
12440    callback.call(el, e);
12441    el.removeEventListener('transitionend', fireCallBack);
12442  }
12443  if (callback) {
12444    el.addEventListener('transitionend', fireCallBack);
12445  }
12446}
12447function elementOuterSize(el, size, includeMargins) {
12448  const window = ssr_window_esm_getWindow();
12449  if (includeMargins) {
12450    return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
12451  }
12452  return el.offsetWidth;
12453}
12454function utils_makeElementsArray(el) {
12455  return (Array.isArray(el) ? el : [el]).filter(e => !!e);
12456}
12457function utils_getRotateFix(swiper) {
12458  return v => {
12459    if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) {
12460      return v + 0.001;
12461    }
12462    return v;
12463  };
12464}
12465function utils_setInnerHTML(el, html) {
12466  if (html === void 0) {
12467    html = '';
12468  }
12469  if (typeof trustedTypes !== 'undefined') {
12470    el.innerHTML = trustedTypes.createPolicy('html', {
12471      createHTML: s => s
12472    }).createHTML(html);
12473  } else {
12474    el.innerHTML = html;
12475  }
12476}
12477
12478
12479
12480;// ./node_modules/swiper/shared/swiper-core.mjs
12481
12482
12483
12484let support;
12485function calcSupport() {
12486  const window = ssr_window_esm_getWindow();
12487  const document = ssr_window_esm_getDocument();
12488  return {
12489    smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
12490    touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
12491  };
12492}
vendor: 6,684 bytes, lines 12493-12712
12493function getSupport() {
12494  if (!support) {
12495    support = calcSupport();
12496  }
12497  return support;
12498}
12499
12500let deviceCached;
12501function calcDevice(_temp) {
12502  let {
12503    userAgent
12504  } = _temp === void 0 ? {} : _temp;
12505  const support = getSupport();
12506  const window = ssr_window_esm_getWindow();
12507  const platform = window.navigator.platform;
12508  const ua = userAgent || window.navigator.userAgent;
12509  const device = {
12510    ios: false,
12511    android: false
12512  };
12513  const screenWidth = window.screen.width;
12514  const screenHeight = window.screen.height;
12515  const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
12516  let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
12517  const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
12518  const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
12519  const windows = platform === 'Win32';
12520  let macos = platform === 'MacIntel';
12521
12522  // iPadOs 13 fix
12523  const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
12524  if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
12525    ipad = ua.match(/(Version)\/([\d.]+)/);
12526    if (!ipad) ipad = [0, 1, '13_0_0'];
12527    macos = false;
12528  }
12529
12530  // Android
12531  if (android && !windows) {
12532    device.os = 'android';
12533    device.android = true;
12534  }
12535  if (ipad || iphone || ipod) {
12536    device.os = 'ios';
12537    device.ios = true;
12538  }
12539
12540  // Export object
12541  return device;
12542}
12543function getDevice(overrides) {
12544  if (overrides === void 0) {
12545    overrides = {};
12546  }
12547  if (!deviceCached) {
12548    deviceCached = calcDevice(overrides);
12549  }
12550  return deviceCached;
12551}
12552
12553let browser;
12554function calcBrowser() {
12555  const window = ssr_window_esm_getWindow();
12556  const device = getDevice();
12557  let needPerspectiveFix = false;
12558  function isSafari() {
12559    const ua = window.navigator.userAgent.toLowerCase();
12560    return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
12561  }
12562  if (isSafari()) {
12563    const ua = String(window.navigator.userAgent);
12564    if (ua.includes('Version/')) {
12565      const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
12566      needPerspectiveFix = major < 16 || major === 16 && minor < 2;
12567    }
12568  }
12569  const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
12570  const isSafariBrowser = isSafari();
12571  const need3dFix = isSafariBrowser || isWebView && device.ios;
12572  return {
12573    isSafari: needPerspectiveFix || isSafariBrowser,
12574    needPerspectiveFix,
12575    need3dFix,
12576    isWebView
12577  };
12578}
12579function getBrowser() {
12580  if (!browser) {
12581    browser = calcBrowser();
12582  }
12583  return browser;
12584}
12585
12586function Resize(_ref) {
12587  let {
12588    swiper,
12589    on,
12590    emit
12591  } = _ref;
12592  const window = ssr_window_esm_getWindow();
12593  let observer = null;
12594  let animationFrame = null;
12595  const resizeHandler = () => {
12596    if (!swiper || swiper.destroyed || !swiper.initialized) return;
12597    emit('beforeResize');
12598    emit('resize');
12599  };
12600  const createObserver = () => {
12601    if (!swiper || swiper.destroyed || !swiper.initialized) return;
12602    observer = new ResizeObserver(entries => {
12603      animationFrame = window.requestAnimationFrame(() => {
12604        const {
12605          width,
12606          height
12607        } = swiper;
12608        let newWidth = width;
12609        let newHeight = height;
12610        entries.forEach(_ref2 => {
12611          let {
12612            contentBoxSize,
12613            contentRect,
12614            target
12615          } = _ref2;
12616          if (target && target !== swiper.el) return;
12617          newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
12618          newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
12619        });
12620        if (newWidth !== width || newHeight !== height) {
12621          resizeHandler();
12622        }
12623      });
12624    });
12625    observer.observe(swiper.el);
12626  };
12627  const removeObserver = () => {
12628    if (animationFrame) {
12629      window.cancelAnimationFrame(animationFrame);
12630    }
12631    if (observer && observer.unobserve && swiper.el) {
12632      observer.unobserve(swiper.el);
12633      observer = null;
12634    }
12635  };
12636  const orientationChangeHandler = () => {
12637    if (!swiper || swiper.destroyed || !swiper.initialized) return;
12638    emit('orientationchange');
12639  };
12640  on('init', () => {
12641    if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
12642      createObserver();
12643      return;
12644    }
12645    window.addEventListener('resize', resizeHandler);
12646    window.addEventListener('orientationchange', orientationChangeHandler);
12647  });
12648  on('destroy', () => {
12649    removeObserver();
12650    window.removeEventListener('resize', resizeHandler);
12651    window.removeEventListener('orientationchange', orientationChangeHandler);
12652  });
12653}
12654
12655function Observer(_ref) {
12656  let {
12657    swiper,
12658    extendParams,
12659    on,
12660    emit
12661  } = _ref;
12662  const observers = [];
12663  const window = ssr_window_esm_getWindow();
12664  const attach = function (target, options) {
12665    if (options === void 0) {
12666      options = {};
12667    }
12668    const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
12669    const observer = new ObserverFunc(mutations => {
12670      // The observerUpdate event should only be triggered
12671      // once despite the number of mutations.  Additional
12672      // triggers are redundant and are very costly
12673      if (swiper.__preventObserver__) return;
12674      if (mutations.length === 1) {
12675        emit('observerUpdate', mutations[0]);
12676        return;
12677      }
12678      const observerUpdate = function observerUpdate() {
12679        emit('observerUpdate', mutations[0]);
12680      };
12681      if (window.requestAnimationFrame) {
12682        window.requestAnimationFrame(observerUpdate);
12683      } else {
12684        window.setTimeout(observerUpdate, 0);
12685      }
12686    });
12687    observer.observe(target, {
12688      attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
12689      childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList,
12690      characterData: typeof options.characterData === 'undefined' ? true : options.characterData
12691    });
12692    observers.push(observer);
12693  };
12694  const init = () => {
12695    if (!swiper.params.observer) return;
12696    if (swiper.params.observeParents) {
12697      const containerParents = utils_elementParents(swiper.hostEl);
12698      for (let i = 0; i < containerParents.length; i += 1) {
12699        attach(containerParents[i]);
12700      }
12701    }
12702    // Observe container
12703    attach(swiper.hostEl, {
12704      childList: swiper.params.observeSlideChildren
12705    });
12706
12707    // Observe wrapper
12708    attach(swiper.wrapperEl, {
12709      attributes: false
12710    });
12711  };
12712  const destroy = () => {
vendor: 5,654 bytes, lines 12713-12884
12713    observers.forEach(observer => {
12714      observer.disconnect();
12715    });
12716    observers.splice(0, observers.length);
12717  };
12718  extendParams({
12719    observer: false,
12720    observeParents: false,
12721    observeSlideChildren: false
12722  });
12723  on('init', init);
12724  on('destroy', destroy);
12725}
12726
12727/* eslint-disable no-underscore-dangle */
12728
12729var eventsEmitter = {
12730  on(events, handler, priority) {
12731    const self = this;
12732    if (!self.eventsListeners || self.destroyed) return self;
12733    if (typeof handler !== 'function') return self;
12734    const method = priority ? 'unshift' : 'push';
12735    events.split(' ').forEach(event => {
12736      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
12737      self.eventsListeners[event][method](handler);
12738    });
12739    return self;
12740  },
12741  once(events, handler, priority) {
12742    const self = this;
12743    if (!self.eventsListeners || self.destroyed) return self;
12744    if (typeof handler !== 'function') return self;
12745    function onceHandler() {
12746      self.off(events, onceHandler);
12747      if (onceHandler.__emitterProxy) {
12748        delete onceHandler.__emitterProxy;
12749      }
12750      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
12751        args[_key] = arguments[_key];
12752      }
12753      handler.apply(self, args);
12754    }
12755    onceHandler.__emitterProxy = handler;
12756    return self.on(events, onceHandler, priority);
12757  },
12758  onAny(handler, priority) {
12759    const self = this;
12760    if (!self.eventsListeners || self.destroyed) return self;
12761    if (typeof handler !== 'function') return self;
12762    const method = priority ? 'unshift' : 'push';
12763    if (self.eventsAnyListeners.indexOf(handler) < 0) {
12764      self.eventsAnyListeners[method](handler);
12765    }
12766    return self;
12767  },
12768  offAny(handler) {
12769    const self = this;
12770    if (!self.eventsListeners || self.destroyed) return self;
12771    if (!self.eventsAnyListeners) return self;
12772    const index = self.eventsAnyListeners.indexOf(handler);
12773    if (index >= 0) {
12774      self.eventsAnyListeners.splice(index, 1);
12775    }
12776    return self;
12777  },
12778  off(events, handler) {
12779    const self = this;
12780    if (!self.eventsListeners || self.destroyed) return self;
12781    if (!self.eventsListeners) return self;
12782    events.split(' ').forEach(event => {
12783      if (typeof handler === 'undefined') {
12784        self.eventsListeners[event] = [];
12785      } else if (self.eventsListeners[event]) {
12786        self.eventsListeners[event].forEach((eventHandler, index) => {
12787          if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
12788            self.eventsListeners[event].splice(index, 1);
12789          }
12790        });
12791      }
12792    });
12793    return self;
12794  },
12795  emit() {
12796    const self = this;
12797    if (!self.eventsListeners || self.destroyed) return self;
12798    if (!self.eventsListeners) return self;
12799    let events;
12800    let data;
12801    let context;
12802    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
12803      args[_key2] = arguments[_key2];
12804    }
12805    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
12806      events = args[0];
12807      data = args.slice(1, args.length);
12808      context = self;
12809    } else {
12810      events = args[0].events;
12811      data = args[0].data;
12812      context = args[0].context || self;
12813    }
12814    data.unshift(context);
12815    const eventsArray = Array.isArray(events) ? events : events.split(' ');
12816    eventsArray.forEach(event => {
12817      if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
12818        self.eventsAnyListeners.forEach(eventHandler => {
12819          eventHandler.apply(context, [event, ...data]);
12820        });
12821      }
12822      if (self.eventsListeners && self.eventsListeners[event]) {
12823        self.eventsListeners[event].forEach(eventHandler => {
12824          eventHandler.apply(context, data);
12825        });
12826      }
12827    });
12828    return self;
12829  }
12830};
12831
12832function updateSize() {
12833  const swiper = this;
12834  let width;
12835  let height;
12836  const el = swiper.el;
12837  if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
12838    width = swiper.params.width;
12839  } else {
12840    width = el.clientWidth;
12841  }
12842  if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
12843    height = swiper.params.height;
12844  } else {
12845    height = el.clientHeight;
12846  }
12847  if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
12848    return;
12849  }
12850
12851  // Subtract paddings
12852  width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
12853  height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
12854  if (Number.isNaN(width)) width = 0;
12855  if (Number.isNaN(height)) height = 0;
12856  Object.assign(swiper, {
12857    width,
12858    height,
12859    size: swiper.isHorizontal() ? width : height
12860  });
12861}
12862
12863function updateSlides() {
12864  const swiper = this;
12865  function getDirectionPropertyValue(node, label) {
12866    return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
12867  }
12868  const params = swiper.params;
12869  const {
12870    wrapperEl,
12871    slidesEl,
12872    size: swiperSize,
12873    rtlTranslate: rtl,
12874    wrongRTL
12875  } = swiper;
12876  const isVirtual = swiper.virtual && params.virtual.enabled;
12877  const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
12878  const slides = utils_elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
12879  const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
12880  let snapGrid = [];
12881  const slidesGrid = [];
12882  const slidesSizesGrid = [];
12883  let offsetBefore = params.slidesOffsetBefore;
12884  if (typeof offsetBefore === 'function') {
vendor: 7,357 bytes, lines 12885-13065
12885    offsetBefore = params.slidesOffsetBefore.call(swiper);
12886  }
12887  let offsetAfter = params.slidesOffsetAfter;
12888  if (typeof offsetAfter === 'function') {
12889    offsetAfter = params.slidesOffsetAfter.call(swiper);
12890  }
12891  const previousSnapGridLength = swiper.snapGrid.length;
12892  const previousSlidesGridLength = swiper.slidesGrid.length;
12893  let spaceBetween = params.spaceBetween;
12894  let slidePosition = -offsetBefore;
12895  let prevSlideSize = 0;
12896  let index = 0;
12897  if (typeof swiperSize === 'undefined') {
12898    return;
12899  }
12900  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
12901    spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
12902  } else if (typeof spaceBetween === 'string') {
12903    spaceBetween = parseFloat(spaceBetween);
12904  }
12905  swiper.virtualSize = -spaceBetween;
12906
12907  // reset margins
12908  slides.forEach(slideEl => {
12909    if (rtl) {
12910      slideEl.style.marginLeft = '';
12911    } else {
12912      slideEl.style.marginRight = '';
12913    }
12914    slideEl.style.marginBottom = '';
12915    slideEl.style.marginTop = '';
12916  });
12917
12918  // reset cssMode offsets
12919  if (params.centeredSlides && params.cssMode) {
12920    utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
12921    utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
12922  }
12923  const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
12924  if (gridEnabled) {
12925    swiper.grid.initSlides(slides);
12926  } else if (swiper.grid) {
12927    swiper.grid.unsetSlides();
12928  }
12929
12930  // Calc slides
12931  let slideSize;
12932  const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
12933    return typeof params.breakpoints[key].slidesPerView !== 'undefined';
12934  }).length > 0;
12935  for (let i = 0; i < slidesLength; i += 1) {
12936    slideSize = 0;
12937    let slide;
12938    if (slides[i]) slide = slides[i];
12939    if (gridEnabled) {
12940      swiper.grid.updateSlide(i, slide, slides);
12941    }
12942    if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
12943
12944    if (params.slidesPerView === 'auto') {
12945      if (shouldResetSlideSize) {
12946        slides[i].style[swiper.getDirectionLabel('width')] = ``;
12947      }
12948      const slideStyles = getComputedStyle(slide);
12949      const currentTransform = slide.style.transform;
12950      const currentWebKitTransform = slide.style.webkitTransform;
12951      if (currentTransform) {
12952        slide.style.transform = 'none';
12953      }
12954      if (currentWebKitTransform) {
12955        slide.style.webkitTransform = 'none';
12956      }
12957      if (params.roundLengths) {
12958        slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
12959      } else {
12960        // eslint-disable-next-line
12961        const width = getDirectionPropertyValue(slideStyles, 'width');
12962        const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
12963        const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
12964        const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
12965        const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
12966        const boxSizing = slideStyles.getPropertyValue('box-sizing');
12967        if (boxSizing && boxSizing === 'border-box') {
12968          slideSize = width + marginLeft + marginRight;
12969        } else {
12970          const {
12971            clientWidth,
12972            offsetWidth
12973          } = slide;
12974          slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
12975        }
12976      }
12977      if (currentTransform) {
12978        slide.style.transform = currentTransform;
12979      }
12980      if (currentWebKitTransform) {
12981        slide.style.webkitTransform = currentWebKitTransform;
12982      }
12983      if (params.roundLengths) slideSize = Math.floor(slideSize);
12984    } else {
12985      slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
12986      if (params.roundLengths) slideSize = Math.floor(slideSize);
12987      if (slides[i]) {
12988        slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
12989      }
12990    }
12991    if (slides[i]) {
12992      slides[i].swiperSlideSize = slideSize;
12993    }
12994    slidesSizesGrid.push(slideSize);
12995    if (params.centeredSlides) {
12996      slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
12997      if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
12998      if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
12999      if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
13000      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
13001      if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
13002      slidesGrid.push(slidePosition);
13003    } else {
13004      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
13005      if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
13006      slidesGrid.push(slidePosition);
13007      slidePosition = slidePosition + slideSize + spaceBetween;
13008    }
13009    swiper.virtualSize += slideSize + spaceBetween;
13010    prevSlideSize = slideSize;
13011    index += 1;
13012  }
13013  swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
13014  if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
13015    wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
13016  }
13017  if (params.setWrapperSize) {
13018    wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
13019  }
13020  if (gridEnabled) {
13021    swiper.grid.updateWrapperSize(slideSize, snapGrid);
13022  }
13023
13024  // Remove last grid elements depending on width
13025  if (!params.centeredSlides) {
13026    const newSlidesGrid = [];
13027    for (let i = 0; i < snapGrid.length; i += 1) {
13028      let slidesGridItem = snapGrid[i];
13029      if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
13030      if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
13031        newSlidesGrid.push(slidesGridItem);
13032      }
13033    }
13034    snapGrid = newSlidesGrid;
13035    if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
13036      snapGrid.push(swiper.virtualSize - swiperSize);
13037    }
13038  }
13039  if (isVirtual && params.loop) {
13040    const size = slidesSizesGrid[0] + spaceBetween;
13041    if (params.slidesPerGroup > 1) {
13042      const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
13043      const groupSize = size * params.slidesPerGroup;
13044      for (let i = 0; i < groups; i += 1) {
13045        snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
13046      }
13047    }
13048    for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
13049      if (params.slidesPerGroup === 1) {
13050        snapGrid.push(snapGrid[snapGrid.length - 1] + size);
13051      }
13052      slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
13053      swiper.virtualSize += size;
13054    }
13055  }
13056  if (snapGrid.length === 0) snapGrid = [0];
13057  if (spaceBetween !== 0) {
13058    const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
13059    slides.filter((_, slideIndex) => {
13060      if (!params.cssMode || params.loop) return true;
13061      if (slideIndex === slides.length - 1) {
13062        return false;
13063      }
13064      return true;
13065    }
vendor: 3,541 bytes, lines 13065-13157
13065).forEach(slideEl => {
13066      slideEl.style[key] = `${spaceBetween}px`;
13067    });
13068  }
13069  if (params.centeredSlides && params.centeredSlidesBounds) {
13070    let allSlidesSize = 0;
13071    slidesSizesGrid.forEach(slideSizeValue => {
13072      allSlidesSize += slideSizeValue + (spaceBetween || 0);
13073    });
13074    allSlidesSize -= spaceBetween;
13075    const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0;
13076    snapGrid = snapGrid.map(snap => {
13077      if (snap <= 0) return -offsetBefore;
13078      if (snap > maxSnap) return maxSnap + offsetAfter;
13079      return snap;
13080    });
13081  }
13082  if (params.centerInsufficientSlides) {
13083    let allSlidesSize = 0;
13084    slidesSizesGrid.forEach(slideSizeValue => {
13085      allSlidesSize += slideSizeValue + (spaceBetween || 0);
13086    });
13087    allSlidesSize -= spaceBetween;
13088    const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
13089    if (allSlidesSize + offsetSize < swiperSize) {
13090      const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
13091      snapGrid.forEach((snap, snapIndex) => {
13092        snapGrid[snapIndex] = snap - allSlidesOffset;
13093      });
13094      slidesGrid.forEach((snap, snapIndex) => {
13095        slidesGrid[snapIndex] = snap + allSlidesOffset;
13096      });
13097    }
13098  }
13099  Object.assign(swiper, {
13100    slides,
13101    snapGrid,
13102    slidesGrid,
13103    slidesSizesGrid
13104  });
13105  if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
13106    utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
13107    utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
13108    const addToSnapGrid = -swiper.snapGrid[0];
13109    const addToSlidesGrid = -swiper.slidesGrid[0];
13110    swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
13111    swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
13112  }
13113  if (slidesLength !== previousSlidesLength) {
13114    swiper.emit('slidesLengthChange');
13115  }
13116  if (snapGrid.length !== previousSnapGridLength) {
13117    if (swiper.params.watchOverflow) swiper.checkOverflow();
13118    swiper.emit('snapGridLengthChange');
13119  }
13120  if (slidesGrid.length !== previousSlidesGridLength) {
13121    swiper.emit('slidesGridLengthChange');
13122  }
13123  if (params.watchSlidesProgress) {
13124    swiper.updateSlidesOffset();
13125  }
13126  swiper.emit('slidesUpdated');
13127  if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
13128    const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
13129    const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
13130    if (slidesLength <= params.maxBackfaceHiddenSlides) {
13131      if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
13132    } else if (hasClassBackfaceClassAdded) {
13133      swiper.el.classList.remove(backFaceHiddenClass);
13134    }
13135  }
13136}
13137
13138function updateAutoHeight(speed) {
13139  const swiper = this;
13140  const activeSlides = [];
13141  const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
13142  let newHeight = 0;
13143  let i;
13144  if (typeof speed === 'number') {
13145    swiper.setTransition(speed);
13146  } else if (speed === true) {
13147    swiper.setTransition(swiper.params.speed);
13148  }
13149  const getSlideByIndex = index => {
13150    if (isVirtual) {
13151      return swiper.slides[swiper.getSlideIndexByData(index)];
13152    }
13153    return swiper.slides[index];
13154  };
13155  // Find slides currently in view
13156  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
13157    if (swiper.params.centeredSlides) {
vendor: 3,398 bytes, lines 13158-13239
13158      (swiper.visibleSlides || []).forEach(slide => {
13159        activeSlides.push(slide);
13160      });
13161    } else {
13162      for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
13163        const index = swiper.activeIndex + i;
13164        if (index > swiper.slides.length && !isVirtual) break;
13165        activeSlides.push(getSlideByIndex(index));
13166      }
13167    }
13168  } else {
13169    activeSlides.push(getSlideByIndex(swiper.activeIndex));
13170  }
13171
13172  // Find new height from highest slide in view
13173  for (i = 0; i < activeSlides.length; i += 1) {
13174    if (typeof activeSlides[i] !== 'undefined') {
13175      const height = activeSlides[i].offsetHeight;
13176      newHeight = height > newHeight ? height : newHeight;
13177    }
13178  }
13179
13180  // Update Height
13181  if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
13182}
13183
13184function updateSlidesOffset() {
13185  const swiper = this;
13186  const slides = swiper.slides;
13187  // eslint-disable-next-line
13188  const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
13189  for (let i = 0; i < slides.length; i += 1) {
13190    slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
13191  }
13192}
13193
13194const toggleSlideClasses$1 = (slideEl, condition, className) => {
13195  if (condition && !slideEl.classList.contains(className)) {
13196    slideEl.classList.add(className);
13197  } else if (!condition && slideEl.classList.contains(className)) {
13198    slideEl.classList.remove(className);
13199  }
13200};
13201function updateSlidesProgress(translate) {
13202  if (translate === void 0) {
13203    translate = this && this.translate || 0;
13204  }
13205  const swiper = this;
13206  const params = swiper.params;
13207  const {
13208    slides,
13209    rtlTranslate: rtl,
13210    snapGrid
13211  } = swiper;
13212  if (slides.length === 0) return;
13213  if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
13214  let offsetCenter = -translate;
13215  if (rtl) offsetCenter = translate;
13216  swiper.visibleSlidesIndexes = [];
13217  swiper.visibleSlides = [];
13218  let spaceBetween = params.spaceBetween;
13219  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
13220    spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
13221  } else if (typeof spaceBetween === 'string') {
13222    spaceBetween = parseFloat(spaceBetween);
13223  }
13224  for (let i = 0; i < slides.length; i += 1) {
13225    const slide = slides[i];
13226    let slideOffset = slide.swiperSlideOffset;
13227    if (params.cssMode && params.centeredSlides) {
13228      slideOffset -= slides[0].swiperSlideOffset;
13229    }
13230    const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
13231    const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
13232    const slideBefore = -(offsetCenter - slideOffset);
13233    const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
13234    const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
13235    const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
13236    if (isVisible) {
13237      swiper.visibleSlides.push(slide);
13238      swiper.visibleSlidesIndexes.push(i);
13239    }
vendor: 11,267 bytes, lines 13240-13552
13240    toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
13241    toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
13242    slide.progress = rtl ? -slideProgress : slideProgress;
13243    slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
13244  }
13245}
13246
13247function updateProgress(translate) {
13248  const swiper = this;
13249  if (typeof translate === 'undefined') {
13250    const multiplier = swiper.rtlTranslate ? -1 : 1;
13251    // eslint-disable-next-line
13252    translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
13253  }
13254  const params = swiper.params;
13255  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
13256  let {
13257    progress,
13258    isBeginning,
13259    isEnd,
13260    progressLoop
13261  } = swiper;
13262  const wasBeginning = isBeginning;
13263  const wasEnd = isEnd;
13264  if (translatesDiff === 0) {
13265    progress = 0;
13266    isBeginning = true;
13267    isEnd = true;
13268  } else {
13269    progress = (translate - swiper.minTranslate()) / translatesDiff;
13270    const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
13271    const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
13272    isBeginning = isBeginningRounded || progress <= 0;
13273    isEnd = isEndRounded || progress >= 1;
13274    if (isBeginningRounded) progress = 0;
13275    if (isEndRounded) progress = 1;
13276  }
13277  if (params.loop) {
13278    const firstSlideIndex = swiper.getSlideIndexByData(0);
13279    const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
13280    const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
13281    const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
13282    const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
13283    const translateAbs = Math.abs(translate);
13284    if (translateAbs >= firstSlideTranslate) {
13285      progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
13286    } else {
13287      progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
13288    }
13289    if (progressLoop > 1) progressLoop -= 1;
13290  }
13291  Object.assign(swiper, {
13292    progress,
13293    progressLoop,
13294    isBeginning,
13295    isEnd
13296  });
13297  if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
13298  if (isBeginning && !wasBeginning) {
13299    swiper.emit('reachBeginning toEdge');
13300  }
13301  if (isEnd && !wasEnd) {
13302    swiper.emit('reachEnd toEdge');
13303  }
13304  if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
13305    swiper.emit('fromEdge');
13306  }
13307  swiper.emit('progress', progress);
13308}
13309
13310const toggleSlideClasses = (slideEl, condition, className) => {
13311  if (condition && !slideEl.classList.contains(className)) {
13312    slideEl.classList.add(className);
13313  } else if (!condition && slideEl.classList.contains(className)) {
13314    slideEl.classList.remove(className);
13315  }
13316};
13317function updateSlidesClasses() {
13318  const swiper = this;
13319  const {
13320    slides,
13321    params,
13322    slidesEl,
13323    activeIndex
13324  } = swiper;
13325  const isVirtual = swiper.virtual && params.virtual.enabled;
13326  const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
13327  const getFilteredSlide = selector => {
13328    return utils_elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
13329  };
13330  let activeSlide;
13331  let prevSlide;
13332  let nextSlide;
13333  if (isVirtual) {
13334    if (params.loop) {
13335      let slideIndex = activeIndex - swiper.virtual.slidesBefore;
13336      if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
13337      if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
13338      activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
13339    } else {
13340      activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
13341    }
13342  } else {
13343    if (gridEnabled) {
13344      activeSlide = slides.find(slideEl => slideEl.column === activeIndex);
13345      nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1);
13346      prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1);
13347    } else {
13348      activeSlide = slides[activeIndex];
13349    }
13350  }
13351  if (activeSlide) {
13352    if (!gridEnabled) {
13353      // Next Slide
13354      nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
13355      if (params.loop && !nextSlide) {
13356        nextSlide = slides[0];
13357      }
13358
13359      // Prev Slide
13360      prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
13361      if (params.loop && !prevSlide === 0) {
13362        prevSlide = slides[slides.length - 1];
13363      }
13364    }
13365  }
13366  slides.forEach(slideEl => {
13367    toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
13368    toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
13369    toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
13370  });
13371  swiper.emitSlidesClasses();
13372}
13373
13374const processLazyPreloader = (swiper, imageEl) => {
13375  if (!swiper || swiper.destroyed || !swiper.params) return;
13376  const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
13377  const slideEl = imageEl.closest(slideSelector());
13378  if (slideEl) {
13379    let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13380    if (!lazyEl && swiper.isElement) {
13381      if (slideEl.shadowRoot) {
13382        lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13383      } else {
13384        // init later
13385        requestAnimationFrame(() => {
13386          if (slideEl.shadowRoot) {
13387            lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13388            if (lazyEl) lazyEl.remove();
13389          }
13390        });
13391      }
13392    }
13393    if (lazyEl) lazyEl.remove();
13394  }
13395};
13396const unlazy = (swiper, index) => {
13397  if (!swiper.slides[index]) return;
13398  const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
13399  if (imageEl) imageEl.removeAttribute('loading');
13400};
13401const preload = swiper => {
13402  if (!swiper || swiper.destroyed || !swiper.params) return;
13403  let amount = swiper.params.lazyPreloadPrevNext;
13404  const len = swiper.slides.length;
13405  if (!len || !amount || amount < 0) return;
13406  amount = Math.min(amount, len);
13407  const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
13408  const activeIndex = swiper.activeIndex;
13409  if (swiper.params.grid && swiper.params.grid.rows > 1) {
13410    const activeColumn = activeIndex;
13411    const preloadColumns = [activeColumn - amount];
13412    preloadColumns.push(...Array.from({
13413      length: amount
13414    }).map((_, i) => {
13415      return activeColumn + slidesPerView + i;
13416    }));
13417    swiper.slides.forEach((slideEl, i) => {
13418      if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
13419    });
13420    return;
13421  }
13422  const slideIndexLastInView = activeIndex + slidesPerView - 1;
13423  if (swiper.params.rewind || swiper.params.loop) {
13424    for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
13425      const realIndex = (i % len + len) % len;
13426      if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
13427    }
13428  } else {
13429    for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
13430      if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
13431        unlazy(swiper, i);
13432      }
13433    }
13434  }
13435};
13436
13437function getActiveIndexByTranslate(swiper) {
13438  const {
13439    slidesGrid,
13440    params
13441  } = swiper;
13442  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
13443  let activeIndex;
13444  for (let i = 0; i < slidesGrid.length; i += 1) {
13445    if (typeof slidesGrid[i + 1] !== 'undefined') {
13446      if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
13447        activeIndex = i;
13448      } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
13449        activeIndex = i + 1;
13450      }
13451    } else if (translate >= slidesGrid[i]) {
13452      activeIndex = i;
13453    }
13454  }
13455  // Normalize slideIndex
13456  if (params.normalizeSlideIndex) {
13457    if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
13458  }
13459  return activeIndex;
13460}
13461function updateActiveIndex(newActiveIndex) {
13462  const swiper = this;
13463  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
13464  const {
13465    snapGrid,
13466    params,
13467    activeIndex: previousIndex,
13468    realIndex: previousRealIndex,
13469    snapIndex: previousSnapIndex
13470  } = swiper;
13471  let activeIndex = newActiveIndex;
13472  let snapIndex;
13473  const getVirtualRealIndex = aIndex => {
13474    let realIndex = aIndex - swiper.virtual.slidesBefore;
13475    if (realIndex < 0) {
13476      realIndex = swiper.virtual.slides.length + realIndex;
13477    }
13478    if (realIndex >= swiper.virtual.slides.length) {
13479      realIndex -= swiper.virtual.slides.length;
13480    }
13481    return realIndex;
13482  };
13483  if (typeof activeIndex === 'undefined') {
13484    activeIndex = getActiveIndexByTranslate(swiper);
13485  }
13486  if (snapGrid.indexOf(translate) >= 0) {
13487    snapIndex = snapGrid.indexOf(translate);
13488  } else {
13489    const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
13490    snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
13491  }
13492  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
13493  if (activeIndex === previousIndex && !swiper.params.loop) {
13494    if (snapIndex !== previousSnapIndex) {
13495      swiper.snapIndex = snapIndex;
13496      swiper.emit('snapIndexChange');
13497    }
13498    return;
13499  }
13500  if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
13501    swiper.realIndex = getVirtualRealIndex(activeIndex);
13502    return;
13503  }
13504  const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
13505
13506  // Get real index
13507  let realIndex;
13508  if (swiper.virtual && params.virtual.enabled && params.loop) {
13509    realIndex = getVirtualRealIndex(activeIndex);
13510  } else if (gridEnabled) {
13511    const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex);
13512    let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
13513    if (Number.isNaN(activeSlideIndex)) {
13514      activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
13515    }
13516    realIndex = Math.floor(activeSlideIndex / params.grid.rows);
13517  } else if (swiper.slides[activeIndex]) {
13518    const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
13519    if (slideIndex) {
13520      realIndex = parseInt(slideIndex, 10);
13521    } else {
13522      realIndex = activeIndex;
13523    }
13524  } else {
13525    realIndex = activeIndex;
13526  }
13527  Object.assign(swiper, {
13528    previousSnapIndex,
13529    snapIndex,
13530    previousRealIndex,
13531    realIndex,
13532    previousIndex,
13533    activeIndex
13534  });
13535  if (swiper.initialized) {
13536    preload(swiper);
13537  }
13538  swiper.emit('activeIndexChange');
13539  swiper.emit('snapIndexChange');
13540  if (swiper.initialized || swiper.params.runCallbacksOnInit) {
13541    if (previousRealIndex !== realIndex) {
13542      swiper.emit('realIndexChange');
13543    }
13544    swiper.emit('slideChange');
13545  }
13546}
13547
13548function updateClickedSlide(el, path) {
13549  const swiper = this;
13550  const params = swiper.params;
13551  let slide = el.closest(`.${params.slideClass}, swiper-slide`);
13552  if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
vendor: 14,247 bytes, lines 13553-14038
13553    [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
13554      if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
13555        slide = pathEl;
13556      }
13557    });
13558  }
13559  let slideFound = false;
13560  let slideIndex;
13561  if (slide) {
13562    for (let i = 0; i < swiper.slides.length; i += 1) {
13563      if (swiper.slides[i] === slide) {
13564        slideFound = true;
13565        slideIndex = i;
13566        break;
13567      }
13568    }
13569  }
13570  if (slide && slideFound) {
13571    swiper.clickedSlide = slide;
13572    if (swiper.virtual && swiper.params.virtual.enabled) {
13573      swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
13574    } else {
13575      swiper.clickedIndex = slideIndex;
13576    }
13577  } else {
13578    swiper.clickedSlide = undefined;
13579    swiper.clickedIndex = undefined;
13580    return;
13581  }
13582  if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
13583    swiper.slideToClickedSlide();
13584  }
13585}
13586
13587var update = {
13588  updateSize,
13589  updateSlides,
13590  updateAutoHeight,
13591  updateSlidesOffset,
13592  updateSlidesProgress,
13593  updateProgress,
13594  updateSlidesClasses,
13595  updateActiveIndex,
13596  updateClickedSlide
13597};
13598
13599function getSwiperTranslate(axis) {
13600  if (axis === void 0) {
13601    axis = this.isHorizontal() ? 'x' : 'y';
13602  }
13603  const swiper = this;
13604  const {
13605    params,
13606    rtlTranslate: rtl,
13607    translate,
13608    wrapperEl
13609  } = swiper;
13610  if (params.virtualTranslate) {
13611    return rtl ? -translate : translate;
13612  }
13613  if (params.cssMode) {
13614    return translate;
13615  }
13616  let currentTranslate = utils_getTranslate(wrapperEl, axis);
13617  currentTranslate += swiper.cssOverflowAdjustment();
13618  if (rtl) currentTranslate = -currentTranslate;
13619  return currentTranslate || 0;
13620}
13621
13622function setTranslate(translate, byController) {
13623  const swiper = this;
13624  const {
13625    rtlTranslate: rtl,
13626    params,
13627    wrapperEl,
13628    progress
13629  } = swiper;
13630  let x = 0;
13631  let y = 0;
13632  const z = 0;
13633  if (swiper.isHorizontal()) {
13634    x = rtl ? -translate : translate;
13635  } else {
13636    y = translate;
13637  }
13638  if (params.roundLengths) {
13639    x = Math.floor(x);
13640    y = Math.floor(y);
13641  }
13642  swiper.previousTranslate = swiper.translate;
13643  swiper.translate = swiper.isHorizontal() ? x : y;
13644  if (params.cssMode) {
13645    wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
13646  } else if (!params.virtualTranslate) {
13647    if (swiper.isHorizontal()) {
13648      x -= swiper.cssOverflowAdjustment();
13649    } else {
13650      y -= swiper.cssOverflowAdjustment();
13651    }
13652    wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
13653  }
13654
13655  // Check if we need to update progress
13656  let newProgress;
13657  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
13658  if (translatesDiff === 0) {
13659    newProgress = 0;
13660  } else {
13661    newProgress = (translate - swiper.minTranslate()) / translatesDiff;
13662  }
13663  if (newProgress !== progress) {
13664    swiper.updateProgress(translate);
13665  }
13666  swiper.emit('setTranslate', swiper.translate, byController);
13667}
13668
13669function minTranslate() {
13670  return -this.snapGrid[0];
13671}
13672
13673function maxTranslate() {
13674  return -this.snapGrid[this.snapGrid.length - 1];
13675}
13676
13677function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
13678  if (translate === void 0) {
13679    translate = 0;
13680  }
13681  if (speed === void 0) {
13682    speed = this.params.speed;
13683  }
13684  if (runCallbacks === void 0) {
13685    runCallbacks = true;
13686  }
13687  if (translateBounds === void 0) {
13688    translateBounds = true;
13689  }
13690  const swiper = this;
13691  const {
13692    params,
13693    wrapperEl
13694  } = swiper;
13695  if (swiper.animating && params.preventInteractionOnTransition) {
13696    return false;
13697  }
13698  const minTranslate = swiper.minTranslate();
13699  const maxTranslate = swiper.maxTranslate();
13700  let newTranslate;
13701  if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
13702
13703  // Update progress
13704  swiper.updateProgress(newTranslate);
13705  if (params.cssMode) {
13706    const isH = swiper.isHorizontal();
13707    if (speed === 0) {
13708      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
13709    } else {
13710      if (!swiper.support.smoothScroll) {
13711        animateCSSModeScroll({
13712          swiper,
13713          targetPosition: -newTranslate,
13714          side: isH ? 'left' : 'top'
13715        });
13716        return true;
13717      }
13718      wrapperEl.scrollTo({
13719        [isH ? 'left' : 'top']: -newTranslate,
13720        behavior: 'smooth'
13721      });
13722    }
13723    return true;
13724  }
13725  if (speed === 0) {
13726    swiper.setTransition(0);
13727    swiper.setTranslate(newTranslate);
13728    if (runCallbacks) {
13729      swiper.emit('beforeTransitionStart', speed, internal);
13730      swiper.emit('transitionEnd');
13731    }
13732  } else {
13733    swiper.setTransition(speed);
13734    swiper.setTranslate(newTranslate);
13735    if (runCallbacks) {
13736      swiper.emit('beforeTransitionStart', speed, internal);
13737      swiper.emit('transitionStart');
13738    }
13739    if (!swiper.animating) {
13740      swiper.animating = true;
13741      if (!swiper.onTranslateToWrapperTransitionEnd) {
13742        swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
13743          if (!swiper || swiper.destroyed) return;
13744          if (e.target !== this) return;
13745          swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
13746          swiper.onTranslateToWrapperTransitionEnd = null;
13747          delete swiper.onTranslateToWrapperTransitionEnd;
13748          swiper.animating = false;
13749          if (runCallbacks) {
13750            swiper.emit('transitionEnd');
13751          }
13752        };
13753      }
13754      swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
13755    }
13756  }
13757  return true;
13758}
13759
13760var translate = {
13761  getTranslate: getSwiperTranslate,
13762  setTranslate,
13763  minTranslate,
13764  maxTranslate,
13765  translateTo
13766};
13767
13768function setTransition(duration, byController) {
13769  const swiper = this;
13770  if (!swiper.params.cssMode) {
13771    swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
13772    swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
13773  }
13774  swiper.emit('setTransition', duration, byController);
13775}
13776
13777function transitionEmit(_ref) {
13778  let {
13779    swiper,
13780    runCallbacks,
13781    direction,
13782    step
13783  } = _ref;
13784  const {
13785    activeIndex,
13786    previousIndex
13787  } = swiper;
13788  let dir = direction;
13789  if (!dir) {
13790    if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
13791  }
13792  swiper.emit(`transition${step}`);
13793  if (runCallbacks && dir === 'reset') {
13794    swiper.emit(`slideResetTransition${step}`);
13795  } else if (runCallbacks && activeIndex !== previousIndex) {
13796    swiper.emit(`slideChangeTransition${step}`);
13797    if (dir === 'next') {
13798      swiper.emit(`slideNextTransition${step}`);
13799    } else {
13800      swiper.emit(`slidePrevTransition${step}`);
13801    }
13802  }
13803}
13804
13805function transitionStart(runCallbacks, direction) {
13806  if (runCallbacks === void 0) {
13807    runCallbacks = true;
13808  }
13809  const swiper = this;
13810  const {
13811    params
13812  } = swiper;
13813  if (params.cssMode) return;
13814  if (params.autoHeight) {
13815    swiper.updateAutoHeight();
13816  }
13817  transitionEmit({
13818    swiper,
13819    runCallbacks,
13820    direction,
13821    step: 'Start'
13822  });
13823}
13824
13825function transitionEnd(runCallbacks, direction) {
13826  if (runCallbacks === void 0) {
13827    runCallbacks = true;
13828  }
13829  const swiper = this;
13830  const {
13831    params
13832  } = swiper;
13833  swiper.animating = false;
13834  if (params.cssMode) return;
13835  swiper.setTransition(0);
13836  transitionEmit({
13837    swiper,
13838    runCallbacks,
13839    direction,
13840    step: 'End'
13841  });
13842}
13843
13844var transition = {
13845  setTransition,
13846  transitionStart,
13847  transitionEnd
13848};
13849
13850function slideTo(index, speed, runCallbacks, internal, initial) {
13851  if (index === void 0) {
13852    index = 0;
13853  }
13854  if (runCallbacks === void 0) {
13855    runCallbacks = true;
13856  }
13857  if (typeof index === 'string') {
13858    index = parseInt(index, 10);
13859  }
13860  const swiper = this;
13861  let slideIndex = index;
13862  if (slideIndex < 0) slideIndex = 0;
13863  const {
13864    params,
13865    snapGrid,
13866    slidesGrid,
13867    previousIndex,
13868    activeIndex,
13869    rtlTranslate: rtl,
13870    wrapperEl,
13871    enabled
13872  } = swiper;
13873  if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
13874    return false;
13875  }
13876  if (typeof speed === 'undefined') {
13877    speed = swiper.params.speed;
13878  }
13879  const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
13880  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
13881  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
13882  const translate = -snapGrid[snapIndex];
13883  // Normalize slideIndex
13884  if (params.normalizeSlideIndex) {
13885    for (let i = 0; i < slidesGrid.length; i += 1) {
13886      const normalizedTranslate = -Math.floor(translate * 100);
13887      const normalizedGrid = Math.floor(slidesGrid[i] * 100);
13888      const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
13889      if (typeof slidesGrid[i + 1] !== 'undefined') {
13890        if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
13891          slideIndex = i;
13892        } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
13893          slideIndex = i + 1;
13894        }
13895      } else if (normalizedTranslate >= normalizedGrid) {
13896        slideIndex = i;
13897      }
13898    }
13899  }
13900  // Directions locks
13901  if (swiper.initialized && slideIndex !== activeIndex) {
13902    if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
13903      return false;
13904    }
13905    if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
13906      if ((activeIndex || 0) !== slideIndex) {
13907        return false;
13908      }
13909    }
13910  }
13911  if (slideIndex !== (previousIndex || 0) && runCallbacks) {
13912    swiper.emit('beforeSlideChangeStart');
13913  }
13914
13915  // Update progress
13916  swiper.updateProgress(translate);
13917  let direction;
13918  if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
13919
13920  // initial virtual
13921  const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
13922  const isInitialVirtual = isVirtual && initial;
13923  // Update Index
13924  if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
13925    swiper.updateActiveIndex(slideIndex);
13926    // Update Height
13927    if (params.autoHeight) {
13928      swiper.updateAutoHeight();
13929    }
13930    swiper.updateSlidesClasses();
13931    if (params.effect !== 'slide') {
13932      swiper.setTranslate(translate);
13933    }
13934    if (direction !== 'reset') {
13935      swiper.transitionStart(runCallbacks, direction);
13936      swiper.transitionEnd(runCallbacks, direction);
13937    }
13938    return false;
13939  }
13940  if (params.cssMode) {
13941    const isH = swiper.isHorizontal();
13942    const t = rtl ? translate : -translate;
13943    if (speed === 0) {
13944      if (isVirtual) {
13945        swiper.wrapperEl.style.scrollSnapType = 'none';
13946        swiper._immediateVirtual = true;
13947      }
13948      if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
13949        swiper._cssModeVirtualInitialSet = true;
13950        requestAnimationFrame(() => {
13951          wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
13952        });
13953      } else {
13954        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
13955      }
13956      if (isVirtual) {
13957        requestAnimationFrame(() => {
13958          swiper.wrapperEl.style.scrollSnapType = '';
13959          swiper._immediateVirtual = false;
13960        });
13961      }
13962    } else {
13963      if (!swiper.support.smoothScroll) {
13964        animateCSSModeScroll({
13965          swiper,
13966          targetPosition: t,
13967          side: isH ? 'left' : 'top'
13968        });
13969        return true;
13970      }
13971      wrapperEl.scrollTo({
13972        [isH ? 'left' : 'top']: t,
13973        behavior: 'smooth'
13974      });
13975    }
13976    return true;
13977  }
13978  const browser = getBrowser();
13979  const isSafari = browser.isSafari;
13980  if (isVirtual && !initial && isSafari && swiper.isElement) {
13981    swiper.virtual.update(false, false, slideIndex);
13982  }
13983  swiper.setTransition(speed);
13984  swiper.setTranslate(translate);
13985  swiper.updateActiveIndex(slideIndex);
13986  swiper.updateSlidesClasses();
13987  swiper.emit('beforeTransitionStart', speed, internal);
13988  swiper.transitionStart(runCallbacks, direction);
13989  if (speed === 0) {
13990    swiper.transitionEnd(runCallbacks, direction);
13991  } else if (!swiper.animating) {
13992    swiper.animating = true;
13993    if (!swiper.onSlideToWrapperTransitionEnd) {
13994      swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
13995        if (!swiper || swiper.destroyed) return;
13996        if (e.target !== this) return;
13997        swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
13998        swiper.onSlideToWrapperTransitionEnd = null;
13999        delete swiper.onSlideToWrapperTransitionEnd;
14000        swiper.transitionEnd(runCallbacks, direction);
14001      };
14002    }
14003    swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
14004  }
14005  return true;
14006}
14007
14008function slideToLoop(index, speed, runCallbacks, internal) {
14009  if (index === void 0) {
14010    index = 0;
14011  }
14012  if (runCallbacks === void 0) {
14013    runCallbacks = true;
14014  }
14015  if (typeof index === 'string') {
14016    const indexAsNumber = parseInt(index, 10);
14017    index = indexAsNumber;
14018  }
14019  const swiper = this;
14020  if (swiper.destroyed) return;
14021  if (typeof speed === 'undefined') {
14022    speed = swiper.params.speed;
14023  }
14024  const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
14025  let newIndex = index;
14026  if (swiper.params.loop) {
14027    if (swiper.virtual && swiper.params.virtual.enabled) {
14028      // eslint-disable-next-line
14029      newIndex = newIndex + swiper.virtual.slidesBefore;
14030    } else {
14031      let targetSlideIndex;
14032      if (gridEnabled) {
14033        const slideIndex = newIndex * swiper.params.grid.rows;
14034        targetSlideIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
14035      } else {
14036        targetSlideIndex = swiper.getSlideIndexByData(newIndex);
14037      }
14038      const cols = gridEnabled ? Math.ceil(swiper.slides.length / 
vendor: 9,245 bytes, lines 14038-14292
14038swiper.params.grid.rows) : swiper.slides.length;
14039      const {
14040        centeredSlides
14041      } = swiper.params;
14042      let slidesPerView = swiper.params.slidesPerView;
14043      if (slidesPerView === 'auto') {
14044        slidesPerView = swiper.slidesPerViewDynamic();
14045      } else {
14046        slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
14047        if (centeredSlides && slidesPerView % 2 === 0) {
14048          slidesPerView = slidesPerView + 1;
14049        }
14050      }
14051      let needLoopFix = cols - targetSlideIndex < slidesPerView;
14052      if (centeredSlides) {
14053        needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
14054      }
14055      if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
14056        needLoopFix = false;
14057      }
14058      if (needLoopFix) {
14059        const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
14060        swiper.loopFix({
14061          direction,
14062          slideTo: true,
14063          activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
14064          slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
14065        });
14066      }
14067      if (gridEnabled) {
14068        const slideIndex = newIndex * swiper.params.grid.rows;
14069        newIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
14070      } else {
14071        newIndex = swiper.getSlideIndexByData(newIndex);
14072      }
14073    }
14074  }
14075  requestAnimationFrame(() => {
14076    swiper.slideTo(newIndex, speed, runCallbacks, internal);
14077  });
14078  return swiper;
14079}
14080
14081/* eslint no-unused-vars: "off" */
14082function slideNext(speed, runCallbacks, internal) {
14083  if (runCallbacks === void 0) {
14084    runCallbacks = true;
14085  }
14086  const swiper = this;
14087  const {
14088    enabled,
14089    params,
14090    animating
14091  } = swiper;
14092  if (!enabled || swiper.destroyed) return swiper;
14093  if (typeof speed === 'undefined') {
14094    speed = swiper.params.speed;
14095  }
14096  let perGroup = params.slidesPerGroup;
14097  if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
14098    perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
14099  }
14100  const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
14101  const isVirtual = swiper.virtual && params.virtual.enabled;
14102  if (params.loop) {
14103    if (animating && !isVirtual && params.loopPreventsSliding) return false;
14104    swiper.loopFix({
14105      direction: 'next'
14106    });
14107    // eslint-disable-next-line
14108    swiper._clientLeft = swiper.wrapperEl.clientLeft;
14109    if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
14110      requestAnimationFrame(() => {
14111        swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
14112      });
14113      return true;
14114    }
14115  }
14116  if (params.rewind && swiper.isEnd) {
14117    return swiper.slideTo(0, speed, runCallbacks, internal);
14118  }
14119  return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
14120}
14121
14122/* eslint no-unused-vars: "off" */
14123function slidePrev(speed, runCallbacks, internal) {
14124  if (runCallbacks === void 0) {
14125    runCallbacks = true;
14126  }
14127  const swiper = this;
14128  const {
14129    params,
14130    snapGrid,
14131    slidesGrid,
14132    rtlTranslate,
14133    enabled,
14134    animating
14135  } = swiper;
14136  if (!enabled || swiper.destroyed) return swiper;
14137  if (typeof speed === 'undefined') {
14138    speed = swiper.params.speed;
14139  }
14140  const isVirtual = swiper.virtual && params.virtual.enabled;
14141  if (params.loop) {
14142    if (animating && !isVirtual && params.loopPreventsSliding) return false;
14143    swiper.loopFix({
14144      direction: 'prev'
14145    });
14146    // eslint-disable-next-line
14147    swiper._clientLeft = swiper.wrapperEl.clientLeft;
14148  }
14149  const translate = rtlTranslate ? swiper.translate : -swiper.translate;
14150  function normalize(val) {
14151    if (val < 0) return -Math.floor(Math.abs(val));
14152    return Math.floor(val);
14153  }
14154  const normalizedTranslate = normalize(translate);
14155  const normalizedSnapGrid = snapGrid.map(val => normalize(val));
14156  const isFreeMode = params.freeMode && params.freeMode.enabled;
14157  let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
14158  if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) {
14159    let prevSnapIndex;
14160    snapGrid.forEach((snap, snapIndex) => {
14161      if (normalizedTranslate >= snap) {
14162        // prevSnap = snap;
14163        prevSnapIndex = snapIndex;
14164      }
14165    });
14166    if (typeof prevSnapIndex !== 'undefined') {
14167      prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
14168    }
14169  }
14170  let prevIndex = 0;
14171  if (typeof prevSnap !== 'undefined') {
14172    prevIndex = slidesGrid.indexOf(prevSnap);
14173    if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
14174    if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
14175      prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
14176      prevIndex = Math.max(prevIndex, 0);
14177    }
14178  }
14179  if (params.rewind && swiper.isBeginning) {
14180    const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
14181    return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
14182  } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
14183    requestAnimationFrame(() => {
14184      swiper.slideTo(prevIndex, speed, runCallbacks, internal);
14185    });
14186    return true;
14187  }
14188  return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
14189}
14190
14191/* eslint no-unused-vars: "off" */
14192function slideReset(speed, runCallbacks, internal) {
14193  if (runCallbacks === void 0) {
14194    runCallbacks = true;
14195  }
14196  const swiper = this;
14197  if (swiper.destroyed) return;
14198  if (typeof speed === 'undefined') {
14199    speed = swiper.params.speed;
14200  }
14201  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
14202}
14203
14204/* eslint no-unused-vars: "off" */
14205function slideToClosest(speed, runCallbacks, internal, threshold) {
14206  if (runCallbacks === void 0) {
14207    runCallbacks = true;
14208  }
14209  if (threshold === void 0) {
14210    threshold = 0.5;
14211  }
14212  const swiper = this;
14213  if (swiper.destroyed) return;
14214  if (typeof speed === 'undefined') {
14215    speed = swiper.params.speed;
14216  }
14217  let index = swiper.activeIndex;
14218  const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
14219  const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
14220  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
14221  if (translate >= swiper.snapGrid[snapIndex]) {
14222    // The current translate is on or after the current snap index, so the choice
14223    // is between the current index and the one after it.
14224    const currentSnap = swiper.snapGrid[snapIndex];
14225    const nextSnap = swiper.snapGrid[snapIndex + 1];
14226    if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
14227      index += swiper.params.slidesPerGroup;
14228    }
14229  } else {
14230    // The current translate is before the current snap index, so the choice
14231    // is between the current index and the one before it.
14232    const prevSnap = swiper.snapGrid[snapIndex - 1];
14233    const currentSnap = swiper.snapGrid[snapIndex];
14234    if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
14235      index -= swiper.params.slidesPerGroup;
14236    }
14237  }
14238  index = Math.max(index, 0);
14239  index = Math.min(index, swiper.slidesGrid.length - 1);
14240  return swiper.slideTo(index, speed, runCallbacks, internal);
14241}
14242
14243function slideToClickedSlide() {
14244  const swiper = this;
14245  if (swiper.destroyed) return;
14246  const {
14247    params,
14248    slidesEl
14249  } = swiper;
14250  const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
14251  let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex);
14252  let realIndex;
14253  const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
14254  const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
14255  if (params.loop) {
14256    if (swiper.animating) return;
14257    realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
14258    if (params.centeredSlides) {
14259      swiper.slideToLoop(realIndex);
14260    } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) {
14261      swiper.loopFix();
14262      slideToIndex = swiper.getSlideIndex(utils_elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
14263      utils_nextTick(() => {
14264        swiper.slideTo(slideToIndex);
14265      });
14266    } else {
14267      swiper.slideTo(slideToIndex);
14268    }
14269  } else {
14270    swiper.slideTo(slideToIndex);
14271  }
14272}
14273
14274var slide = {
14275  slideTo,
14276  slideToLoop,
14277  slideNext,
14278  slidePrev,
14279  slideReset,
14280  slideToClosest,
14281  slideToClickedSlide
14282};
14283
14284function loopCreate(slideRealIndex, initial) {
14285  const swiper = this;
14286  const {
14287    params,
14288    slidesEl
14289  } = swiper;
14290  if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
14291  const initSlides = () => {
14292    const slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
vendor: 5,612 bytes, lines 14293-14429
14293    slides.forEach((el, index) => {
14294      el.setAttribute('data-swiper-slide-index', index);
14295    });
14296  };
14297  const clearBlankSlides = () => {
14298    const slides = utils_elementChildren(slidesEl, `.${params.slideBlankClass}`);
14299    slides.forEach(el => {
14300      el.remove();
14301    });
14302    if (slides.length > 0) {
14303      swiper.recalcSlides();
14304      swiper.updateSlides();
14305    }
14306  };
14307  const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
14308  if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) {
14309    clearBlankSlides();
14310  }
14311  const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
14312  const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
14313  const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
14314  const addBlankSlides = amountOfSlides => {
14315    for (let i = 0; i < amountOfSlides; i += 1) {
14316      const slideEl = swiper.isElement ? utils_createElement('swiper-slide', [params.slideBlankClass]) : utils_createElement('div', [params.slideClass, params.slideBlankClass]);
14317      swiper.slidesEl.append(slideEl);
14318    }
14319  };
14320  if (shouldFillGroup) {
14321    if (params.loopAddBlankSlides) {
14322      const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
14323      addBlankSlides(slidesToAdd);
14324      swiper.recalcSlides();
14325      swiper.updateSlides();
14326    } else {
14327      showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
14328    }
14329    initSlides();
14330  } else if (shouldFillGrid) {
14331    if (params.loopAddBlankSlides) {
14332      const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
14333      addBlankSlides(slidesToAdd);
14334      swiper.recalcSlides();
14335      swiper.updateSlides();
14336    } else {
14337      showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
14338    }
14339    initSlides();
14340  } else {
14341    initSlides();
14342  }
14343  swiper.loopFix({
14344    slideRealIndex,
14345    direction: params.centeredSlides ? undefined : 'next',
14346    initial
14347  });
14348}
14349
14350function loopFix(_temp) {
14351  let {
14352    slideRealIndex,
14353    slideTo = true,
14354    direction,
14355    setTranslate,
14356    activeSlideIndex,
14357    initial,
14358    byController,
14359    byMousewheel
14360  } = _temp === void 0 ? {} : _temp;
14361  const swiper = this;
14362  if (!swiper.params.loop) return;
14363  swiper.emit('beforeLoopFix');
14364  const {
14365    slides,
14366    allowSlidePrev,
14367    allowSlideNext,
14368    slidesEl,
14369    params
14370  } = swiper;
14371  const {
14372    centeredSlides,
14373    initialSlide
14374  } = params;
14375  swiper.allowSlidePrev = true;
14376  swiper.allowSlideNext = true;
14377  if (swiper.virtual && params.virtual.enabled) {
14378    if (slideTo) {
14379      if (!params.centeredSlides && swiper.snapIndex === 0) {
14380        swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
14381      } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
14382        swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
14383      } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
14384        swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
14385      }
14386    }
14387    swiper.allowSlidePrev = allowSlidePrev;
14388    swiper.allowSlideNext = allowSlideNext;
14389    swiper.emit('loopFix');
14390    return;
14391  }
14392  let slidesPerView = params.slidesPerView;
14393  if (slidesPerView === 'auto') {
14394    slidesPerView = swiper.slidesPerViewDynamic();
14395  } else {
14396    slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
14397    if (centeredSlides && slidesPerView % 2 === 0) {
14398      slidesPerView = slidesPerView + 1;
14399    }
14400  }
14401  const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
14402  let loopedSlides = centeredSlides ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup;
14403  if (loopedSlides % slidesPerGroup !== 0) {
14404    loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
14405  }
14406  loopedSlides += params.loopAdditionalSlides;
14407  swiper.loopedSlides = loopedSlides;
14408  const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
14409  if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
14410    showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
14411  } else if (gridEnabled && params.grid.fill === 'row') {
14412    showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
14413  }
14414  const prependSlidesIndexes = [];
14415  const appendSlidesIndexes = [];
14416  const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
14417  const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !centeredSlides;
14418  let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex;
14419  if (typeof activeSlideIndex === 'undefined') {
14420    activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass)));
14421  } else {
14422    activeIndex = activeSlideIndex;
14423  }
14424  const isNext = direction === 'next' || !direction;
14425  const isPrev = direction === 'prev' || !direction;
14426  let slidesPrepended = 0;
14427  let slidesAppended = 0;
14428  const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
14429  const activeColIndexWithShift = activeColIndex + (centeredSlide
vendor: 7,760 bytes, lines 14429-14636
14429s && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
14430  // prepend last slides before start
14431  if (activeColIndexWithShift < loopedSlides) {
14432    slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
14433    for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
14434      const index = i - Math.floor(i / cols) * cols;
14435      if (gridEnabled) {
14436        const colIndexToPrepend = cols - index - 1;
14437        for (let i = slides.length - 1; i >= 0; i -= 1) {
14438          if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
14439        }
14440        // slides.forEach((slide, slideIndex) => {
14441        //   if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
14442        // });
14443      } else {
14444        prependSlidesIndexes.push(cols - index - 1);
14445      }
14446    }
14447  } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
14448    slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
14449    if (isInitialOverflow) {
14450      slidesAppended = Math.max(slidesAppended, slidesPerView - cols + initialSlide + 1);
14451    }
14452    for (let i = 0; i < slidesAppended; i += 1) {
14453      const index = i - Math.floor(i / cols) * cols;
14454      if (gridEnabled) {
14455        slides.forEach((slide, slideIndex) => {
14456          if (slide.column === index) appendSlidesIndexes.push(slideIndex);
14457        });
14458      } else {
14459        appendSlidesIndexes.push(index);
14460      }
14461    }
14462  }
14463  swiper.__preventObserver__ = true;
14464  requestAnimationFrame(() => {
14465    swiper.__preventObserver__ = false;
14466  });
14467  if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
14468    if (appendSlidesIndexes.includes(activeSlideIndex)) {
14469      appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1);
14470    }
14471    if (prependSlidesIndexes.includes(activeSlideIndex)) {
14472      prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1);
14473    }
14474  }
14475  if (isPrev) {
14476    prependSlidesIndexes.forEach(index => {
14477      slides[index].swiperLoopMoveDOM = true;
14478      slidesEl.prepend(slides[index]);
14479      slides[index].swiperLoopMoveDOM = false;
14480    });
14481  }
14482  if (isNext) {
14483    appendSlidesIndexes.forEach(index => {
14484      slides[index].swiperLoopMoveDOM = true;
14485      slidesEl.append(slides[index]);
14486      slides[index].swiperLoopMoveDOM = false;
14487    });
14488  }
14489  swiper.recalcSlides();
14490  if (params.slidesPerView === 'auto') {
14491    swiper.updateSlides();
14492  } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
14493    swiper.slides.forEach((slide, slideIndex) => {
14494      swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
14495    });
14496  }
14497  if (params.watchSlidesProgress) {
14498    swiper.updateSlidesOffset();
14499  }
14500  if (slideTo) {
14501    if (prependSlidesIndexes.length > 0 && isPrev) {
14502      if (typeof slideRealIndex === 'undefined') {
14503        const currentSlideTranslate = swiper.slidesGrid[activeIndex];
14504        const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
14505        const diff = newSlideTranslate - currentSlideTranslate;
14506        if (byMousewheel) {
14507          swiper.setTranslate(swiper.translate - diff);
14508        } else {
14509          swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
14510          if (setTranslate) {
14511            swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
14512            swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
14513          }
14514        }
14515      } else {
14516        if (setTranslate) {
14517          const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
14518          swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
14519          swiper.touchEventsData.currentTranslate = swiper.translate;
14520        }
14521      }
14522    } else if (appendSlidesIndexes.length > 0 && isNext) {
14523      if (typeof slideRealIndex === 'undefined') {
14524        const currentSlideTranslate = swiper.slidesGrid[activeIndex];
14525        const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
14526        const diff = newSlideTranslate - currentSlideTranslate;
14527        if (byMousewheel) {
14528          swiper.setTranslate(swiper.translate - diff);
14529        } else {
14530          swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
14531          if (setTranslate) {
14532            swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
14533            swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
14534          }
14535        }
14536      } else {
14537        const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
14538        swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
14539      }
14540    }
14541  }
14542  swiper.allowSlidePrev = allowSlidePrev;
14543  swiper.allowSlideNext = allowSlideNext;
14544  if (swiper.controller && swiper.controller.control && !byController) {
14545    const loopParams = {
14546      slideRealIndex,
14547      direction,
14548      setTranslate,
14549      activeSlideIndex,
14550      byController: true
14551    };
14552    if (Array.isArray(swiper.controller.control)) {
14553      swiper.controller.control.forEach(c => {
14554        if (!c.destroyed && c.params.loop) c.loopFix({
14555          ...loopParams,
14556          slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
14557        });
14558      });
14559    } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
14560      swiper.controller.control.loopFix({
14561        ...loopParams,
14562        slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
14563      });
14564    }
14565  }
14566  swiper.emit('loopFix');
14567}
14568
14569function loopDestroy() {
14570  const swiper = this;
14571  const {
14572    params,
14573    slidesEl
14574  } = swiper;
14575  if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return;
14576  swiper.recalcSlides();
14577  const newSlidesOrder = [];
14578  swiper.slides.forEach(slideEl => {
14579    const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
14580    newSlidesOrder[index] = slideEl;
14581  });
14582  swiper.slides.forEach(slideEl => {
14583    slideEl.removeAttribute('data-swiper-slide-index');
14584  });
14585  newSlidesOrder.forEach(slideEl => {
14586    slidesEl.append(slideEl);
14587  });
14588  swiper.recalcSlides();
14589  swiper.slideTo(swiper.realIndex, 0);
14590}
14591
14592var loop = {
14593  loopCreate,
14594  loopFix,
14595  loopDestroy
14596};
14597
14598function setGrabCursor(moving) {
14599  const swiper = this;
14600  if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
14601  const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
14602  if (swiper.isElement) {
14603    swiper.__preventObserver__ = true;
14604  }
14605  el.style.cursor = 'move';
14606  el.style.cursor = moving ? 'grabbing' : 'grab';
14607  if (swiper.isElement) {
14608    requestAnimationFrame(() => {
14609      swiper.__preventObserver__ = false;
14610    });
14611  }
14612}
14613
14614function unsetGrabCursor() {
14615  const swiper = this;
14616  if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
14617    return;
14618  }
14619  if (swiper.isElement) {
14620    swiper.__preventObserver__ = true;
14621  }
14622  swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
14623  if (swiper.isElement) {
14624    requestAnimationFrame(() => {
14625      swiper.__preventObserver__ = false;
14626    });
14627  }
14628}
14629
14630var grabCursor = {
14631  setGrabCursor,
14632  unsetGrabCursor
14633};
14634
14635// Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
14636function closestElement(selector, base
vendor: 3,722 bytes, lines 14636-14748
14636) {
14637  if (base === void 0) {
14638    base = this;
14639  }
14640  function __closestFrom(el) {
14641    if (!el || el === ssr_window_esm_getDocument() || el === ssr_window_esm_getWindow()) return null;
14642    if (el.assignedSlot) el = el.assignedSlot;
14643    const found = el.closest(selector);
14644    if (!found && !el.getRootNode) {
14645      return null;
14646    }
14647    return found || __closestFrom(el.getRootNode().host);
14648  }
14649  return __closestFrom(base);
14650}
14651function preventEdgeSwipe(swiper, event, startX) {
14652  const window = ssr_window_esm_getWindow();
14653  const {
14654    params
14655  } = swiper;
14656  const edgeSwipeDetection = params.edgeSwipeDetection;
14657  const edgeSwipeThreshold = params.edgeSwipeThreshold;
14658  if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
14659    if (edgeSwipeDetection === 'prevent') {
14660      event.preventDefault();
14661      return true;
14662    }
14663    return false;
14664  }
14665  return true;
14666}
14667function onTouchStart(event) {
14668  const swiper = this;
14669  const document = ssr_window_esm_getDocument();
14670  let e = event;
14671  if (e.originalEvent) e = e.originalEvent;
14672  const data = swiper.touchEventsData;
14673  if (e.type === 'pointerdown') {
14674    if (data.pointerId !== null && data.pointerId !== e.pointerId) {
14675      return;
14676    }
14677    data.pointerId = e.pointerId;
14678  } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
14679    data.touchId = e.targetTouches[0].identifier;
14680  }
14681  if (e.type === 'touchstart') {
14682    // don't proceed touch event
14683    preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
14684    return;
14685  }
14686  const {
14687    params,
14688    touches,
14689    enabled
14690  } = swiper;
14691  if (!enabled) return;
14692  if (!params.simulateTouch && e.pointerType === 'mouse') return;
14693  if (swiper.animating && params.preventInteractionOnTransition) {
14694    return;
14695  }
14696  if (!swiper.animating && params.cssMode && params.loop) {
14697    swiper.loopFix();
14698  }
14699  let targetEl = e.target;
14700  if (params.touchEventsTarget === 'wrapper') {
14701    if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return;
14702  }
14703  if ('which' in e && e.which === 3) return;
14704  if ('button' in e && e.button > 0) return;
14705  if (data.isTouched && data.isMoved) return;
14706
14707  // change target el for shadow root component
14708  const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
14709  // eslint-disable-next-line
14710  const eventPath = e.composedPath ? e.composedPath() : e.path;
14711  if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
14712    targetEl = eventPath[0];
14713  }
14714  const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
14715  const isTargetShadow = !!(e.target && e.target.shadowRoot);
14716
14717  // use closestElement for shadow root element to get the actual closest for nested shadow root element
14718  if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
14719    swiper.allowClick = true;
14720    return;
14721  }
14722  if (params.swipeHandler) {
14723    if (!targetEl.closest(params.swipeHandler)) return;
14724  }
14725  touches.currentX = e.pageX;
14726  touches.currentY = e.pageY;
14727  const startX = touches.currentX;
14728  const startY = touches.currentY;
14729
14730  // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
14731
14732  if (!preventEdgeSwipe(swiper, e, startX)) {
14733    return;
14734  }
14735  Object.assign(data, {
14736    isTouched: true,
14737    isMoved: false,
14738    allowTouchCallbacks: true,
14739    isScrolling: undefined,
14740    startMoving: undefined
14741  });
14742  touches.startX = startX;
14743  touches.startY = startY;
14744  data.touchStartTime = utils_now();
14745  swiper.allowClick = true;
14746  swiper.updateSize();
14747  swiper.swipeDirection = undefined;
14748  if (params.threshold > 0) data.allowThresholdMove = false;
vendor: 2,328 bytes, lines 14749-14819
14749  let preventDefault = true;
14750  if (targetEl.matches(data.focusableElements)) {
14751    preventDefault = false;
14752    if (targetEl.nodeName === 'SELECT') {
14753      data.isTouched = false;
14754    }
14755  }
14756  if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) {
14757    document.activeElement.blur();
14758  }
14759  const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
14760  if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
14761    e.preventDefault();
14762  }
14763  if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
14764    swiper.freeMode.onTouchStart();
14765  }
14766  swiper.emit('touchStart', e);
14767}
14768
14769function onTouchMove(event) {
14770  const document = ssr_window_esm_getDocument();
14771  const swiper = this;
14772  const data = swiper.touchEventsData;
14773  const {
14774    params,
14775    touches,
14776    rtlTranslate: rtl,
14777    enabled
14778  } = swiper;
14779  if (!enabled) return;
14780  if (!params.simulateTouch && event.pointerType === 'mouse') return;
14781  let e = event;
14782  if (e.originalEvent) e = e.originalEvent;
14783  if (e.type === 'pointermove') {
14784    if (data.touchId !== null) return; // return from pointer if we use touch
14785    const id = e.pointerId;
14786    if (id !== data.pointerId) return;
14787  }
14788  let targetTouch;
14789  if (e.type === 'touchmove') {
14790    targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
14791    if (!targetTouch || targetTouch.identifier !== data.touchId) return;
14792  } else {
14793    targetTouch = e;
14794  }
14795  if (!data.isTouched) {
14796    if (data.startMoving && data.isScrolling) {
14797      swiper.emit('touchMoveOpposite', e);
14798    }
14799    return;
14800  }
14801  const pageX = targetTouch.pageX;
14802  const pageY = targetTouch.pageY;
14803  if (e.preventedByNestedSwiper) {
14804    touches.startX = pageX;
14805    touches.startY = pageY;
14806    return;
14807  }
14808  if (!swiper.allowTouchMove) {
14809    if (!e.target.matches(data.focusableElements)) {
14810      swiper.allowClick = false;
14811    }
14812    if (data.isTouched) {
14813      Object.assign(touches, {
14814        startX: pageX,
14815        startY: pageY,
14816        currentX: pageX,
14817        currentY: pageY
14818      });
14819      data.touchStartTime = utils_now
vendor: 10,043 bytes, lines 14819-15082
14819();
14820    }
14821    return;
14822  }
14823  if (params.touchReleaseOnEdges && !params.loop) {
14824    if (swiper.isVertical()) {
14825      // Vertical
14826      if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
14827        data.isTouched = false;
14828        data.isMoved = false;
14829        return;
14830      }
14831    } else if (rtl && (pageX > touches.startX && -swiper.translate <= swiper.maxTranslate() || pageX < touches.startX && -swiper.translate >= swiper.minTranslate())) {
14832      return;
14833    } else if (!rtl && (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate())) {
14834      return;
14835    }
14836  }
14837  if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') {
14838    document.activeElement.blur();
14839  }
14840  if (document.activeElement) {
14841    if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
14842      data.isMoved = true;
14843      swiper.allowClick = false;
14844      return;
14845    }
14846  }
14847  if (data.allowTouchCallbacks) {
14848    swiper.emit('touchMove', e);
14849  }
14850  touches.previousX = touches.currentX;
14851  touches.previousY = touches.currentY;
14852  touches.currentX = pageX;
14853  touches.currentY = pageY;
14854  const diffX = touches.currentX - touches.startX;
14855  const diffY = touches.currentY - touches.startY;
14856  if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
14857  if (typeof data.isScrolling === 'undefined') {
14858    let touchAngle;
14859    if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
14860      data.isScrolling = false;
14861    } else {
14862      // eslint-disable-next-line
14863      if (diffX * diffX + diffY * diffY >= 25) {
14864        touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
14865        data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
14866      }
14867    }
14868  }
14869  if (data.isScrolling) {
14870    swiper.emit('touchMoveOpposite', e);
14871  }
14872  if (typeof data.startMoving === 'undefined') {
14873    if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
14874      data.startMoving = true;
14875    }
14876  }
14877  if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
14878    data.isTouched = false;
14879    return;
14880  }
14881  if (!data.startMoving) {
14882    return;
14883  }
14884  swiper.allowClick = false;
14885  if (!params.cssMode && e.cancelable) {
14886    e.preventDefault();
14887  }
14888  if (params.touchMoveStopPropagation && !params.nested) {
14889    e.stopPropagation();
14890  }
14891  let diff = swiper.isHorizontal() ? diffX : diffY;
14892  let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
14893  if (params.oneWayMovement) {
14894    diff = Math.abs(diff) * (rtl ? 1 : -1);
14895    touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
14896  }
14897  touches.diff = diff;
14898  diff *= params.touchRatio;
14899  if (rtl) {
14900    diff = -diff;
14901    touchesDiff = -touchesDiff;
14902  }
14903  const prevTouchesDirection = swiper.touchesDirection;
14904  swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
14905  swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
14906  const isLoop = swiper.params.loop && !params.cssMode;
14907  const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
14908  if (!data.isMoved) {
14909    if (isLoop && allowLoopFix) {
14910      swiper.loopFix({
14911        direction: swiper.swipeDirection
14912      });
14913    }
14914    data.startTranslate = swiper.getTranslate();
14915    swiper.setTransition(0);
14916    if (swiper.animating) {
14917      const evt = new window.CustomEvent('transitionend', {
14918        bubbles: true,
14919        cancelable: true,
14920        detail: {
14921          bySwiperTouchMove: true
14922        }
14923      });
14924      swiper.wrapperEl.dispatchEvent(evt);
14925    }
14926    data.allowMomentumBounce = false;
14927    // Grab Cursor
14928    if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
14929      swiper.setGrabCursor(true);
14930    }
14931    swiper.emit('sliderFirstMove', e);
14932  }
14933  let loopFixed;
14934  new Date().getTime();
14935  if (params._loopSwapReset !== false && data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
14936    Object.assign(touches, {
14937      startX: pageX,
14938      startY: pageY,
14939      currentX: pageX,
14940      currentY: pageY,
14941      startTranslate: data.currentTranslate
14942    });
14943    data.loopSwapReset = true;
14944    data.startTranslate = data.currentTranslate;
14945    return;
14946  }
14947  swiper.emit('sliderMove', e);
14948  data.isMoved = true;
14949  data.currentTranslate = diff + data.startTranslate;
14950  let disableParentSwiper = true;
14951  let resistanceRatio = params.resistanceRatio;
14952  if (params.touchReleaseOnEdges) {
14953    resistanceRatio = 0;
14954  }
14955  if (diff > 0) {
14956    if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.slidesSizesGrid[swiper.activeIndex + 1] - (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.activeIndex + 1] + swiper.params.spaceBetween : 0) - swiper.params.spaceBetween : swiper.minTranslate())) {
14957      swiper.loopFix({
14958        direction: 'prev',
14959        setTranslate: true,
14960        activeSlideIndex: 0
14961      });
14962    }
14963    if (data.currentTranslate > swiper.minTranslate()) {
14964      disableParentSwiper = false;
14965      if (params.resistance) {
14966        data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
14967      }
14968    }
14969  } else if (diff < 0) {
14970    if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween + (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween : 0) : swiper.maxTranslate())) {
14971      swiper.loopFix({
14972        direction: 'next',
14973        setTranslate: true,
14974        activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
14975      });
14976    }
14977    if (data.currentTranslate < swiper.maxTranslate()) {
14978      disableParentSwiper = false;
14979      if (params.resistance) {
14980        data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
14981      }
14982    }
14983  }
14984  if (disableParentSwiper) {
14985    e.preventedByNestedSwiper = true;
14986  }
14987
14988  // Directions locks
14989  if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
14990    data.currentTranslate = data.startTranslate;
14991  }
14992  if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
14993    data.currentTranslate = data.startTranslate;
14994  }
14995  if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
14996    data.currentTranslate = data.startTranslate;
14997  }
14998
14999  // Threshold
15000  if (params.threshold > 0) {
15001    if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
15002      if (!data.allowThresholdMove) {
15003        data.allowThresholdMove = true;
15004        touches.startX = touches.currentX;
15005        touches.startY = touches.currentY;
15006        data.currentTranslate = data.startTranslate;
15007        touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
15008        return;
15009      }
15010    } else {
15011      data.currentTranslate = data.startTranslate;
15012      return;
15013    }
15014  }
15015  if (!params.followFinger || params.cssMode) return;
15016
15017  // Update active index in free mode
15018  if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
15019    swiper.updateActiveIndex();
15020    swiper.updateSlidesClasses();
15021  }
15022  if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
15023    swiper.freeMode.onTouchMove();
15024  }
15025  // Update progress
15026  swiper.updateProgress(data.currentTranslate);
15027  // Update translate
15028  swiper.setTranslate(data.currentTranslate);
15029}
15030
15031function onTouchEnd(event) {
15032  const swiper = this;
15033  const data = swiper.touchEventsData;
15034  let e = event;
15035  if (e.originalEvent) e = e.originalEvent;
15036  let targetTouch;
15037  const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
15038  if (!isTouchEvent) {
15039    if (data.touchId !== null) return; // return from pointer if we use touch
15040    if (e.pointerId !== data.pointerId) return;
15041    targetTouch = e;
15042  } else {
15043    targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
15044    if (!targetTouch || targetTouch.identifier !== data.touchId) return;
15045  }
15046  if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
15047    const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
15048    if (!proceed) {
15049      return;
15050    }
15051  }
15052  data.pointerId = null;
15053  data.touchId = null;
15054  const {
15055    params,
15056    touches,
15057    rtlTranslate: rtl,
15058    slidesGrid,
15059    enabled
15060  } = swiper;
15061  if (!enabled) return;
15062  if (!params.simulateTouch && e.pointerType === 'mouse') return;
15063  if (data.allowTouchCallbacks) {
15064    swiper.emit('touchEnd', e);
15065  }
15066  data.allowTouchCallbacks = false;
15067  if (!data.isTouched) {
15068    if (data.isMoved && params.grabCursor) {
15069      swiper.setGrabCursor(false);
15070    }
15071    data.isMoved = false;
15072    data.startMoving = false;
15073    return;
15074  }
15075
15076  // Return Grab Cursor
15077  if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
15078    swiper.setGrabCursor(false);
15079  }
15080
15081  // Time diff
15082  const touchEndTime = 
vendor: 4,126 bytes, lines 15082-15198
15082utils_now();
15083  const timeDiff = touchEndTime - data.touchStartTime;
15084
15085  // Tap, doubleTap, Click
15086  if (swiper.allowClick) {
15087    const pathTree = e.path || e.composedPath && e.composedPath();
15088    swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
15089    swiper.emit('tap click', e);
15090    if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
15091      swiper.emit('doubleTap doubleClick', e);
15092    }
15093  }
15094  data.lastClickTime = utils_now();
15095  utils_nextTick(() => {
15096    if (!swiper.destroyed) swiper.allowClick = true;
15097  });
15098  if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
15099    data.isTouched = false;
15100    data.isMoved = false;
15101    data.startMoving = false;
15102    return;
15103  }
15104  data.isTouched = false;
15105  data.isMoved = false;
15106  data.startMoving = false;
15107  let currentPos;
15108  if (params.followFinger) {
15109    currentPos = rtl ? swiper.translate : -swiper.translate;
15110  } else {
15111    currentPos = -data.currentTranslate;
15112  }
15113  if (params.cssMode) {
15114    return;
15115  }
15116  if (params.freeMode && params.freeMode.enabled) {
15117    swiper.freeMode.onTouchEnd({
15118      currentPos
15119    });
15120    return;
15121  }
15122
15123  // Find current slide
15124  const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
15125  let stopIndex = 0;
15126  let groupSize = swiper.slidesSizesGrid[0];
15127  for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
15128    const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
15129    if (typeof slidesGrid[i + increment] !== 'undefined') {
15130      if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
15131        stopIndex = i;
15132        groupSize = slidesGrid[i + increment] - slidesGrid[i];
15133      }
15134    } else if (swipeToLast || currentPos >= slidesGrid[i]) {
15135      stopIndex = i;
15136      groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
15137    }
15138  }
15139  let rewindFirstIndex = null;
15140  let rewindLastIndex = null;
15141  if (params.rewind) {
15142    if (swiper.isBeginning) {
15143      rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
15144    } else if (swiper.isEnd) {
15145      rewindFirstIndex = 0;
15146    }
15147  }
15148  // Find current slide size
15149  const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
15150  const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
15151  if (timeDiff > params.longSwipesMs) {
15152    // Long touches
15153    if (!params.longSwipes) {
15154      swiper.slideTo(swiper.activeIndex);
15155      return;
15156    }
15157    if (swiper.swipeDirection === 'next') {
15158      if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
15159    }
15160    if (swiper.swipeDirection === 'prev') {
15161      if (ratio > 1 - params.longSwipesRatio) {
15162        swiper.slideTo(stopIndex + increment);
15163      } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
15164        swiper.slideTo(rewindLastIndex);
15165      } else {
15166        swiper.slideTo(stopIndex);
15167      }
15168    }
15169  } else {
15170    // Short swipes
15171    if (!params.shortSwipes) {
15172      swiper.slideTo(swiper.activeIndex);
15173      return;
15174    }
15175    const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
15176    if (!isNavButtonTarget) {
15177      if (swiper.swipeDirection === 'next') {
15178        swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
15179      }
15180      if (swiper.swipeDirection === 'prev') {
15181        swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
15182      }
15183    } else if (e.target === swiper.navigation.nextEl) {
15184      swiper.slideTo(stopIndex + increment);
15185    } else {
15186      swiper.slideTo(stopIndex);
15187    }
15188  }
15189}
15190
15191function onResize() {
15192  const swiper = this;
15193  const {
15194    params,
15195    el
15196  } = swiper;
15197  if (el && el.offsetWidth === 0) return;
15198
vendor: 6,463 bytes, lines 15199-15421
15199  // Breakpoints
15200  if (params.breakpoints) {
15201    swiper.setBreakpoint();
15202  }
15203
15204  // Save locks
15205  const {
15206    allowSlideNext,
15207    allowSlidePrev,
15208    snapGrid
15209  } = swiper;
15210  const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
15211
15212  // Disable locks on resize
15213  swiper.allowSlideNext = true;
15214  swiper.allowSlidePrev = true;
15215  swiper.updateSize();
15216  swiper.updateSlides();
15217  swiper.updateSlidesClasses();
15218  const isVirtualLoop = isVirtual && params.loop;
15219  if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
15220    swiper.slideTo(swiper.slides.length - 1, 0, false, true);
15221  } else {
15222    if (swiper.params.loop && !isVirtual) {
15223      swiper.slideToLoop(swiper.realIndex, 0, false, true);
15224    } else {
15225      swiper.slideTo(swiper.activeIndex, 0, false, true);
15226    }
15227  }
15228  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
15229    clearTimeout(swiper.autoplay.resizeTimeout);
15230    swiper.autoplay.resizeTimeout = setTimeout(() => {
15231      if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
15232        swiper.autoplay.resume();
15233      }
15234    }, 500);
15235  }
15236  // Return locks after resize
15237  swiper.allowSlidePrev = allowSlidePrev;
15238  swiper.allowSlideNext = allowSlideNext;
15239  if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
15240    swiper.checkOverflow();
15241  }
15242}
15243
15244function onClick(e) {
15245  const swiper = this;
15246  if (!swiper.enabled) return;
15247  if (!swiper.allowClick) {
15248    if (swiper.params.preventClicks) e.preventDefault();
15249    if (swiper.params.preventClicksPropagation && swiper.animating) {
15250      e.stopPropagation();
15251      e.stopImmediatePropagation();
15252    }
15253  }
15254}
15255
15256function onScroll() {
15257  const swiper = this;
15258  const {
15259    wrapperEl,
15260    rtlTranslate,
15261    enabled
15262  } = swiper;
15263  if (!enabled) return;
15264  swiper.previousTranslate = swiper.translate;
15265  if (swiper.isHorizontal()) {
15266    swiper.translate = -wrapperEl.scrollLeft;
15267  } else {
15268    swiper.translate = -wrapperEl.scrollTop;
15269  }
15270  // eslint-disable-next-line
15271  if (swiper.translate === 0) swiper.translate = 0;
15272  swiper.updateActiveIndex();
15273  swiper.updateSlidesClasses();
15274  let newProgress;
15275  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
15276  if (translatesDiff === 0) {
15277    newProgress = 0;
15278  } else {
15279    newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
15280  }
15281  if (newProgress !== swiper.progress) {
15282    swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
15283  }
15284  swiper.emit('setTranslate', swiper.translate, false);
15285}
15286
15287function onLoad(e) {
15288  const swiper = this;
15289  processLazyPreloader(swiper, e.target);
15290  if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
15291    return;
15292  }
15293  swiper.update();
15294}
15295
15296function onDocumentTouchStart() {
15297  const swiper = this;
15298  if (swiper.documentTouchHandlerProceeded) return;
15299  swiper.documentTouchHandlerProceeded = true;
15300  if (swiper.params.touchReleaseOnEdges) {
15301    swiper.el.style.touchAction = 'auto';
15302  }
15303}
15304
15305const events = (swiper, method) => {
15306  const document = ssr_window_esm_getDocument();
15307  const {
15308    params,
15309    el,
15310    wrapperEl,
15311    device
15312  } = swiper;
15313  const capture = !!params.nested;
15314  const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
15315  const swiperMethod = method;
15316  if (!el || typeof el === 'string') return;
15317
15318  // Touch Events
15319  document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
15320    passive: false,
15321    capture
15322  });
15323  el[domMethod]('touchstart', swiper.onTouchStart, {
15324    passive: false
15325  });
15326  el[domMethod]('pointerdown', swiper.onTouchStart, {
15327    passive: false
15328  });
15329  document[domMethod]('touchmove', swiper.onTouchMove, {
15330    passive: false,
15331    capture
15332  });
15333  document[domMethod]('pointermove', swiper.onTouchMove, {
15334    passive: false,
15335    capture
15336  });
15337  document[domMethod]('touchend', swiper.onTouchEnd, {
15338    passive: true
15339  });
15340  document[domMethod]('pointerup', swiper.onTouchEnd, {
15341    passive: true
15342  });
15343  document[domMethod]('pointercancel', swiper.onTouchEnd, {
15344    passive: true
15345  });
15346  document[domMethod]('touchcancel', swiper.onTouchEnd, {
15347    passive: true
15348  });
15349  document[domMethod]('pointerout', swiper.onTouchEnd, {
15350    passive: true
15351  });
15352  document[domMethod]('pointerleave', swiper.onTouchEnd, {
15353    passive: true
15354  });
15355  document[domMethod]('contextmenu', swiper.onTouchEnd, {
15356    passive: true
15357  });
15358
15359  // Prevent Links Clicks
15360  if (params.preventClicks || params.preventClicksPropagation) {
15361    el[domMethod]('click', swiper.onClick, true);
15362  }
15363  if (params.cssMode) {
15364    wrapperEl[domMethod]('scroll', swiper.onScroll);
15365  }
15366
15367  // Resize handler
15368  if (params.updateOnWindowResize) {
15369    swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
15370  } else {
15371    swiper[swiperMethod]('observerUpdate', onResize, true);
15372  }
15373
15374  // Images loader
15375  el[domMethod]('load', swiper.onLoad, {
15376    capture: true
15377  });
15378};
15379function attachEvents() {
15380  const swiper = this;
15381  const {
15382    params
15383  } = swiper;
15384  swiper.onTouchStart = onTouchStart.bind(swiper);
15385  swiper.onTouchMove = onTouchMove.bind(swiper);
15386  swiper.onTouchEnd = onTouchEnd.bind(swiper);
15387  swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
15388  if (params.cssMode) {
15389    swiper.onScroll = onScroll.bind(swiper);
15390  }
15391  swiper.onClick = onClick.bind(swiper);
15392  swiper.onLoad = onLoad.bind(swiper);
15393  events(swiper, 'on');
15394}
15395function detachEvents() {
15396  const swiper = this;
15397  events(swiper, 'off');
15398}
15399var events$1 = {
15400  attachEvents,
15401  detachEvents
15402};
15403
15404const isGridEnabled = (swiper, params) => {
15405  return swiper.grid && params.grid && params.grid.rows > 1;
15406};
15407function setBreakpoint() {
15408  const swiper = this;
15409  const {
15410    realIndex,
15411    initialized,
15412    params,
15413    el
15414  } = swiper;
15415  const breakpoints = params.breakpoints;
15416  if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
15417  const document = ssr_window_esm_getDocument();
15418
15419  // Get breakpoint for window/container width and update parameters
15420  const breakpointsBase = params.breakpointsBase === 'window' || !params.breakpointsBase ? params.breakpointsBase : 'container';
15421  const breakpointContainer = ['window', 'container'].includes(params.breakpointsBase) || !params.breakpointsBase ? swiper.el : document.querySelector(params.breakpointsBase);
vendor: 4,153 bytes, lines 15422-15535
15422  const breakpoint = swiper.getBreakpoint(breakpoints, breakpointsBase, breakpointContainer);
15423  if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
15424  const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
15425  const breakpointParams = breakpointOnlyParams || swiper.originalParams;
15426  const wasMultiRow = isGridEnabled(swiper, params);
15427  const isMultiRow = isGridEnabled(swiper, breakpointParams);
15428  const wasGrabCursor = swiper.params.grabCursor;
15429  const isGrabCursor = breakpointParams.grabCursor;
15430  const wasEnabled = params.enabled;
15431  if (wasMultiRow && !isMultiRow) {
15432    el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
15433    swiper.emitContainerClasses();
15434  } else if (!wasMultiRow && isMultiRow) {
15435    el.classList.add(`${params.containerModifierClass}grid`);
15436    if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
15437      el.classList.add(`${params.containerModifierClass}grid-column`);
15438    }
15439    swiper.emitContainerClasses();
15440  }
15441  if (wasGrabCursor && !isGrabCursor) {
15442    swiper.unsetGrabCursor();
15443  } else if (!wasGrabCursor && isGrabCursor) {
15444    swiper.setGrabCursor();
15445  }
15446
15447  // Toggle navigation, pagination, scrollbar
15448  ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
15449    if (typeof breakpointParams[prop] === 'undefined') return;
15450    const wasModuleEnabled = params[prop] && params[prop].enabled;
15451    const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
15452    if (wasModuleEnabled && !isModuleEnabled) {
15453      swiper[prop].disable();
15454    }
15455    if (!wasModuleEnabled && isModuleEnabled) {
15456      swiper[prop].enable();
15457    }
15458  });
15459  const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
15460  const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
15461  const wasLoop = params.loop;
15462  if (directionChanged && initialized) {
15463    swiper.changeDirection();
15464  }
15465  utils_extend(swiper.params, breakpointParams);
15466  const isEnabled = swiper.params.enabled;
15467  const hasLoop = swiper.params.loop;
15468  Object.assign(swiper, {
15469    allowTouchMove: swiper.params.allowTouchMove,
15470    allowSlideNext: swiper.params.allowSlideNext,
15471    allowSlidePrev: swiper.params.allowSlidePrev
15472  });
15473  if (wasEnabled && !isEnabled) {
15474    swiper.disable();
15475  } else if (!wasEnabled && isEnabled) {
15476    swiper.enable();
15477  }
15478  swiper.currentBreakpoint = breakpoint;
15479  swiper.emit('_beforeBreakpoint', breakpointParams);
15480  if (initialized) {
15481    if (needsReLoop) {
15482      swiper.loopDestroy();
15483      swiper.loopCreate(realIndex);
15484      swiper.updateSlides();
15485    } else if (!wasLoop && hasLoop) {
15486      swiper.loopCreate(realIndex);
15487      swiper.updateSlides();
15488    } else if (wasLoop && !hasLoop) {
15489      swiper.loopDestroy();
15490    }
15491  }
15492  swiper.emit('breakpoint', breakpointParams);
15493}
15494
15495function getBreakpoint(breakpoints, base, containerEl) {
15496  if (base === void 0) {
15497    base = 'window';
15498  }
15499  if (!breakpoints || base === 'container' && !containerEl) return undefined;
15500  let breakpoint = false;
15501  const window = ssr_window_esm_getWindow();
15502  const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
15503  const points = Object.keys(breakpoints).map(point => {
15504    if (typeof point === 'string' && point.indexOf('@') === 0) {
15505      const minRatio = parseFloat(point.substr(1));
15506      const value = currentHeight * minRatio;
15507      return {
15508        value,
15509        point
15510      };
15511    }
15512    return {
15513      value: point,
15514      point
15515    };
15516  });
15517  points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
15518  for (let i = 0; i < points.length; i += 1) {
15519    const {
15520      point,
15521      value
15522    } = points[i];
15523    if (base === 'window') {
15524      if (window.matchMedia(`(min-width: ${value}px)`).matches) {
15525        breakpoint = point;
15526      }
15527    } else if (value <= containerEl.clientWidth) {
15528      breakpoint = point;
15529    }
15530  }
15531  return breakpoint || 'max';
15532}
15533
15534var breakpoints = {
15535  setBreakpoint,
vendor: 14,757 bytes, lines 15536-16064
15536  getBreakpoint
15537};
15538
15539function prepareClasses(entries, prefix) {
15540  const resultClasses = [];
15541  entries.forEach(item => {
15542    if (typeof item === 'object') {
15543      Object.keys(item).forEach(classNames => {
15544        if (item[classNames]) {
15545          resultClasses.push(prefix + classNames);
15546        }
15547      });
15548    } else if (typeof item === 'string') {
15549      resultClasses.push(prefix + item);
15550    }
15551  });
15552  return resultClasses;
15553}
15554function addClasses() {
15555  const swiper = this;
15556  const {
15557    classNames,
15558    params,
15559    rtl,
15560    el,
15561    device
15562  } = swiper;
15563  // prettier-ignore
15564  const suffixes = prepareClasses(['initialized', params.direction, {
15565    'free-mode': swiper.params.freeMode && params.freeMode.enabled
15566  }, {
15567    'autoheight': params.autoHeight
15568  }, {
15569    'rtl': rtl
15570  }, {
15571    'grid': params.grid && params.grid.rows > 1
15572  }, {
15573    'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
15574  }, {
15575    'android': device.android
15576  }, {
15577    'ios': device.ios
15578  }, {
15579    'css-mode': params.cssMode
15580  }, {
15581    'centered': params.cssMode && params.centeredSlides
15582  }, {
15583    'watch-progress': params.watchSlidesProgress
15584  }], params.containerModifierClass);
15585  classNames.push(...suffixes);
15586  el.classList.add(...classNames);
15587  swiper.emitContainerClasses();
15588}
15589
15590function removeClasses() {
15591  const swiper = this;
15592  const {
15593    el,
15594    classNames
15595  } = swiper;
15596  if (!el || typeof el === 'string') return;
15597  el.classList.remove(...classNames);
15598  swiper.emitContainerClasses();
15599}
15600
15601var classes = {
15602  addClasses,
15603  removeClasses
15604};
15605
15606function checkOverflow() {
15607  const swiper = this;
15608  const {
15609    isLocked: wasLocked,
15610    params
15611  } = swiper;
15612  const {
15613    slidesOffsetBefore
15614  } = params;
15615  if (slidesOffsetBefore) {
15616    const lastSlideIndex = swiper.slides.length - 1;
15617    const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
15618    swiper.isLocked = swiper.size > lastSlideRightEdge;
15619  } else {
15620    swiper.isLocked = swiper.snapGrid.length === 1;
15621  }
15622  if (params.allowSlideNext === true) {
15623    swiper.allowSlideNext = !swiper.isLocked;
15624  }
15625  if (params.allowSlidePrev === true) {
15626    swiper.allowSlidePrev = !swiper.isLocked;
15627  }
15628  if (wasLocked && wasLocked !== swiper.isLocked) {
15629    swiper.isEnd = false;
15630  }
15631  if (wasLocked !== swiper.isLocked) {
15632    swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
15633  }
15634}
15635var checkOverflow$1 = {
15636  checkOverflow
15637};
15638
15639var defaults = {
15640  init: true,
15641  direction: 'horizontal',
15642  oneWayMovement: false,
15643  swiperElementNodeName: 'SWIPER-CONTAINER',
15644  touchEventsTarget: 'wrapper',
15645  initialSlide: 0,
15646  speed: 300,
15647  cssMode: false,
15648  updateOnWindowResize: true,
15649  resizeObserver: true,
15650  nested: false,
15651  createElements: false,
15652  eventsPrefix: 'swiper',
15653  enabled: true,
15654  focusableElements: 'input, select, option, textarea, button, video, label',
15655  // Overrides
15656  width: null,
15657  height: null,
15658  //
15659  preventInteractionOnTransition: false,
15660  // ssr
15661  userAgent: null,
15662  url: null,
15663  // To support iOS's swipe-to-go-back gesture (when being used in-app).
15664  edgeSwipeDetection: false,
15665  edgeSwipeThreshold: 20,
15666  // Autoheight
15667  autoHeight: false,
15668  // Set wrapper width
15669  setWrapperSize: false,
15670  // Virtual Translate
15671  virtualTranslate: false,
15672  // Effects
15673  effect: 'slide',
15674  // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
15675
15676  // Breakpoints
15677  breakpoints: undefined,
15678  breakpointsBase: 'window',
15679  // Slides grid
15680  spaceBetween: 0,
15681  slidesPerView: 1,
15682  slidesPerGroup: 1,
15683  slidesPerGroupSkip: 0,
15684  slidesPerGroupAuto: false,
15685  centeredSlides: false,
15686  centeredSlidesBounds: false,
15687  slidesOffsetBefore: 0,
15688  // in px
15689  slidesOffsetAfter: 0,
15690  // in px
15691  normalizeSlideIndex: true,
15692  centerInsufficientSlides: false,
15693  // Disable swiper and hide navigation when container not overflow
15694  watchOverflow: true,
15695  // Round length
15696  roundLengths: false,
15697  // Touches
15698  touchRatio: 1,
15699  touchAngle: 45,
15700  simulateTouch: true,
15701  shortSwipes: true,
15702  longSwipes: true,
15703  longSwipesRatio: 0.5,
15704  longSwipesMs: 300,
15705  followFinger: true,
15706  allowTouchMove: true,
15707  threshold: 5,
15708  touchMoveStopPropagation: false,
15709  touchStartPreventDefault: true,
15710  touchStartForcePreventDefault: false,
15711  touchReleaseOnEdges: false,
15712  // Unique Navigation Elements
15713  uniqueNavElements: true,
15714  // Resistance
15715  resistance: true,
15716  resistanceRatio: 0.85,
15717  // Progress
15718  watchSlidesProgress: false,
15719  // Cursor
15720  grabCursor: false,
15721  // Clicks
15722  preventClicks: true,
15723  preventClicksPropagation: true,
15724  slideToClickedSlide: false,
15725  // loop
15726  loop: false,
15727  loopAddBlankSlides: true,
15728  loopAdditionalSlides: 0,
15729  loopPreventsSliding: true,
15730  // rewind
15731  rewind: false,
15732  // Swiping/no swiping
15733  allowSlidePrev: true,
15734  allowSlideNext: true,
15735  swipeHandler: null,
15736  // '.swipe-handler',
15737  noSwiping: true,
15738  noSwipingClass: 'swiper-no-swiping',
15739  noSwipingSelector: null,
15740  // Passive Listeners
15741  passiveListeners: true,
15742  maxBackfaceHiddenSlides: 10,
15743  // NS
15744  containerModifierClass: 'swiper-',
15745  // NEW
15746  slideClass: 'swiper-slide',
15747  slideBlankClass: 'swiper-slide-blank',
15748  slideActiveClass: 'swiper-slide-active',
15749  slideVisibleClass: 'swiper-slide-visible',
15750  slideFullyVisibleClass: 'swiper-slide-fully-visible',
15751  slideNextClass: 'swiper-slide-next',
15752  slidePrevClass: 'swiper-slide-prev',
15753  wrapperClass: 'swiper-wrapper',
15754  lazyPreloaderClass: 'swiper-lazy-preloader',
15755  lazyPreloadPrevNext: 0,
15756  // Callbacks
15757  runCallbacksOnInit: true,
15758  // Internals
15759  _emitClasses: false
15760};
15761
15762function moduleExtendParams(params, allModulesParams) {
15763  return function extendParams(obj) {
15764    if (obj === void 0) {
15765      obj = {};
15766    }
15767    const moduleParamName = Object.keys(obj)[0];
15768    const moduleParams = obj[moduleParamName];
15769    if (typeof moduleParams !== 'object' || moduleParams === null) {
15770      utils_extend(allModulesParams, obj);
15771      return;
15772    }
15773    if (params[moduleParamName] === true) {
15774      params[moduleParamName] = {
15775        enabled: true
15776      };
15777    }
15778    if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
15779      params[moduleParamName].auto = true;
15780    }
15781    if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
15782      params[moduleParamName].auto = true;
15783    }
15784    if (!(moduleParamName in params && 'enabled' in moduleParams)) {
15785      utils_extend(allModulesParams, obj);
15786      return;
15787    }
15788    if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
15789      params[moduleParamName].enabled = true;
15790    }
15791    if (!params[moduleParamName]) params[moduleParamName] = {
15792      enabled: false
15793    };
15794    utils_extend(allModulesParams, obj);
15795  };
15796}
15797
15798/* eslint no-param-reassign: "off" */
15799const prototypes = {
15800  eventsEmitter,
15801  update,
15802  translate,
15803  transition,
15804  slide,
15805  loop,
15806  grabCursor,
15807  events: events$1,
15808  breakpoints,
15809  checkOverflow: checkOverflow$1,
15810  classes
15811};
15812const extendedDefaults = {};
15813class Swiper {
15814  constructor() {
15815    let el;
15816    let params;
15817    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
15818      args[_key] = arguments[_key];
15819    }
15820    if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
15821      params = args[0];
15822    } else {
15823      [el, params] = args;
15824    }
15825    if (!params) params = {};
15826    params = utils_extend({}, params);
15827    if (el && !params.el) params.el = el;
15828    const document = ssr_window_esm_getDocument();
15829    if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
15830      const swipers = [];
15831      document.querySelectorAll(params.el).forEach(containerEl => {
15832        const newParams = utils_extend({}, params, {
15833          el: containerEl
15834        });
15835        swipers.push(new Swiper(newParams));
15836      });
15837      // eslint-disable-next-line no-constructor-return
15838      return swipers;
15839    }
15840
15841    // Swiper Instance
15842    const swiper = this;
15843    swiper.__swiper__ = true;
15844    swiper.support = getSupport();
15845    swiper.device = getDevice({
15846      userAgent: params.userAgent
15847    });
15848    swiper.browser = getBrowser();
15849    swiper.eventsListeners = {};
15850    swiper.eventsAnyListeners = [];
15851    swiper.modules = [...swiper.__modules__];
15852    if (params.modules && Array.isArray(params.modules)) {
15853      swiper.modules.push(...params.modules);
15854    }
15855    const allModulesParams = {};
15856    swiper.modules.forEach(mod => {
15857      mod({
15858        params,
15859        swiper,
15860        extendParams: moduleExtendParams(params, allModulesParams),
15861        on: swiper.on.bind(swiper),
15862        once: swiper.once.bind(swiper),
15863        off: swiper.off.bind(swiper),
15864        emit: swiper.emit.bind(swiper)
15865      });
15866    });
15867
15868    // Extend defaults with modules params
15869    const swiperParams = utils_extend({}, defaults, allModulesParams);
15870
15871    // Extend defaults with passed params
15872    swiper.params = utils_extend({}, swiperParams, extendedDefaults, params);
15873    swiper.originalParams = utils_extend({}, swiper.params);
15874    swiper.passedParams = utils_extend({}, params);
15875
15876    // add event listeners
15877    if (swiper.params && swiper.params.on) {
15878      Object.keys(swiper.params.on).forEach(eventName => {
15879        swiper.on(eventName, swiper.params.on[eventName]);
15880      });
15881    }
15882    if (swiper.params && swiper.params.onAny) {
15883      swiper.onAny(swiper.params.onAny);
15884    }
15885
15886    // Extend Swiper
15887    Object.assign(swiper, {
15888      enabled: swiper.params.enabled,
15889      el,
15890      // Classes
15891      classNames: [],
15892      // Slides
15893      slides: [],
15894      slidesGrid: [],
15895      snapGrid: [],
15896      slidesSizesGrid: [],
15897      // isDirection
15898      isHorizontal() {
15899        return swiper.params.direction === 'horizontal';
15900      },
15901      isVertical() {
15902        return swiper.params.direction === 'vertical';
15903      },
15904      // Indexes
15905      activeIndex: 0,
15906      realIndex: 0,
15907      //
15908      isBeginning: true,
15909      isEnd: false,
15910      // Props
15911      translate: 0,
15912      previousTranslate: 0,
15913      progress: 0,
15914      velocity: 0,
15915      animating: false,
15916      cssOverflowAdjustment() {
15917        // Returns 0 unless `translate` is > 2**23
15918        // Should be subtracted from css values to prevent overflow
15919        return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
15920      },
15921      // Locks
15922      allowSlideNext: swiper.params.allowSlideNext,
15923      allowSlidePrev: swiper.params.allowSlidePrev,
15924      // Touch Events
15925      touchEventsData: {
15926        isTouched: undefined,
15927        isMoved: undefined,
15928        allowTouchCallbacks: undefined,
15929        touchStartTime: undefined,
15930        isScrolling: undefined,
15931        currentTranslate: undefined,
15932        startTranslate: undefined,
15933        allowThresholdMove: undefined,
15934        // Form elements to match
15935        focusableElements: swiper.params.focusableElements,
15936        // Last click time
15937        lastClickTime: 0,
15938        clickTimeout: undefined,
15939        // Velocities
15940        velocities: [],
15941        allowMomentumBounce: undefined,
15942        startMoving: undefined,
15943        pointerId: null,
15944        touchId: null
15945      },
15946      // Clicks
15947      allowClick: true,
15948      // Touches
15949      allowTouchMove: swiper.params.allowTouchMove,
15950      touches: {
15951        startX: 0,
15952        startY: 0,
15953        currentX: 0,
15954        currentY: 0,
15955        diff: 0
15956      },
15957      // Images
15958      imagesToLoad: [],
15959      imagesLoaded: 0
15960    });
15961    swiper.emit('_swiper');
15962
15963    // Init
15964    if (swiper.params.init) {
15965      swiper.init();
15966    }
15967
15968    // Return app instance
15969    // eslint-disable-next-line no-constructor-return
15970    return swiper;
15971  }
15972  getDirectionLabel(property) {
15973    if (this.isHorizontal()) {
15974      return property;
15975    }
15976    // prettier-ignore
15977    return {
15978      'width': 'height',
15979      'margin-top': 'margin-left',
15980      'margin-bottom ': 'margin-right',
15981      'margin-left': 'margin-top',
15982      'margin-right': 'margin-bottom',
15983      'padding-left': 'padding-top',
15984      'padding-right': 'padding-bottom',
15985      'marginRight': 'marginBottom'
15986    }[property];
15987  }
15988  getSlideIndex(slideEl) {
15989    const {
15990      slidesEl,
15991      params
15992    } = this;
15993    const slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
15994    const firstSlideIndex = utils_elementIndex(slides[0]);
15995    return utils_elementIndex(slideEl) - firstSlideIndex;
15996  }
15997  getSlideIndexByData(index) {
15998    return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index));
15999  }
16000  getSlideIndexWhenGrid(index) {
16001    if (this.grid && this.params.grid && this.params.grid.rows > 1) {
16002      if (this.params.grid.fill === 'column') {
16003        index = Math.floor(index / this.params.grid.rows);
16004      } else if (this.params.grid.fill === 'row') {
16005        index = index % Math.ceil(this.slides.length / this.params.grid.rows);
16006      }
16007    }
16008    return index;
16009  }
16010  recalcSlides() {
16011    const swiper = this;
16012    const {
16013      slidesEl,
16014      params
16015    } = swiper;
16016    swiper.slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
16017  }
16018  enable() {
16019    const swiper = this;
16020    if (swiper.enabled) return;
16021    swiper.enabled = true;
16022    if (swiper.params.grabCursor) {
16023      swiper.setGrabCursor();
16024    }
16025    swiper.emit('enable');
16026  }
16027  disable() {
16028    const swiper = this;
16029    if (!swiper.enabled) return;
16030    swiper.enabled = false;
16031    if (swiper.params.grabCursor) {
16032      swiper.unsetGrabCursor();
16033    }
16034    swiper.emit('disable');
16035  }
16036  setProgress(progress, speed) {
16037    const swiper = this;
16038    progress = Math.min(Math.max(progress, 0), 1);
16039    const min = swiper.minTranslate();
16040    const max = swiper.maxTranslate();
16041    const current = (max - min) * progress + min;
16042    swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
16043    swiper.updateActiveIndex();
16044    swiper.updateSlidesClasses();
16045  }
16046  emitContainerClasses() {
16047    const swiper = this;
16048    if (!swiper.params._emitClasses || !swiper.el) return;
16049    const cls = swiper.el.className.split(' ').filter(className => {
16050      return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
16051    });
16052    swiper.emit('_containerClasses', cls.join(' '));
16053  }
16054  getSlideClasses(slideEl) {
16055    const swiper = this;
16056    if (swiper.destroyed) return '';
16057    return slideEl.className.split(' ').filter(className => {
16058      return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
16059    }).join(' ');
16060  }
16061  emitSlidesClasses() {
16062    const swiper = this;
16063    if (!swiper.params._emitClasses || !swiper.el) return;
16064    const updates = [];
vendor: 4,378 bytes, lines 16065-16196
16065    swiper.slides.forEach(slideEl => {
16066      const classNames = swiper.getSlideClasses(slideEl);
16067      updates.push({
16068        slideEl,
16069        classNames
16070      });
16071      swiper.emit('_slideClass', slideEl, classNames);
16072    });
16073    swiper.emit('_slideClasses', updates);
16074  }
16075  slidesPerViewDynamic(view, exact) {
16076    if (view === void 0) {
16077      view = 'current';
16078    }
16079    if (exact === void 0) {
16080      exact = false;
16081    }
16082    const swiper = this;
16083    const {
16084      params,
16085      slides,
16086      slidesGrid,
16087      slidesSizesGrid,
16088      size: swiperSize,
16089      activeIndex
16090    } = swiper;
16091    let spv = 1;
16092    if (typeof params.slidesPerView === 'number') return params.slidesPerView;
16093    if (params.centeredSlides) {
16094      let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
16095      let breakLoop;
16096      for (let i = activeIndex + 1; i < slides.length; i += 1) {
16097        if (slides[i] && !breakLoop) {
16098          slideSize += Math.ceil(slides[i].swiperSlideSize);
16099          spv += 1;
16100          if (slideSize > swiperSize) breakLoop = true;
16101        }
16102      }
16103      for (let i = activeIndex - 1; i >= 0; i -= 1) {
16104        if (slides[i] && !breakLoop) {
16105          slideSize += slides[i].swiperSlideSize;
16106          spv += 1;
16107          if (slideSize > swiperSize) breakLoop = true;
16108        }
16109      }
16110    } else {
16111      // eslint-disable-next-line
16112      if (view === 'current') {
16113        for (let i = activeIndex + 1; i < slides.length; i += 1) {
16114          const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
16115          if (slideInView) {
16116            spv += 1;
16117          }
16118        }
16119      } else {
16120        // previous
16121        for (let i = activeIndex - 1; i >= 0; i -= 1) {
16122          const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
16123          if (slideInView) {
16124            spv += 1;
16125          }
16126        }
16127      }
16128    }
16129    return spv;
16130  }
16131  update() {
16132    const swiper = this;
16133    if (!swiper || swiper.destroyed) return;
16134    const {
16135      snapGrid,
16136      params
16137    } = swiper;
16138    // Breakpoints
16139    if (params.breakpoints) {
16140      swiper.setBreakpoint();
16141    }
16142    [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
16143      if (imageEl.complete) {
16144        processLazyPreloader(swiper, imageEl);
16145      }
16146    });
16147    swiper.updateSize();
16148    swiper.updateSlides();
16149    swiper.updateProgress();
16150    swiper.updateSlidesClasses();
16151    function setTranslate() {
16152      const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
16153      const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
16154      swiper.setTranslate(newTranslate);
16155      swiper.updateActiveIndex();
16156      swiper.updateSlidesClasses();
16157    }
16158    let translated;
16159    if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
16160      setTranslate();
16161      if (params.autoHeight) {
16162        swiper.updateAutoHeight();
16163      }
16164    } else {
16165      if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
16166        const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
16167        translated = swiper.slideTo(slides.length - 1, 0, false, true);
16168      } else {
16169        translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
16170      }
16171      if (!translated) {
16172        setTranslate();
16173      }
16174    }
16175    if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
16176      swiper.checkOverflow();
16177    }
16178    swiper.emit('update');
16179  }
16180  changeDirection(newDirection, needUpdate) {
16181    if (needUpdate === void 0) {
16182      needUpdate = true;
16183    }
16184    const swiper = this;
16185    const currentDirection = swiper.params.direction;
16186    if (!newDirection) {
16187      // eslint-disable-next-line
16188      newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
16189    }
16190    if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
16191      return swiper;
16192    }
16193    swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
16194    swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
16195    swiper.emitContainerClasses();
16196    swiper.params.direction = newDirection;
vendor: 1,995 bytes, lines 16197-16254
16197    swiper.slides.forEach(slideEl => {
16198      if (newDirection === 'vertical') {
16199        slideEl.style.width = '';
16200      } else {
16201        slideEl.style.height = '';
16202      }
16203    });
16204    swiper.emit('changeDirection');
16205    if (needUpdate) swiper.update();
16206    return swiper;
16207  }
16208  changeLanguageDirection(direction) {
16209    const swiper = this;
16210    if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
16211    swiper.rtl = direction === 'rtl';
16212    swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
16213    if (swiper.rtl) {
16214      swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
16215      swiper.el.dir = 'rtl';
16216    } else {
16217      swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
16218      swiper.el.dir = 'ltr';
16219    }
16220    swiper.update();
16221  }
16222  mount(element) {
16223    const swiper = this;
16224    if (swiper.mounted) return true;
16225
16226    // Find el
16227    let el = element || swiper.params.el;
16228    if (typeof el === 'string') {
16229      el = document.querySelector(el);
16230    }
16231    if (!el) {
16232      return false;
16233    }
16234    el.swiper = swiper;
16235    if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
16236      swiper.isElement = true;
16237    }
16238    const getWrapperSelector = () => {
16239      return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
16240    };
16241    const getWrapper = () => {
16242      if (el && el.shadowRoot && el.shadowRoot.querySelector) {
16243        const res = el.shadowRoot.querySelector(getWrapperSelector());
16244        // Children needs to return slot items
16245        return res;
16246      }
16247      return utils_elementChildren(el, getWrapperSelector())[0];
16248    };
16249    // Find Wrapper
16250    let wrapperEl = getWrapper();
16251    if (!wrapperEl && swiper.params.createElements) {
16252      wrapperEl = utils_createElement('div', swiper.params.wrapperClass);
16253      el.append(wrapperEl);
16254      utils_elementChildren(el, `.${swiper.params.slideClass}
16254`).forEach(slideEl => {
16255        wrapperEl.append(slideEl);
16256      });
16257    }
16258    Object.assign(swiper, {
16259      el,
16260      wrapperEl,
16261      slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
16262      hostEl: swiper.isElement ? el.parentNode.host : el,
16263      mounted: true,
16264      // RTL
16265      rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
16266      rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
16267      wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
16268    });
16269    return true;
16270  }
16271  init(el) {
16272    const swiper = this;
16273    if (swiper.initialized) return swiper;
16274    const mounted = swiper.mount(el);
16275    if (mounted === false) return swiper;
16276    swiper.emit('beforeInit');
16277
16278    // Set breakpoint
16279    if (swiper.params.breakpoints) {
16280      swiper.setBreakpoint();
16281    }
16282
16283    // Add Classes
16284    swiper.addClasses();
16285
16286    // Update size
16287    swiper.updateSize();
16288
16289    // Update slides
16290    swiper.updateSlides();
16291    if (swiper.params.watchOverflow) {
16292      swiper.checkOverflow();
16293    }
16294
16295    // Set Grab Cursor
16296    if (swiper.params.grabCursor && swiper.enabled) {
16297      swiper.setGrabCursor();
16298    }
16299
16300    // Slide To Initial Slide
16301    if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
16302      swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
16303    } else {
16304      swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
16305    }
16306
16307    // Create loop
16308    if (swiper.params.loop) {
16309      swiper.loopCreate(undefined, true);
16310    }
16311
16312    // Attach events
16313    swiper.attachEvents();
16314    const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
16315    if (swiper.isElement) {
16316      lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
16317    }
16318    lazyElements.forEach(imageEl => {
16319      if (imageEl.complete) {
16320        processLazyPreloader(swiper, imageEl);
16321      } else {
16322        imageEl.addEventListener('load', e => {
16323          processLazyPreloader(swiper, e.target);
16324        });
16325      }
16326    });
16327    preload(swiper);
16328
16329    // Init Flag
16330    swiper.initialized = true;
16331    preload(swiper);
16332
16333    // Emit
16334    swiper.emit('init');
16335    swiper.emit('afterInit');
16336    return swiper;
16337  }
16338  destroy(deleteInstance, cleanStyles) {
16339    if (deleteInstance === void 0) {
16340      deleteInstance = true;
16341    }
16342    if (cleanStyles === void 0) {
16343      cleanStyles = true;
16344    }
16345    const swiper = this;
16346    const {
16347      params,
16348      el,
16349      wrapperEl,
16350      slides
16351    } = swiper;
16352    if (typeof swiper.params === 'undefined' || swiper.destroyed) {
16353      return null;
16354    }
16355    swiper.emit('beforeDestroy');
16356
16357    // Init Flag
16358    swiper.initialized = false;
16359
16360    // Detach events
16361    swiper.detachEvents();
16362
16363    // Destroy loop
16364    if (params.loop) {
16365      swiper.loopDestroy();
16366    }
16367
16368    // Cleanup styles
16369    if (cleanStyles) {
16370      swiper.removeClasses();
16371      if (el && typeof el !== 'string') {
16372        el.removeAttribute('style');
16373      }
16374      if (wrapperEl) {
16375        wrapperEl.removeAttribute('style');
16376      }
16377      if (slides && slides.length) {
vendor: 4,573 bytes, lines 16378-16545
16378        slides.forEach(slideEl => {
16379          slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
16380          slideEl.removeAttribute('style');
16381          slideEl.removeAttribute('data-swiper-slide-index');
16382        });
16383      }
16384    }
16385    swiper.emit('destroy');
16386
16387    // Detach emitter events
16388    Object.keys(swiper.eventsListeners).forEach(eventName => {
16389      swiper.off(eventName);
16390    });
16391    if (deleteInstance !== false) {
16392      if (swiper.el && typeof swiper.el !== 'string') {
16393        swiper.el.swiper = null;
16394      }
16395      deleteProps(swiper);
16396    }
16397    swiper.destroyed = true;
16398    return null;
16399  }
16400  static extendDefaults(newDefaults) {
16401    utils_extend(extendedDefaults, newDefaults);
16402  }
16403  static get extendedDefaults() {
16404    return extendedDefaults;
16405  }
16406  static get defaults() {
16407    return defaults;
16408  }
16409  static installModule(mod) {
16410    if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
16411    const modules = Swiper.prototype.__modules__;
16412    if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
16413      modules.push(mod);
16414    }
16415  }
16416  static use(module) {
16417    if (Array.isArray(module)) {
16418      module.forEach(m => Swiper.installModule(m));
16419      return Swiper;
16420    }
16421    Swiper.installModule(module);
16422    return Swiper;
16423  }
16424}
16425Object.keys(prototypes).forEach(prototypeGroup => {
16426  Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
16427    Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
16428  });
16429});
16430Swiper.use([Resize, Observer]);
16431
16432
16433
16434;// ./node_modules/swiper/swiper.mjs
16435/**
16436 * Swiper 11.2.10
16437 * Most modern mobile touch slider and framework with hardware accelerated transitions
16438 * https://swiperjs.com
16439 *
16440 * Copyright 2014-2025 Vladimir Kharlampidi
16441 *
16442 * Released under the MIT License
16443 *
16444 * Released on: June 28, 2025
16445 */
16446
16447
16448
16449;// ./node_modules/swiper/modules/virtual.mjs
16450
16451
16452
16453function Virtual(_ref) {
16454  let {
16455    swiper,
16456    extendParams,
16457    on,
16458    emit
16459  } = _ref;
16460  extendParams({
16461    virtual: {
16462      enabled: false,
16463      slides: [],
16464      cache: true,
16465      renderSlide: null,
16466      renderExternal: null,
16467      renderExternalUpdate: true,
16468      addSlidesBefore: 0,
16469      addSlidesAfter: 0
16470    }
16471  });
16472  let cssModeTimeout;
16473  const document = getDocument();
16474  swiper.virtual = {
16475    cache: {},
16476    from: undefined,
16477    to: undefined,
16478    slides: [],
16479    offset: 0,
16480    slidesGrid: []
16481  };
16482  const tempDOM = document.createElement('div');
16483  function renderSlide(slide, index) {
16484    const params = swiper.params.virtual;
16485    if (params.cache && swiper.virtual.cache[index]) {
16486      return swiper.virtual.cache[index];
16487    }
16488    // eslint-disable-next-line
16489    let slideEl;
16490    if (params.renderSlide) {
16491      slideEl = params.renderSlide.call(swiper, slide, index);
16492      if (typeof slideEl === 'string') {
16493        setInnerHTML(tempDOM, slideEl);
16494        slideEl = tempDOM.children[0];
16495      }
16496    } else if (swiper.isElement) {
16497      slideEl = createElement('swiper-slide');
16498    } else {
16499      slideEl = createElement('div', swiper.params.slideClass);
16500    }
16501    slideEl.setAttribute('data-swiper-slide-index', index);
16502    if (!params.renderSlide) {
16503      setInnerHTML(slideEl, slide);
16504    }
16505    if (params.cache) {
16506      swiper.virtual.cache[index] = slideEl;
16507    }
16508    return slideEl;
16509  }
16510  function update(force, beforeInit, forceActiveIndex) {
16511    const {
16512      slidesPerView,
16513      slidesPerGroup,
16514      centeredSlides,
16515      loop: isLoop,
16516      initialSlide
16517    } = swiper.params;
16518    if (beforeInit && !isLoop && initialSlide > 0) {
16519      return;
16520    }
16521    const {
16522      addSlidesBefore,
16523      addSlidesAfter
16524    } = swiper.params.virtual;
16525    const {
16526      from: previousFrom,
16527      to: previousTo,
16528      slides,
16529      slidesGrid: previousSlidesGrid,
16530      offset: previousOffset
16531    } = swiper.virtual;
16532    if (!swiper.params.cssMode) {
16533      swiper.updateActiveIndex();
16534    }
16535    const activeIndex = typeof forceActiveIndex === 'undefined' ? swiper.activeIndex || 0 : forceActiveIndex;
16536    let offsetProp;
16537    if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
16538    let slidesAfter;
16539    let slidesBefore;
16540    if (centeredSlides) {
16541      slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
16542      slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
16543    } else {
16544      slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
16545      slidesBefore = (isLoop ? slidesPerView
vendor: 3,781 bytes, lines 16545-16658
16545 : slidesPerGroup) + addSlidesBefore;
16546    }
16547    let from = activeIndex - slidesBefore;
16548    let to = activeIndex + slidesAfter;
16549    if (!isLoop) {
16550      from = Math.max(from, 0);
16551      to = Math.min(to, slides.length - 1);
16552    }
16553    let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
16554    if (isLoop && activeIndex >= slidesBefore) {
16555      from -= slidesBefore;
16556      if (!centeredSlides) offset += swiper.slidesGrid[0];
16557    } else if (isLoop && activeIndex < slidesBefore) {
16558      from = -slidesBefore;
16559      if (centeredSlides) offset += swiper.slidesGrid[0];
16560    }
16561    Object.assign(swiper.virtual, {
16562      from,
16563      to,
16564      offset,
16565      slidesGrid: swiper.slidesGrid,
16566      slidesBefore,
16567      slidesAfter
16568    });
16569    function onRendered() {
16570      swiper.updateSlides();
16571      swiper.updateProgress();
16572      swiper.updateSlidesClasses();
16573      emit('virtualUpdate');
16574    }
16575    if (previousFrom === from && previousTo === to && !force) {
16576      if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
16577        swiper.slides.forEach(slideEl => {
16578          slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
16579        });
16580      }
16581      swiper.updateProgress();
16582      emit('virtualUpdate');
16583      return;
16584    }
16585    if (swiper.params.virtual.renderExternal) {
16586      swiper.params.virtual.renderExternal.call(swiper, {
16587        offset,
16588        from,
16589        to,
16590        slides: function getSlides() {
16591          const slidesToRender = [];
16592          for (let i = from; i <= to; i += 1) {
16593            slidesToRender.push(slides[i]);
16594          }
16595          return slidesToRender;
16596        }()
16597      });
16598      if (swiper.params.virtual.renderExternalUpdate) {
16599        onRendered();
16600      } else {
16601        emit('virtualUpdate');
16602      }
16603      return;
16604    }
16605    const prependIndexes = [];
16606    const appendIndexes = [];
16607    const getSlideIndex = index => {
16608      let slideIndex = index;
16609      if (index < 0) {
16610        slideIndex = slides.length + index;
16611      } else if (slideIndex >= slides.length) {
16612        // eslint-disable-next-line
16613        slideIndex = slideIndex - slides.length;
16614      }
16615      return slideIndex;
16616    };
16617    if (force) {
16618      swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)).forEach(slideEl => {
16619        slideEl.remove();
16620      });
16621    } else {
16622      for (let i = previousFrom; i <= previousTo; i += 1) {
16623        if (i < from || i > to) {
16624          const slideIndex = getSlideIndex(i);
16625          swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
16626            slideEl.remove();
16627          });
16628        }
16629      }
16630    }
16631    const loopFrom = isLoop ? -slides.length : 0;
16632    const loopTo = isLoop ? slides.length * 2 : slides.length;
16633    for (let i = loopFrom; i < loopTo; i += 1) {
16634      if (i >= from && i <= to) {
16635        const slideIndex = getSlideIndex(i);
16636        if (typeof previousTo === 'undefined' || force) {
16637          appendIndexes.push(slideIndex);
16638        } else {
16639          if (i > previousTo) appendIndexes.push(slideIndex);
16640          if (i < previousFrom) prependIndexes.push(slideIndex);
16641        }
16642      }
16643    }
16644    appendIndexes.forEach(index => {
16645      swiper.slidesEl.append(renderSlide(slides[index], index));
16646    });
16647    if (isLoop) {
16648      for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
16649        const index = prependIndexes[i];
16650        swiper.slidesEl.prepend(renderSlide(slides[index], index));
16651      }
16652    } else {
16653      prependIndexes.sort((a, b) => b - a);
16654      prependIndexes.forEach(index => {
16655        swiper.slidesEl.prepend(renderSlide(slides[index], index));
16656      });
16657    }
16658    
16658elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(sli
vendor: 38,634 bytes, lines 16658-17745
16658deEl => {
16659      slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
16660    });
16661    onRendered();
16662  }
16663  function appendSlide(slides) {
16664    if (typeof slides === 'object' && 'length' in slides) {
16665      for (let i = 0; i < slides.length; i += 1) {
16666        if (slides[i]) swiper.virtual.slides.push(slides[i]);
16667      }
16668    } else {
16669      swiper.virtual.slides.push(slides);
16670    }
16671    update(true);
16672  }
16673  function prependSlide(slides) {
16674    const activeIndex = swiper.activeIndex;
16675    let newActiveIndex = activeIndex + 1;
16676    let numberOfNewSlides = 1;
16677    if (Array.isArray(slides)) {
16678      for (let i = 0; i < slides.length; i += 1) {
16679        if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
16680      }
16681      newActiveIndex = activeIndex + slides.length;
16682      numberOfNewSlides = slides.length;
16683    } else {
16684      swiper.virtual.slides.unshift(slides);
16685    }
16686    if (swiper.params.virtual.cache) {
16687      const cache = swiper.virtual.cache;
16688      const newCache = {};
16689      Object.keys(cache).forEach(cachedIndex => {
16690        const cachedEl = cache[cachedIndex];
16691        const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
16692        if (cachedElIndex) {
16693          cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
16694        }
16695        newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
16696      });
16697      swiper.virtual.cache = newCache;
16698    }
16699    update(true);
16700    swiper.slideTo(newActiveIndex, 0);
16701  }
16702  function removeSlide(slidesIndexes) {
16703    if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
16704    let activeIndex = swiper.activeIndex;
16705    if (Array.isArray(slidesIndexes)) {
16706      for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
16707        if (swiper.params.virtual.cache) {
16708          delete swiper.virtual.cache[slidesIndexes[i]];
16709          // shift cache indexes
16710          Object.keys(swiper.virtual.cache).forEach(key => {
16711            if (key > slidesIndexes) {
16712              swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
16713              swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
16714              delete swiper.virtual.cache[key];
16715            }
16716          });
16717        }
16718        swiper.virtual.slides.splice(slidesIndexes[i], 1);
16719        if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
16720        activeIndex = Math.max(activeIndex, 0);
16721      }
16722    } else {
16723      if (swiper.params.virtual.cache) {
16724        delete swiper.virtual.cache[slidesIndexes];
16725        // shift cache indexes
16726        Object.keys(swiper.virtual.cache).forEach(key => {
16727          if (key > slidesIndexes) {
16728            swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
16729            swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
16730            delete swiper.virtual.cache[key];
16731          }
16732        });
16733      }
16734      swiper.virtual.slides.splice(slidesIndexes, 1);
16735      if (slidesIndexes < activeIndex) activeIndex -= 1;
16736      activeIndex = Math.max(activeIndex, 0);
16737    }
16738    update(true);
16739    swiper.slideTo(activeIndex, 0);
16740  }
16741  function removeAllSlides() {
16742    swiper.virtual.slides = [];
16743    if (swiper.params.virtual.cache) {
16744      swiper.virtual.cache = {};
16745    }
16746    update(true);
16747    swiper.slideTo(0, 0);
16748  }
16749  on('beforeInit', () => {
16750    if (!swiper.params.virtual.enabled) return;
16751    let domSlidesAssigned;
16752    if (typeof swiper.passedParams.virtual.slides === 'undefined') {
16753      const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
16754      if (slides && slides.length) {
16755        swiper.virtual.slides = [...slides];
16756        domSlidesAssigned = true;
16757        slides.forEach((slideEl, slideIndex) => {
16758          slideEl.setAttribute('data-swiper-slide-index', slideIndex);
16759          swiper.virtual.cache[slideIndex] = slideEl;
16760          slideEl.remove();
16761        });
16762      }
16763    }
16764    if (!domSlidesAssigned) {
16765      swiper.virtual.slides = swiper.params.virtual.slides;
16766    }
16767    swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
16768    swiper.params.watchSlidesProgress = true;
16769    swiper.originalParams.watchSlidesProgress = true;
16770    update(false, true);
16771  });
16772  on('setTranslate', () => {
16773    if (!swiper.params.virtual.enabled) return;
16774    if (swiper.params.cssMode && !swiper._immediateVirtual) {
16775      clearTimeout(cssModeTimeout);
16776      cssModeTimeout = setTimeout(() => {
16777        update();
16778      }, 100);
16779    } else {
16780      update();
16781    }
16782  });
16783  on('init update resize', () => {
16784    if (!swiper.params.virtual.enabled) return;
16785    if (swiper.params.cssMode) {
16786      setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
16787    }
16788  });
16789  Object.assign(swiper.virtual, {
16790    appendSlide,
16791    prependSlide,
16792    removeSlide,
16793    removeAllSlides,
16794    update
16795  });
16796}
16797
16798
16799
16800;// ./node_modules/swiper/modules/keyboard.mjs
16801
16802
16803
16804/* eslint-disable consistent-return */
16805function Keyboard(_ref) {
16806  let {
16807    swiper,
16808    extendParams,
16809    on,
16810    emit
16811  } = _ref;
16812  const document = getDocument();
16813  const window = getWindow();
16814  swiper.keyboard = {
16815    enabled: false
16816  };
16817  extendParams({
16818    keyboard: {
16819      enabled: false,
16820      onlyInViewport: true,
16821      pageUpDown: true
16822    }
16823  });
16824  function handle(event) {
16825    if (!swiper.enabled) return;
16826    const {
16827      rtlTranslate: rtl
16828    } = swiper;
16829    let e = event;
16830    if (e.originalEvent) e = e.originalEvent; // jquery fix
16831    const kc = e.keyCode || e.charCode;
16832    const pageUpDown = swiper.params.keyboard.pageUpDown;
16833    const isPageUp = pageUpDown && kc === 33;
16834    const isPageDown = pageUpDown && kc === 34;
16835    const isArrowLeft = kc === 37;
16836    const isArrowRight = kc === 39;
16837    const isArrowUp = kc === 38;
16838    const isArrowDown = kc === 40;
16839    // Directions locks
16840    if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
16841      return false;
16842    }
16843    if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
16844      return false;
16845    }
16846    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
16847      return undefined;
16848    }
16849    if (document.activeElement && (document.activeElement.isContentEditable || document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea'))) {
16850      return undefined;
16851    }
16852    if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
16853      let inView = false;
16854      // Check that swiper should be inside of visible area of window
16855      if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) {
16856        return undefined;
16857      }
16858      const el = swiper.el;
16859      const swiperWidth = el.clientWidth;
16860      const swiperHeight = el.clientHeight;
16861      const windowWidth = window.innerWidth;
16862      const windowHeight = window.innerHeight;
16863      const swiperOffset = elementOffset(el);
16864      if (rtl) swiperOffset.left -= el.scrollLeft;
16865      const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
16866      for (let i = 0; i < swiperCoord.length; i += 1) {
16867        const point = swiperCoord[i];
16868        if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
16869          if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
16870          inView = true;
16871        }
16872      }
16873      if (!inView) return undefined;
16874    }
16875    if (swiper.isHorizontal()) {
16876      if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
16877        if (e.preventDefault) e.preventDefault();else e.returnValue = false;
16878      }
16879      if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
16880      if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
16881    } else {
16882      if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
16883        if (e.preventDefault) e.preventDefault();else e.returnValue = false;
16884      }
16885      if (isPageDown || isArrowDown) swiper.slideNext();
16886      if (isPageUp || isArrowUp) swiper.slidePrev();
16887    }
16888    emit('keyPress', kc);
16889    return undefined;
16890  }
16891  function enable() {
16892    if (swiper.keyboard.enabled) return;
16893    document.addEventListener('keydown', handle);
16894    swiper.keyboard.enabled = true;
16895  }
16896  function disable() {
16897    if (!swiper.keyboard.enabled) return;
16898    document.removeEventListener('keydown', handle);
16899    swiper.keyboard.enabled = false;
16900  }
16901  on('init', () => {
16902    if (swiper.params.keyboard.enabled) {
16903      enable();
16904    }
16905  });
16906  on('destroy', () => {
16907    if (swiper.keyboard.enabled) {
16908      disable();
16909    }
16910  });
16911  Object.assign(swiper.keyboard, {
16912    enable,
16913    disable
16914  });
16915}
16916
16917
16918
16919;// ./node_modules/swiper/modules/mousewheel.mjs
16920
16921
16922
16923/* eslint-disable consistent-return */
16924function Mousewheel(_ref) {
16925  let {
16926    swiper,
16927    extendParams,
16928    on,
16929    emit
16930  } = _ref;
16931  const window = getWindow();
16932  extendParams({
16933    mousewheel: {
16934      enabled: false,
16935      releaseOnEdges: false,
16936      invert: false,
16937      forceToAxis: false,
16938      sensitivity: 1,
16939      eventsTarget: 'container',
16940      thresholdDelta: null,
16941      thresholdTime: null,
16942      noMousewheelClass: 'swiper-no-mousewheel'
16943    }
16944  });
16945  swiper.mousewheel = {
16946    enabled: false
16947  };
16948  let timeout;
16949  let lastScrollTime = now();
16950  let lastEventBeforeSnap;
16951  const recentWheelEvents = [];
16952  function normalize(e) {
16953    // Reasonable defaults
16954    const PIXEL_STEP = 10;
16955    const LINE_HEIGHT = 40;
16956    const PAGE_HEIGHT = 800;
16957    let sX = 0;
16958    let sY = 0; // spinX, spinY
16959    let pX = 0;
16960    let pY = 0; // pixelX, pixelY
16961
16962    // Legacy
16963    if ('detail' in e) {
16964      sY = e.detail;
16965    }
16966    if ('wheelDelta' in e) {
16967      sY = -e.wheelDelta / 120;
16968    }
16969    if ('wheelDeltaY' in e) {
16970      sY = -e.wheelDeltaY / 120;
16971    }
16972    if ('wheelDeltaX' in e) {
16973      sX = -e.wheelDeltaX / 120;
16974    }
16975
16976    // side scrolling on FF with DOMMouseScroll
16977    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
16978      sX = sY;
16979      sY = 0;
16980    }
16981    pX = sX * PIXEL_STEP;
16982    pY = sY * PIXEL_STEP;
16983    if ('deltaY' in e) {
16984      pY = e.deltaY;
16985    }
16986    if ('deltaX' in e) {
16987      pX = e.deltaX;
16988    }
16989    if (e.shiftKey && !pX) {
16990      // if user scrolls with shift he wants horizontal scroll
16991      pX = pY;
16992      pY = 0;
16993    }
16994    if ((pX || pY) && e.deltaMode) {
16995      if (e.deltaMode === 1) {
16996        // delta in LINE units
16997        pX *= LINE_HEIGHT;
16998        pY *= LINE_HEIGHT;
16999      } else {
17000        // delta in PAGE units
17001        pX *= PAGE_HEIGHT;
17002        pY *= PAGE_HEIGHT;
17003      }
17004    }
17005
17006    // Fall-back if spin cannot be determined
17007    if (pX && !sX) {
17008      sX = pX < 1 ? -1 : 1;
17009    }
17010    if (pY && !sY) {
17011      sY = pY < 1 ? -1 : 1;
17012    }
17013    return {
17014      spinX: sX,
17015      spinY: sY,
17016      pixelX: pX,
17017      pixelY: pY
17018    };
17019  }
17020  function handleMouseEnter() {
17021    if (!swiper.enabled) return;
17022    swiper.mouseEntered = true;
17023  }
17024  function handleMouseLeave() {
17025    if (!swiper.enabled) return;
17026    swiper.mouseEntered = false;
17027  }
17028  function animateSlider(newEvent) {
17029    if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
17030      // Prevent if delta of wheel scroll delta is below configured threshold
17031      return false;
17032    }
17033    if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
17034      // Prevent if time between scrolls is below configured threshold
17035      return false;
17036    }
17037
17038    // If the movement is NOT big enough and
17039    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
17040    //   Don't go any further (avoid insignificant scroll movement).
17041    if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
17042      // Return false as a default
17043      return true;
17044    }
17045    // If user is scrolling towards the end:
17046    //   If the slider hasn't hit the latest slide or
17047    //   if the slider is a loop and
17048    //   if the slider isn't moving right now:
17049    //     Go to next slide and
17050    //     emit a scroll event.
17051    // Else (the user is scrolling towards the beginning) and
17052    // if the slider hasn't hit the first slide or
17053    // if the slider is a loop and
17054    // if the slider isn't moving right now:
17055    //   Go to prev slide and
17056    //   emit a scroll event.
17057    if (newEvent.direction < 0) {
17058      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
17059        swiper.slideNext();
17060        emit('scroll', newEvent.raw);
17061      }
17062    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
17063      swiper.slidePrev();
17064      emit('scroll', newEvent.raw);
17065    }
17066    // If you got here is because an animation has been triggered so store the current time
17067    lastScrollTime = new window.Date().getTime();
17068    // Return false as a default
17069    return false;
17070  }
17071  function releaseScroll(newEvent) {
17072    const params = swiper.params.mousewheel;
17073    if (newEvent.direction < 0) {
17074      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
17075        // Return true to animate scroll on edges
17076        return true;
17077      }
17078    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
17079      // Return true to animate scroll on edges
17080      return true;
17081    }
17082    return false;
17083  }
17084  function handle(event) {
17085    let e = event;
17086    let disableParentSwiper = true;
17087    if (!swiper.enabled) return;
17088
17089    // Ignore event if the target or its parents have the swiper-no-mousewheel class
17090    if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
17091    const params = swiper.params.mousewheel;
17092    if (swiper.params.cssMode) {
17093      e.preventDefault();
17094    }
17095    let targetEl = swiper.el;
17096    if (swiper.params.mousewheel.eventsTarget !== 'container') {
17097      targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
17098    }
17099    const targetElContainsTarget = targetEl && targetEl.contains(e.target);
17100    if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
17101    if (e.originalEvent) e = e.originalEvent; // jquery fix
17102    let delta = 0;
17103    const rtlFactor = swiper.rtlTranslate ? -1 : 1;
17104    const data = normalize(e);
17105    if (params.forceToAxis) {
17106      if (swiper.isHorizontal()) {
17107        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;
17108      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;
17109    } else {
17110      delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
17111    }
17112    if (delta === 0) return true;
17113    if (params.invert) delta = -delta;
17114
17115    // Get the scroll positions
17116    let positions = swiper.getTranslate() + delta * params.sensitivity;
17117    if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
17118    if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
17119
17120    // When loop is true:
17121    //     the disableParentSwiper will be true.
17122    // When loop is false:
17123    //     if the scroll positions is not on edge,
17124    //     then the disableParentSwiper will be true.
17125    //     if the scroll on edge positions,
17126    //     then the disableParentSwiper will be false.
17127    disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
17128    if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
17129    if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
17130      // Register the new event in a variable which stores the relevant data
17131      const newEvent = {
17132        time: now(),
17133        delta: Math.abs(delta),
17134        direction: Math.sign(delta),
17135        raw: event
17136      };
17137
17138      // Keep the most recent events
17139      if (recentWheelEvents.length >= 2) {
17140        recentWheelEvents.shift(); // only store the last N events
17141      }
17142
17143      const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
17144      recentWheelEvents.push(newEvent);
17145
17146      // If there is at least one previous recorded event:
17147      //   If direction has changed or
17148      //   if the scroll is quicker than the previous one:
17149      //     Animate the slider.
17150      // Else (this is the first time the wheel is moved):
17151      //     Animate the slider.
17152      if (prevEvent) {
17153        if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
17154          animateSlider(newEvent);
17155        }
17156      } else {
17157        animateSlider(newEvent);
17158      }
17159
17160      // If it's time to release the scroll:
17161      //   Return now so you don't hit the preventDefault.
17162      if (releaseScroll(newEvent)) {
17163        return true;
17164      }
17165    } else {
17166      // Freemode or scrollContainer:
17167
17168      // If we recently snapped after a momentum scroll, then ignore wheel events
17169      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
17170      // or if it's a new scroll (larger delta or inverse sign as last event before
17171      // an end-of-momentum snap).
17172      const newEvent = {
17173        time: now(),
17174        delta: Math.abs(delta),
17175        direction: Math.sign(delta)
17176      };
17177      const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;
17178      if (!ignoreWheelEvents) {
17179        lastEventBeforeSnap = undefined;
17180        let position = swiper.getTranslate() + delta * params.sensitivity;
17181        const wasBeginning = swiper.isBeginning;
17182        const wasEnd = swiper.isEnd;
17183        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
17184        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
17185        swiper.setTransition(0);
17186        swiper.setTranslate(position);
17187        swiper.updateProgress();
17188        swiper.updateActiveIndex();
17189        swiper.updateSlidesClasses();
17190        if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
17191          swiper.updateSlidesClasses();
17192        }
17193        if (swiper.params.loop) {
17194          swiper.loopFix({
17195            direction: newEvent.direction < 0 ? 'next' : 'prev',
17196            byMousewheel: true
17197          });
17198        }
17199        if (swiper.params.freeMode.sticky) {
17200          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
17201          // the end of a momentum scroll by storing recent (N=15?) wheel events.
17202          // 1. do all N events have decreasing or same (absolute value) delta?
17203          // 2. did all N events arrive in the last M (M=500?) msecs?
17204          // 3. does the earliest event have an (absolute value) delta that's
17205          //    at least P (P=1?) larger than the most recent event's delta?
17206          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
17207          // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
17208          // Snap immediately and ignore remaining wheel events in this scroll.
17209          // See comment above for "remaining wheel events in this scroll" determination.
17210          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
17211          clearTimeout(timeout);
17212          timeout = undefined;
17213          if (recentWheelEvents.length >= 15) {
17214            recentWheelEvents.shift(); // only store the last N events
17215          }
17216
17217          const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
17218          const firstEvent = recentWheelEvents[0];
17219          recentWheelEvents.push(newEvent);
17220          if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
17221            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
17222            recentWheelEvents.splice(0);
17223          } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {
17224            // We're at the end of the deceleration of a momentum scroll, so there's no need
17225            // to wait for more events. Snap ASAP on the next tick.
17226            // Also, because there's some remaining momentum we'll bias the snap in the
17227            // direction of the ongoing scroll because it's better UX for the scroll to snap
17228            // in the same direction as the scroll instead of reversing to snap.  Therefore,
17229            // if it's already scrolled more than 20% in the current direction, keep going.
17230            const snapToThreshold = delta > 0 ? 0.8 : 0.2;
17231            lastEventBeforeSnap = newEvent;
17232            recentWheelEvents.splice(0);
17233            timeout = nextTick(() => {
17234              if (swiper.destroyed || !swiper.params) return;
17235              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
17236            }, 0); // no delay; move on next tick
17237          }
17238
17239          if (!timeout) {
17240            // if we get here, then we haven't detected the end of a momentum scroll, so
17241            // we'll consider a scroll "complete" when there haven't been any wheel events
17242            // for 500ms.
17243            timeout = nextTick(() => {
17244              if (swiper.destroyed || !swiper.params) return;
17245              const snapToThreshold = 0.5;
17246              lastEventBeforeSnap = newEvent;
17247              recentWheelEvents.splice(0);
17248              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
17249            }, 500);
17250          }
17251        }
17252
17253        // Emit event
17254        if (!ignoreWheelEvents) emit('scroll', e);
17255
17256        // Stop autoplay
17257        if (swiper.params.autoplay && swiper.params.autoplay.disableOnInteraction) swiper.autoplay.stop();
17258        // Return page scroll on edge positions
17259        if (params.releaseOnEdges && (position === swiper.minTranslate() || position === swiper.maxTranslate())) {
17260          return true;
17261        }
17262      }
17263    }
17264    if (e.preventDefault) e.preventDefault();else e.returnValue = false;
17265    return false;
17266  }
17267  function events(method) {
17268    let targetEl = swiper.el;
17269    if (swiper.params.mousewheel.eventsTarget !== 'container') {
17270      targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
17271    }
17272    targetEl[method]('mouseenter', handleMouseEnter);
17273    targetEl[method]('mouseleave', handleMouseLeave);
17274    targetEl[method]('wheel', handle);
17275  }
17276  function enable() {
17277    if (swiper.params.cssMode) {
17278      swiper.wrapperEl.removeEventListener('wheel', handle);
17279      return true;
17280    }
17281    if (swiper.mousewheel.enabled) return false;
17282    events('addEventListener');
17283    swiper.mousewheel.enabled = true;
17284    return true;
17285  }
17286  function disable() {
17287    if (swiper.params.cssMode) {
17288      swiper.wrapperEl.addEventListener(event, handle);
17289      return true;
17290    }
17291    if (!swiper.mousewheel.enabled) return false;
17292    events('removeEventListener');
17293    swiper.mousewheel.enabled = false;
17294    return true;
17295  }
17296  on('init', () => {
17297    if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
17298      disable();
17299    }
17300    if (swiper.params.mousewheel.enabled) enable();
17301  });
17302  on('destroy', () => {
17303    if (swiper.params.cssMode) {
17304      enable();
17305    }
17306    if (swiper.mousewheel.enabled) disable();
17307  });
17308  Object.assign(swiper.mousewheel, {
17309    enable,
17310    disable
17311  });
17312}
17313
17314
17315
17316;// ./node_modules/swiper/shared/create-element-if-not-defined.mjs
17317
17318
17319function create_element_if_not_defined_createElementIfNotDefined(swiper, originalParams, params, checkProps) {
17320  if (swiper.params.createElements) {
17321    Object.keys(checkProps).forEach(key => {
17322      if (!params[key] && params.auto === true) {
17323        let element = utils_elementChildren(swiper.el, `.${checkProps[key]}`)[0];
17324        if (!element) {
17325          element = utils_createElement('div', checkProps[key]);
17326          element.className = checkProps[key];
17327          swiper.el.append(element);
17328        }
17329        params[key] = element;
17330        originalParams[key] = element;
17331      }
17332    });
17333  }
17334  return params;
17335}
17336
17337
17338
17339;// ./node_modules/swiper/modules/navigation.mjs
17340
17341
17342
17343function Navigation(_ref) {
17344  let {
17345    swiper,
17346    extendParams,
17347    on,
17348    emit
17349  } = _ref;
17350  extendParams({
17351    navigation: {
17352      nextEl: null,
17353      prevEl: null,
17354      hideOnClick: false,
17355      disabledClass: 'swiper-button-disabled',
17356      hiddenClass: 'swiper-button-hidden',
17357      lockClass: 'swiper-button-lock',
17358      navigationDisabledClass: 'swiper-navigation-disabled'
17359    }
17360  });
17361  swiper.navigation = {
17362    nextEl: null,
17363    prevEl: null
17364  };
17365  function getEl(el) {
17366    let res;
17367    if (el && typeof el === 'string' && swiper.isElement) {
17368      res = swiper.el.querySelector(el) || swiper.hostEl.querySelector(el);
17369      if (res) return res;
17370    }
17371    if (el) {
17372      if (typeof el === 'string') res = [...document.querySelectorAll(el)];
17373      if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
17374        res = swiper.el.querySelector(el);
17375      } else if (res && res.length === 1) {
17376        res = res[0];
17377      }
17378    }
17379    if (el && !res) return el;
17380    // if (Array.isArray(res) && res.length === 1) res = res[0];
17381    return res;
17382  }
17383  function toggleEl(el, disabled) {
17384    const params = swiper.params.navigation;
17385    el = utils_makeElementsArray(el);
17386    el.forEach(subEl => {
17387      if (subEl) {
17388        subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
17389        if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
17390        if (swiper.params.watchOverflow && swiper.enabled) {
17391          subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
17392        }
17393      }
17394    });
17395  }
17396  function update() {
17397    // Update Navigation Buttons
17398    const {
17399      nextEl,
17400      prevEl
17401    } = swiper.navigation;
17402    if (swiper.params.loop) {
17403      toggleEl(prevEl, false);
17404      toggleEl(nextEl, false);
17405      return;
17406    }
17407    toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
17408    toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
17409  }
17410  function onPrevClick(e) {
17411    e.preventDefault();
17412    if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
17413    swiper.slidePrev();
17414    emit('navigationPrev');
17415  }
17416  function onNextClick(e) {
17417    e.preventDefault();
17418    if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
17419    swiper.slideNext();
17420    emit('navigationNext');
17421  }
17422  function init() {
17423    const params = swiper.params.navigation;
17424    swiper.params.navigation = create_element_if_not_defined_createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
17425      nextEl: 'swiper-button-next',
17426      prevEl: 'swiper-button-prev'
17427    });
17428    if (!(params.nextEl || params.prevEl)) return;
17429    let nextEl = getEl(params.nextEl);
17430    let prevEl = getEl(params.prevEl);
17431    Object.assign(swiper.navigation, {
17432      nextEl,
17433      prevEl
17434    });
17435    nextEl = utils_makeElementsArray(nextEl);
17436    prevEl = utils_makeElementsArray(prevEl);
17437    const initButton = (el, dir) => {
17438      if (el) {
17439        el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
17440      }
17441      if (!swiper.enabled && el) {
17442        el.classList.add(...params.lockClass.split(' '));
17443      }
17444    };
17445    nextEl.forEach(el => initButton(el, 'next'));
17446    prevEl.forEach(el => initButton(el, 'prev'));
17447  }
17448  function destroy() {
17449    let {
17450      nextEl,
17451      prevEl
17452    } = swiper.navigation;
17453    nextEl = utils_makeElementsArray(nextEl);
17454    prevEl = utils_makeElementsArray(prevEl);
17455    const destroyButton = (el, dir) => {
17456      el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
17457      el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
17458    };
17459    nextEl.forEach(el => destroyButton(el, 'next'));
17460    prevEl.forEach(el => destroyButton(el, 'prev'));
17461  }
17462  on('init', () => {
17463    if (swiper.params.navigation.enabled === false) {
17464      // eslint-disable-next-line
17465      disable();
17466    } else {
17467      init();
17468      update();
17469    }
17470  });
17471  on('toEdge fromEdge lock unlock', () => {
17472    update();
17473  });
17474  on('destroy', () => {
17475    destroy();
17476  });
17477  on('enable disable', () => {
17478    let {
17479      nextEl,
17480      prevEl
17481    } = swiper.navigation;
17482    nextEl = utils_makeElementsArray(nextEl);
17483    prevEl = utils_makeElementsArray(prevEl);
17484    if (swiper.enabled) {
17485      update();
17486      return;
17487    }
17488    [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass));
17489  });
17490  on('click', (_s, e) => {
17491    let {
17492      nextEl,
17493      prevEl
17494    } = swiper.navigation;
17495    nextEl = utils_makeElementsArray(nextEl);
17496    prevEl = utils_makeElementsArray(prevEl);
17497    const targetEl = e.target;
17498    let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
17499    if (swiper.isElement && !targetIsButton) {
17500      const path = e.path || e.composedPath && e.composedPath();
17501      if (path) {
17502        targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
17503      }
17504    }
17505    if (swiper.params.navigation.hideOnClick && !targetIsButton) {
17506      if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
17507      let isHidden;
17508      if (nextEl.length) {
17509        isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
17510      } else if (prevEl.length) {
17511        isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
17512      }
17513      if (isHidden === true) {
17514        emit('navigationShow');
17515      } else {
17516        emit('navigationHide');
17517      }
17518      [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
17519    }
17520  });
17521  const enable = () => {
17522    swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
17523    init();
17524    update();
17525  };
17526  const disable = () => {
17527    swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
17528    destroy();
17529  };
17530  Object.assign(swiper.navigation, {
17531    enable,
17532    disable,
17533    update,
17534    init,
17535    destroy
17536  });
17537}
17538
17539
17540
17541;// ./node_modules/swiper/shared/classes-to-selector.mjs
17542function classes_to_selector_classesToSelector(classes) {
17543  if (classes === void 0) {
17544    classes = '';
17545  }
17546  return `.${classes.trim().replace(/([\.:!+\/()[\]])/g, '\\$1') // eslint-disable-line
17547  .replace(/ /g, '.')}`;
17548}
17549
17550
17551
17552;// ./node_modules/swiper/modules/pagination.mjs
17553
17554
17555
17556
17557function Pagination(_ref) {
17558  let {
17559    swiper,
17560    extendParams,
17561    on,
17562    emit
17563  } = _ref;
17564  const pfx = 'swiper-pagination';
17565  extendParams({
17566    pagination: {
17567      el: null,
17568      bulletElement: 'span',
17569      clickable: false,
17570      hideOnClick: false,
17571      renderBullet: null,
17572      renderProgressbar: null,
17573      renderFraction: null,
17574      renderCustom: null,
17575      progressbarOpposite: false,
17576      type: 'bullets',
17577      // 'bullets' or 'progressbar' or 'fraction' or 'custom'
17578      dynamicBullets: false,
17579      dynamicMainBullets: 1,
17580      formatFractionCurrent: number => number,
17581      formatFractionTotal: number => number,
17582      bulletClass: `${pfx}-bullet`,
17583      bulletActiveClass: `${pfx}-bullet-active`,
17584      modifierClass: `${pfx}-`,
17585      currentClass: `${pfx}-current`,
17586      totalClass: `${pfx}-total`,
17587      hiddenClass: `${pfx}-hidden`,
17588      progressbarFillClass: `${pfx}-progressbar-fill`,
17589      progressbarOppositeClass: `${pfx}-progressbar-opposite`,
17590      clickableClass: `${pfx}-clickable`,
17591      lockClass: `${pfx}-lock`,
17592      horizontalClass: `${pfx}-horizontal`,
17593      verticalClass: `${pfx}-vertical`,
17594      paginationDisabledClass: `${pfx}-disabled`
17595    }
17596  });
17597  swiper.pagination = {
17598    el: null,
17599    bullets: []
17600  };
17601  let bulletSize;
17602  let dynamicBulletIndex = 0;
17603  function isPaginationDisabled() {
17604    return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;
17605  }
17606  function setSideBullets(bulletEl, position) {
17607    const {
17608      bulletActiveClass
17609    } = swiper.params.pagination;
17610    if (!bulletEl) return;
17611    bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
17612    if (bulletEl) {
17613      bulletEl.classList.add(`${bulletActiveClass}-${position}`);
17614      bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
17615      if (bulletEl) {
17616        bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
17617      }
17618    }
17619  }
17620  function getMoveDirection(prevIndex, nextIndex, length) {
17621    prevIndex = prevIndex % length;
17622    nextIndex = nextIndex % length;
17623    if (nextIndex === prevIndex + 1) {
17624      return 'next';
17625    } else if (nextIndex === prevIndex - 1) {
17626      return 'previous';
17627    }
17628    return;
17629  }
17630  function onBulletClick(e) {
17631    const bulletEl = e.target.closest(classes_to_selector_classesToSelector(swiper.params.pagination.bulletClass));
17632    if (!bulletEl) {
17633      return;
17634    }
17635    e.preventDefault();
17636    const index = utils_elementIndex(bulletEl) * swiper.params.slidesPerGroup;
17637    if (swiper.params.loop) {
17638      if (swiper.realIndex === index) return;
17639      const moveDirection = getMoveDirection(swiper.realIndex, index, swiper.slides.length);
17640      if (moveDirection === 'next') {
17641        swiper.slideNext();
17642      } else if (moveDirection === 'previous') {
17643        swiper.slidePrev();
17644      } else {
17645        swiper.slideToLoop(index);
17646      }
17647    } else {
17648      swiper.slideTo(index);
17649    }
17650  }
17651  function update() {
17652    // Render || Update Pagination bullets/items
17653    const rtl = swiper.rtl;
17654    const params = swiper.params.pagination;
17655    if (isPaginationDisabled()) return;
17656    let el = swiper.pagination.el;
17657    el = utils_makeElementsArray(el);
17658    // Current/Total
17659    let current;
17660    let previousIndex;
17661    const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
17662    const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
17663    if (swiper.params.loop) {
17664      previousIndex = swiper.previousRealIndex || 0;
17665      current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;
17666    } else if (typeof swiper.snapIndex !== 'undefined') {
17667      current = swiper.snapIndex;
17668      previousIndex = swiper.previousSnapIndex;
17669    } else {
17670      previousIndex = swiper.previousIndex || 0;
17671      current = swiper.activeIndex || 0;
17672    }
17673    // Types
17674    if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
17675      const bullets = swiper.pagination.bullets;
17676      let firstIndex;
17677      let lastIndex;
17678      let midIndex;
17679      if (params.dynamicBullets) {
17680        bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);
17681        el.forEach(subEl => {
17682          subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
17683        });
17684        if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
17685          dynamicBulletIndex += current - (previousIndex || 0);
17686          if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
17687            dynamicBulletIndex = params.dynamicMainBullets - 1;
17688          } else if (dynamicBulletIndex < 0) {
17689            dynamicBulletIndex = 0;
17690          }
17691        }
17692        firstIndex = Math.max(current - dynamicBulletIndex, 0);
17693        lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
17694        midIndex = (lastIndex + firstIndex) / 2;
17695      }
17696      bullets.forEach(bulletEl => {
17697        const classesToRemove = [...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`)].map(s => typeof s === 'string' && s.includes(' ') ? s.split(' ') : s).flat();
17698        bulletEl.classList.remove(...classesToRemove);
17699      });
17700      if (el.length > 1) {
17701        bullets.forEach(bullet => {
17702          const bulletIndex = utils_elementIndex(bullet);
17703          if (bulletIndex === current) {
17704            bullet.classList.add(...params.bulletActiveClass.split(' '));
17705          } else if (swiper.isElement) {
17706            bullet.setAttribute('part', 'bullet');
17707          }
17708          if (params.dynamicBullets) {
17709            if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
17710              bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
17711            }
17712            if (bulletIndex === firstIndex) {
17713              setSideBullets(bullet, 'prev');
17714            }
17715            if (bulletIndex === lastIndex) {
17716              setSideBullets(bullet, 'next');
17717            }
17718          }
17719        });
17720      } else {
17721        const bullet = bullets[current];
17722        if (bullet) {
17723          bullet.classList.add(...params.bulletActiveClass.split(' '));
17724        }
17725        if (swiper.isElement) {
17726          bullets.forEach((bulletEl, bulletIndex) => {
17727            bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
17728          });
17729        }
17730        if (params.dynamicBullets) {
17731          const firstDisplayedBullet = bullets[firstIndex];
17732          const lastDisplayedBullet = bullets[lastIndex];
17733          for (let i = firstIndex; i <= lastIndex; i += 1) {
17734            if (bullets[i]) {
17735              bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
17736            }
17737          }
17738          setSideBullets(firstDisplayedBullet, 'prev');
17739          setSideBullets(lastDisplayedBullet, 'next');
17740        }
17741      }
17742      if (params.dynamicBullets) {
17743        const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
17744        const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
17745        const offsetProp = rtl ? 'right' : 'left';
vendor: 4,211 bytes, lines 17746-17840
17746        bullets.forEach(bullet => {
17747          bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
17748        });
17749      }
17750    }
17751    el.forEach((subEl, subElIndex) => {
17752      if (params.type === 'fraction') {
17753        subEl.querySelectorAll(classes_to_selector_classesToSelector(params.currentClass)).forEach(fractionEl => {
17754          fractionEl.textContent = params.formatFractionCurrent(current + 1);
17755        });
17756        subEl.querySelectorAll(classes_to_selector_classesToSelector(params.totalClass)).forEach(totalEl => {
17757          totalEl.textContent = params.formatFractionTotal(total);
17758        });
17759      }
17760      if (params.type === 'progressbar') {
17761        let progressbarDirection;
17762        if (params.progressbarOpposite) {
17763          progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
17764        } else {
17765          progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
17766        }
17767        const scale = (current + 1) / total;
17768        let scaleX = 1;
17769        let scaleY = 1;
17770        if (progressbarDirection === 'horizontal') {
17771          scaleX = scale;
17772        } else {
17773          scaleY = scale;
17774        }
17775        subEl.querySelectorAll(classes_to_selector_classesToSelector(params.progressbarFillClass)).forEach(progressEl => {
17776          progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
17777          progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
17778        });
17779      }
17780      if (params.type === 'custom' && params.renderCustom) {
17781        utils_setInnerHTML(subEl, params.renderCustom(swiper, current + 1, total));
17782        if (subElIndex === 0) emit('paginationRender', subEl);
17783      } else {
17784        if (subElIndex === 0) emit('paginationRender', subEl);
17785        emit('paginationUpdate', subEl);
17786      }
17787      if (swiper.params.watchOverflow && swiper.enabled) {
17788        subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
17789      }
17790    });
17791  }
17792  function render() {
17793    // Render Container
17794    const params = swiper.params.pagination;
17795    if (isPaginationDisabled()) return;
17796    const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.grid && swiper.params.grid.rows > 1 ? swiper.slides.length / Math.ceil(swiper.params.grid.rows) : swiper.slides.length;
17797    let el = swiper.pagination.el;
17798    el = utils_makeElementsArray(el);
17799    let paginationHTML = '';
17800    if (params.type === 'bullets') {
17801      let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
17802      if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
17803        numberOfBullets = slidesLength;
17804      }
17805      for (let i = 0; i < numberOfBullets; i += 1) {
17806        if (params.renderBullet) {
17807          paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
17808        } else {
17809          // prettier-ignore
17810          paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
17811        }
17812      }
17813    }
17814    if (params.type === 'fraction') {
17815      if (params.renderFraction) {
17816        paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
17817      } else {
17818        paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
17819      }
17820    }
17821    if (params.type === 'progressbar') {
17822      if (params.renderProgressbar) {
17823        paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
17824      } else {
17825        paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
17826      }
17827    }
17828    swiper.pagination.bullets = [];
17829    el.forEach(subEl => {
17830      if (params.type !== 'custom') {
17831        utils_setInnerHTML(subEl, paginationHTML || '');
17832      }
17833      if (params.type === 'bullets') {
17834        swiper.pagination.bullets.push(...subEl.querySelectorAll(classes_to_selector_classesToSelector(params.bulletClass)));
17835      }
17836    });
17837    if (params.type !== 'custom') {
17838      emit('paginationRender', el[0]);
17839    }
17840  }
vendor: 5,913 bytes, lines 17841-18028
17841  function init() {
17842    swiper.params.pagination = create_element_if_not_defined_createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
17843      el: 'swiper-pagination'
17844    });
17845    const params = swiper.params.pagination;
17846    if (!params.el) return;
17847    let el;
17848    if (typeof params.el === 'string' && swiper.isElement) {
17849      el = swiper.el.querySelector(params.el);
17850    }
17851    if (!el && typeof params.el === 'string') {
17852      el = [...document.querySelectorAll(params.el)];
17853    }
17854    if (!el) {
17855      el = params.el;
17856    }
17857    if (!el || el.length === 0) return;
17858    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
17859      el = [...swiper.el.querySelectorAll(params.el)];
17860      // check if it belongs to another nested Swiper
17861      if (el.length > 1) {
17862        el = el.find(subEl => {
17863          if (utils_elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
17864          return true;
17865        });
17866      }
17867    }
17868    if (Array.isArray(el) && el.length === 1) el = el[0];
17869    Object.assign(swiper.pagination, {
17870      el
17871    });
17872    el = utils_makeElementsArray(el);
17873    el.forEach(subEl => {
17874      if (params.type === 'bullets' && params.clickable) {
17875        subEl.classList.add(...(params.clickableClass || '').split(' '));
17876      }
17877      subEl.classList.add(params.modifierClass + params.type);
17878      subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
17879      if (params.type === 'bullets' && params.dynamicBullets) {
17880        subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
17881        dynamicBulletIndex = 0;
17882        if (params.dynamicMainBullets < 1) {
17883          params.dynamicMainBullets = 1;
17884        }
17885      }
17886      if (params.type === 'progressbar' && params.progressbarOpposite) {
17887        subEl.classList.add(params.progressbarOppositeClass);
17888      }
17889      if (params.clickable) {
17890        subEl.addEventListener('click', onBulletClick);
17891      }
17892      if (!swiper.enabled) {
17893        subEl.classList.add(params.lockClass);
17894      }
17895    });
17896  }
17897  function destroy() {
17898    const params = swiper.params.pagination;
17899    if (isPaginationDisabled()) return;
17900    let el = swiper.pagination.el;
17901    if (el) {
17902      el = utils_makeElementsArray(el);
17903      el.forEach(subEl => {
17904        subEl.classList.remove(params.hiddenClass);
17905        subEl.classList.remove(params.modifierClass + params.type);
17906        subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
17907        if (params.clickable) {
17908          subEl.classList.remove(...(params.clickableClass || '').split(' '));
17909          subEl.removeEventListener('click', onBulletClick);
17910        }
17911      });
17912    }
17913    if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
17914  }
17915  on('changeDirection', () => {
17916    if (!swiper.pagination || !swiper.pagination.el) return;
17917    const params = swiper.params.pagination;
17918    let {
17919      el
17920    } = swiper.pagination;
17921    el = utils_makeElementsArray(el);
17922    el.forEach(subEl => {
17923      subEl.classList.remove(params.horizontalClass, params.verticalClass);
17924      subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
17925    });
17926  });
17927  on('init', () => {
17928    if (swiper.params.pagination.enabled === false) {
17929      // eslint-disable-next-line
17930      disable();
17931    } else {
17932      init();
17933      render();
17934      update();
17935    }
17936  });
17937  on('activeIndexChange', () => {
17938    if (typeof swiper.snapIndex === 'undefined') {
17939      update();
17940    }
17941  });
17942  on('snapIndexChange', () => {
17943    update();
17944  });
17945  on('snapGridLengthChange', () => {
17946    render();
17947    update();
17948  });
17949  on('destroy', () => {
17950    destroy();
17951  });
17952  on('enable disable', () => {
17953    let {
17954      el
17955    } = swiper.pagination;
17956    if (el) {
17957      el = utils_makeElementsArray(el);
17958      el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
17959    }
17960  });
17961  on('lock unlock', () => {
17962    update();
17963  });
17964  on('click', (_s, e) => {
17965    const targetEl = e.target;
17966    const el = utils_makeElementsArray(swiper.pagination.el);
17967    if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {
17968      if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
17969      const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
17970      if (isHidden === true) {
17971        emit('paginationShow');
17972      } else {
17973        emit('paginationHide');
17974      }
17975      el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
17976    }
17977  });
17978  const enable = () => {
17979    swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
17980    let {
17981      el
17982    } = swiper.pagination;
17983    if (el) {
17984      el = utils_makeElementsArray(el);
17985      el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
17986    }
17987    init();
17988    render();
17989    update();
17990  };
17991  const disable = () => {
17992    swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
17993    let {
17994      el
17995    } = swiper.pagination;
17996    if (el) {
17997      el = utils_makeElementsArray(el);
17998      el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
17999    }
18000    destroy();
18001  };
18002  Object.assign(swiper.pagination, {
18003    enable,
18004    disable,
18005    render,
18006    update,
18007    init,
18008    destroy
18009  });
18010}
18011
18012
18013
18014;// ./node_modules/swiper/modules/scrollbar.mjs
18015
18016
18017
18018
18019
18020function Scrollbar(_ref) {
18021  let {
18022    swiper,
18023    extendParams,
18024    on,
18025    emit
18026  } = _ref;
18027  const document = getDocument();
18028  let isTouched = false;
vendor: 4,705 bytes, lines 18029-18181
18029  let timeout = null;
18030  let dragTimeout = null;
18031  let dragStartPos;
18032  let dragSize;
18033  let trackSize;
18034  let divider;
18035  extendParams({
18036    scrollbar: {
18037      el: null,
18038      dragSize: 'auto',
18039      hide: false,
18040      draggable: false,
18041      snapOnRelease: true,
18042      lockClass: 'swiper-scrollbar-lock',
18043      dragClass: 'swiper-scrollbar-drag',
18044      scrollbarDisabledClass: 'swiper-scrollbar-disabled',
18045      horizontalClass: `swiper-scrollbar-horizontal`,
18046      verticalClass: `swiper-scrollbar-vertical`
18047    }
18048  });
18049  swiper.scrollbar = {
18050    el: null,
18051    dragEl: null
18052  };
18053  function setTranslate() {
18054    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18055    const {
18056      scrollbar,
18057      rtlTranslate: rtl
18058    } = swiper;
18059    const {
18060      dragEl,
18061      el
18062    } = scrollbar;
18063    const params = swiper.params.scrollbar;
18064    const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
18065    let newSize = dragSize;
18066    let newPos = (trackSize - dragSize) * progress;
18067    if (rtl) {
18068      newPos = -newPos;
18069      if (newPos > 0) {
18070        newSize = dragSize - newPos;
18071        newPos = 0;
18072      } else if (-newPos + dragSize > trackSize) {
18073        newSize = trackSize + newPos;
18074      }
18075    } else if (newPos < 0) {
18076      newSize = dragSize + newPos;
18077      newPos = 0;
18078    } else if (newPos + dragSize > trackSize) {
18079      newSize = trackSize - newPos;
18080    }
18081    if (swiper.isHorizontal()) {
18082      dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
18083      dragEl.style.width = `${newSize}px`;
18084    } else {
18085      dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
18086      dragEl.style.height = `${newSize}px`;
18087    }
18088    if (params.hide) {
18089      clearTimeout(timeout);
18090      el.style.opacity = 1;
18091      timeout = setTimeout(() => {
18092        el.style.opacity = 0;
18093        el.style.transitionDuration = '400ms';
18094      }, 1000);
18095    }
18096  }
18097  function setTransition(duration) {
18098    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18099    swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
18100  }
18101  function updateSize() {
18102    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18103    const {
18104      scrollbar
18105    } = swiper;
18106    const {
18107      dragEl,
18108      el
18109    } = scrollbar;
18110    dragEl.style.width = '';
18111    dragEl.style.height = '';
18112    trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
18113    divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
18114    if (swiper.params.scrollbar.dragSize === 'auto') {
18115      dragSize = trackSize * divider;
18116    } else {
18117      dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
18118    }
18119    if (swiper.isHorizontal()) {
18120      dragEl.style.width = `${dragSize}px`;
18121    } else {
18122      dragEl.style.height = `${dragSize}px`;
18123    }
18124    if (divider >= 1) {
18125      el.style.display = 'none';
18126    } else {
18127      el.style.display = '';
18128    }
18129    if (swiper.params.scrollbar.hide) {
18130      el.style.opacity = 0;
18131    }
18132    if (swiper.params.watchOverflow && swiper.enabled) {
18133      scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
18134    }
18135  }
18136  function getPointerPosition(e) {
18137    return swiper.isHorizontal() ? e.clientX : e.clientY;
18138  }
18139  function setDragPosition(e) {
18140    const {
18141      scrollbar,
18142      rtlTranslate: rtl
18143    } = swiper;
18144    const {
18145      el
18146    } = scrollbar;
18147    let positionRatio;
18148    positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
18149    positionRatio = Math.max(Math.min(positionRatio, 1), 0);
18150    if (rtl) {
18151      positionRatio = 1 - positionRatio;
18152    }
18153    const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
18154    swiper.updateProgress(position);
18155    swiper.setTranslate(position);
18156    swiper.updateActiveIndex();
18157    swiper.updateSlidesClasses();
18158  }
18159  function onDragStart(e) {
18160    const params = swiper.params.scrollbar;
18161    const {
18162      scrollbar,
18163      wrapperEl
18164    } = swiper;
18165    const {
18166      el,
18167      dragEl
18168    } = scrollbar;
18169    isTouched = true;
18170    dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
18171    e.preventDefault();
18172    e.stopPropagation();
18173    wrapperEl.style.transitionDuration = '100ms';
18174    dragEl.style.transitionDuration = '100ms';
18175    setDragPosition(e);
18176    clearTimeout(dragTimeout);
18177    el.style.transitionDuration = '0ms';
18178    if (params.hide) {
18179      el.style.opacity = 1;
18180    }
18181    if (swiper.params.cssMode) {
vendor: 117,893 bytes, lines 18182-21750
18182      swiper.wrapperEl.style['scroll-snap-type'] = 'none';
18183    }
18184    emit('scrollbarDragStart', e);
18185  }
18186  function onDragMove(e) {
18187    const {
18188      scrollbar,
18189      wrapperEl
18190    } = swiper;
18191    const {
18192      el,
18193      dragEl
18194    } = scrollbar;
18195    if (!isTouched) return;
18196    if (e.preventDefault && e.cancelable) e.preventDefault();else e.returnValue = false;
18197    setDragPosition(e);
18198    wrapperEl.style.transitionDuration = '0ms';
18199    el.style.transitionDuration = '0ms';
18200    dragEl.style.transitionDuration = '0ms';
18201    emit('scrollbarDragMove', e);
18202  }
18203  function onDragEnd(e) {
18204    const params = swiper.params.scrollbar;
18205    const {
18206      scrollbar,
18207      wrapperEl
18208    } = swiper;
18209    const {
18210      el
18211    } = scrollbar;
18212    if (!isTouched) return;
18213    isTouched = false;
18214    if (swiper.params.cssMode) {
18215      swiper.wrapperEl.style['scroll-snap-type'] = '';
18216      wrapperEl.style.transitionDuration = '';
18217    }
18218    if (params.hide) {
18219      clearTimeout(dragTimeout);
18220      dragTimeout = nextTick(() => {
18221        el.style.opacity = 0;
18222        el.style.transitionDuration = '400ms';
18223      }, 1000);
18224    }
18225    emit('scrollbarDragEnd', e);
18226    if (params.snapOnRelease) {
18227      swiper.slideToClosest();
18228    }
18229  }
18230  function events(method) {
18231    const {
18232      scrollbar,
18233      params
18234    } = swiper;
18235    const el = scrollbar.el;
18236    if (!el) return;
18237    const target = el;
18238    const activeListener = params.passiveListeners ? {
18239      passive: false,
18240      capture: false
18241    } : false;
18242    const passiveListener = params.passiveListeners ? {
18243      passive: true,
18244      capture: false
18245    } : false;
18246    if (!target) return;
18247    const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
18248    target[eventMethod]('pointerdown', onDragStart, activeListener);
18249    document[eventMethod]('pointermove', onDragMove, activeListener);
18250    document[eventMethod]('pointerup', onDragEnd, passiveListener);
18251  }
18252  function enableDraggable() {
18253    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18254    events('on');
18255  }
18256  function disableDraggable() {
18257    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18258    events('off');
18259  }
18260  function init() {
18261    const {
18262      scrollbar,
18263      el: swiperEl
18264    } = swiper;
18265    swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {
18266      el: 'swiper-scrollbar'
18267    });
18268    const params = swiper.params.scrollbar;
18269    if (!params.el) return;
18270    let el;
18271    if (typeof params.el === 'string' && swiper.isElement) {
18272      el = swiper.el.querySelector(params.el);
18273    }
18274    if (!el && typeof params.el === 'string') {
18275      el = document.querySelectorAll(params.el);
18276      if (!el.length) return;
18277    } else if (!el) {
18278      el = params.el;
18279    }
18280    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) {
18281      el = swiperEl.querySelector(params.el);
18282    }
18283    if (el.length > 0) el = el[0];
18284    el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18285    let dragEl;
18286    if (el) {
18287      dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass));
18288      if (!dragEl) {
18289        dragEl = createElement('div', swiper.params.scrollbar.dragClass);
18290        el.append(dragEl);
18291      }
18292    }
18293    Object.assign(scrollbar, {
18294      el,
18295      dragEl
18296    });
18297    if (params.draggable) {
18298      enableDraggable();
18299    }
18300    if (el) {
18301      el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
18302    }
18303  }
18304  function destroy() {
18305    const params = swiper.params.scrollbar;
18306    const el = swiper.scrollbar.el;
18307    if (el) {
18308      el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass));
18309    }
18310    disableDraggable();
18311  }
18312  on('changeDirection', () => {
18313    if (!swiper.scrollbar || !swiper.scrollbar.el) return;
18314    const params = swiper.params.scrollbar;
18315    let {
18316      el
18317    } = swiper.scrollbar;
18318    el = makeElementsArray(el);
18319    el.forEach(subEl => {
18320      subEl.classList.remove(params.horizontalClass, params.verticalClass);
18321      subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18322    });
18323  });
18324  on('init', () => {
18325    if (swiper.params.scrollbar.enabled === false) {
18326      // eslint-disable-next-line
18327      disable();
18328    } else {
18329      init();
18330      updateSize();
18331      setTranslate();
18332    }
18333  });
18334  on('update resize observerUpdate lock unlock changeDirection', () => {
18335    updateSize();
18336  });
18337  on('setTranslate', () => {
18338    setTranslate();
18339  });
18340  on('setTransition', (_s, duration) => {
18341    setTransition(duration);
18342  });
18343  on('enable disable', () => {
18344    const {
18345      el
18346    } = swiper.scrollbar;
18347    if (el) {
18348      el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
18349    }
18350  });
18351  on('destroy', () => {
18352    destroy();
18353  });
18354  const enable = () => {
18355    swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18356    if (swiper.scrollbar.el) {
18357      swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18358    }
18359    init();
18360    updateSize();
18361    setTranslate();
18362  };
18363  const disable = () => {
18364    swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18365    if (swiper.scrollbar.el) {
18366      swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18367    }
18368    destroy();
18369  };
18370  Object.assign(swiper.scrollbar, {
18371    enable,
18372    disable,
18373    updateSize,
18374    setTranslate,
18375    init,
18376    destroy
18377  });
18378}
18379
18380
18381
18382;// ./node_modules/swiper/modules/parallax.mjs
18383
18384
18385function Parallax(_ref) {
18386  let {
18387    swiper,
18388    extendParams,
18389    on
18390  } = _ref;
18391  extendParams({
18392    parallax: {
18393      enabled: false
18394    }
18395  });
18396  const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]';
18397  const setTransform = (el, progress) => {
18398    const {
18399      rtl
18400    } = swiper;
18401    const rtlFactor = rtl ? -1 : 1;
18402    const p = el.getAttribute('data-swiper-parallax') || '0';
18403    let x = el.getAttribute('data-swiper-parallax-x');
18404    let y = el.getAttribute('data-swiper-parallax-y');
18405    const scale = el.getAttribute('data-swiper-parallax-scale');
18406    const opacity = el.getAttribute('data-swiper-parallax-opacity');
18407    const rotate = el.getAttribute('data-swiper-parallax-rotate');
18408    if (x || y) {
18409      x = x || '0';
18410      y = y || '0';
18411    } else if (swiper.isHorizontal()) {
18412      x = p;
18413      y = '0';
18414    } else {
18415      y = p;
18416      x = '0';
18417    }
18418    if (x.indexOf('%') >= 0) {
18419      x = `${parseInt(x, 10) * progress * rtlFactor}%`;
18420    } else {
18421      x = `${x * progress * rtlFactor}px`;
18422    }
18423    if (y.indexOf('%') >= 0) {
18424      y = `${parseInt(y, 10) * progress}%`;
18425    } else {
18426      y = `${y * progress}px`;
18427    }
18428    if (typeof opacity !== 'undefined' && opacity !== null) {
18429      const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
18430      el.style.opacity = currentOpacity;
18431    }
18432    let transform = `translate3d(${x}, ${y}, 0px)`;
18433    if (typeof scale !== 'undefined' && scale !== null) {
18434      const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
18435      transform += ` scale(${currentScale})`;
18436    }
18437    if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
18438      const currentRotate = rotate * progress * -1;
18439      transform += ` rotate(${currentRotate}deg)`;
18440    }
18441    el.style.transform = transform;
18442  };
18443  const setTranslate = () => {
18444    const {
18445      el,
18446      slides,
18447      progress,
18448      snapGrid,
18449      isElement
18450    } = swiper;
18451    const elements = elementChildren(el, elementsSelector);
18452    if (swiper.isElement) {
18453      elements.push(...elementChildren(swiper.hostEl, elementsSelector));
18454    }
18455    elements.forEach(subEl => {
18456      setTransform(subEl, progress);
18457    });
18458    slides.forEach((slideEl, slideIndex) => {
18459      let slideProgress = slideEl.progress;
18460      if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
18461        slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
18462      }
18463      slideProgress = Math.min(Math.max(slideProgress, -1), 1);
18464      slideEl.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`).forEach(subEl => {
18465        setTransform(subEl, slideProgress);
18466      });
18467    });
18468  };
18469  const setTransition = function (duration) {
18470    if (duration === void 0) {
18471      duration = swiper.params.speed;
18472    }
18473    const {
18474      el,
18475      hostEl
18476    } = swiper;
18477    const elements = [...el.querySelectorAll(elementsSelector)];
18478    if (swiper.isElement) {
18479      elements.push(...hostEl.querySelectorAll(elementsSelector));
18480    }
18481    elements.forEach(parallaxEl => {
18482      let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
18483      if (duration === 0) parallaxDuration = 0;
18484      parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
18485    });
18486  };
18487  on('beforeInit', () => {
18488    if (!swiper.params.parallax.enabled) return;
18489    swiper.params.watchSlidesProgress = true;
18490    swiper.originalParams.watchSlidesProgress = true;
18491  });
18492  on('init', () => {
18493    if (!swiper.params.parallax.enabled) return;
18494    setTranslate();
18495  });
18496  on('setTranslate', () => {
18497    if (!swiper.params.parallax.enabled) return;
18498    setTranslate();
18499  });
18500  on('setTransition', (_swiper, duration) => {
18501    if (!swiper.params.parallax.enabled) return;
18502    setTransition(duration);
18503  });
18504}
18505
18506
18507
18508;// ./node_modules/swiper/modules/zoom.mjs
18509
18510
18511
18512function Zoom(_ref) {
18513  let {
18514    swiper,
18515    extendParams,
18516    on,
18517    emit
18518  } = _ref;
18519  const window = getWindow();
18520  extendParams({
18521    zoom: {
18522      enabled: false,
18523      limitToOriginalSize: false,
18524      maxRatio: 3,
18525      minRatio: 1,
18526      panOnMouseMove: false,
18527      toggle: true,
18528      containerClass: 'swiper-zoom-container',
18529      zoomedSlideClass: 'swiper-slide-zoomed'
18530    }
18531  });
18532  swiper.zoom = {
18533    enabled: false
18534  };
18535  let currentScale = 1;
18536  let isScaling = false;
18537  let isPanningWithMouse = false;
18538  let mousePanStart = {
18539    x: 0,
18540    y: 0
18541  };
18542  const mousePanSensitivity = -3; // Negative to invert pan direction
18543  let fakeGestureTouched;
18544  let fakeGestureMoved;
18545  const evCache = [];
18546  const gesture = {
18547    originX: 0,
18548    originY: 0,
18549    slideEl: undefined,
18550    slideWidth: undefined,
18551    slideHeight: undefined,
18552    imageEl: undefined,
18553    imageWrapEl: undefined,
18554    maxRatio: 3
18555  };
18556  const image = {
18557    isTouched: undefined,
18558    isMoved: undefined,
18559    currentX: undefined,
18560    currentY: undefined,
18561    minX: undefined,
18562    minY: undefined,
18563    maxX: undefined,
18564    maxY: undefined,
18565    width: undefined,
18566    height: undefined,
18567    startX: undefined,
18568    startY: undefined,
18569    touchesStart: {},
18570    touchesCurrent: {}
18571  };
18572  const velocity = {
18573    x: undefined,
18574    y: undefined,
18575    prevPositionX: undefined,
18576    prevPositionY: undefined,
18577    prevTime: undefined
18578  };
18579  let scale = 1;
18580  Object.defineProperty(swiper.zoom, 'scale', {
18581    get() {
18582      return scale;
18583    },
18584    set(value) {
18585      if (scale !== value) {
18586        const imageEl = gesture.imageEl;
18587        const slideEl = gesture.slideEl;
18588        emit('zoomChange', value, imageEl, slideEl);
18589      }
18590      scale = value;
18591    }
18592  });
18593  function getDistanceBetweenTouches() {
18594    if (evCache.length < 2) return 1;
18595    const x1 = evCache[0].pageX;
18596    const y1 = evCache[0].pageY;
18597    const x2 = evCache[1].pageX;
18598    const y2 = evCache[1].pageY;
18599    const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
18600    return distance;
18601  }
18602  function getMaxRatio() {
18603    const params = swiper.params.zoom;
18604    const maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
18605    if (params.limitToOriginalSize && gesture.imageEl && gesture.imageEl.naturalWidth) {
18606      const imageMaxRatio = gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth;
18607      return Math.min(imageMaxRatio, maxRatio);
18608    }
18609    return maxRatio;
18610  }
18611  function getScaleOrigin() {
18612    if (evCache.length < 2) return {
18613      x: null,
18614      y: null
18615    };
18616    const box = gesture.imageEl.getBoundingClientRect();
18617    return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x - window.scrollX) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y - window.scrollY) / currentScale];
18618  }
18619  function getSlideSelector() {
18620    return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
18621  }
18622  function eventWithinSlide(e) {
18623    const slideSelector = getSlideSelector();
18624    if (e.target.matches(slideSelector)) return true;
18625    if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;
18626    return false;
18627  }
18628  function eventWithinZoomContainer(e) {
18629    const selector = `.${swiper.params.zoom.containerClass}`;
18630    if (e.target.matches(selector)) return true;
18631    if ([...swiper.hostEl.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;
18632    return false;
18633  }
18634
18635  // Events
18636  function onGestureStart(e) {
18637    if (e.pointerType === 'mouse') {
18638      evCache.splice(0, evCache.length);
18639    }
18640    if (!eventWithinSlide(e)) return;
18641    const params = swiper.params.zoom;
18642    fakeGestureTouched = false;
18643    fakeGestureMoved = false;
18644    evCache.push(e);
18645    if (evCache.length < 2) {
18646      return;
18647    }
18648    fakeGestureTouched = true;
18649    gesture.scaleStart = getDistanceBetweenTouches();
18650    if (!gesture.slideEl) {
18651      gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
18652      if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
18653      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
18654      if (imageEl) {
18655        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
18656      }
18657      gesture.imageEl = imageEl;
18658      if (imageEl) {
18659        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
18660      } else {
18661        gesture.imageWrapEl = undefined;
18662      }
18663      if (!gesture.imageWrapEl) {
18664        gesture.imageEl = undefined;
18665        return;
18666      }
18667      gesture.maxRatio = getMaxRatio();
18668    }
18669    if (gesture.imageEl) {
18670      const [originX, originY] = getScaleOrigin();
18671      gesture.originX = originX;
18672      gesture.originY = originY;
18673      gesture.imageEl.style.transitionDuration = '0ms';
18674    }
18675    isScaling = true;
18676  }
18677  function onGestureChange(e) {
18678    if (!eventWithinSlide(e)) return;
18679    const params = swiper.params.zoom;
18680    const zoom = swiper.zoom;
18681    const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
18682    if (pointerIndex >= 0) evCache[pointerIndex] = e;
18683    if (evCache.length < 2) {
18684      return;
18685    }
18686    fakeGestureMoved = true;
18687    gesture.scaleMove = getDistanceBetweenTouches();
18688    if (!gesture.imageEl) {
18689      return;
18690    }
18691    zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;
18692    if (zoom.scale > gesture.maxRatio) {
18693      zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
18694    }
18695    if (zoom.scale < params.minRatio) {
18696      zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
18697    }
18698    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
18699  }
18700  function onGestureEnd(e) {
18701    if (!eventWithinSlide(e)) return;
18702    if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
18703    const params = swiper.params.zoom;
18704    const zoom = swiper.zoom;
18705    const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
18706    if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
18707    if (!fakeGestureTouched || !fakeGestureMoved) {
18708      return;
18709    }
18710    fakeGestureTouched = false;
18711    fakeGestureMoved = false;
18712    if (!gesture.imageEl) return;
18713    zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
18714    gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
18715    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
18716    currentScale = zoom.scale;
18717    isScaling = false;
18718    if (zoom.scale > 1 && gesture.slideEl) {
18719      gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
18720    } else if (zoom.scale <= 1 && gesture.slideEl) {
18721      gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
18722    }
18723    if (zoom.scale === 1) {
18724      gesture.originX = 0;
18725      gesture.originY = 0;
18726      gesture.slideEl = undefined;
18727    }
18728  }
18729  let allowTouchMoveTimeout;
18730  function allowTouchMove() {
18731    swiper.touchEventsData.preventTouchMoveFromPointerMove = false;
18732  }
18733  function preventTouchMove() {
18734    clearTimeout(allowTouchMoveTimeout);
18735    swiper.touchEventsData.preventTouchMoveFromPointerMove = true;
18736    allowTouchMoveTimeout = setTimeout(() => {
18737      if (swiper.destroyed) return;
18738      allowTouchMove();
18739    });
18740  }
18741  function onTouchStart(e) {
18742    const device = swiper.device;
18743    if (!gesture.imageEl) return;
18744    if (image.isTouched) return;
18745    if (device.android && e.cancelable) e.preventDefault();
18746    image.isTouched = true;
18747    const event = evCache.length > 0 ? evCache[0] : e;
18748    image.touchesStart.x = event.pageX;
18749    image.touchesStart.y = event.pageY;
18750  }
18751  function onTouchMove(e) {
18752    const isMouseEvent = e.pointerType === 'mouse';
18753    const isMousePan = isMouseEvent && swiper.params.zoom.panOnMouseMove;
18754    if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) {
18755      return;
18756    }
18757    const zoom = swiper.zoom;
18758    if (!gesture.imageEl) {
18759      return;
18760    }
18761    if (!image.isTouched || !gesture.slideEl) {
18762      if (isMousePan) onMouseMove(e);
18763      return;
18764    }
18765    if (isMousePan) {
18766      onMouseMove(e);
18767      return;
18768    }
18769    if (!image.isMoved) {
18770      image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
18771      image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
18772      image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
18773      image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
18774      gesture.slideWidth = gesture.slideEl.offsetWidth;
18775      gesture.slideHeight = gesture.slideEl.offsetHeight;
18776      gesture.imageWrapEl.style.transitionDuration = '0ms';
18777    }
18778    // Define if we need image drag
18779    const scaledWidth = image.width * zoom.scale;
18780    const scaledHeight = image.height * zoom.scale;
18781    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
18782    image.maxX = -image.minX;
18783    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
18784    image.maxY = -image.minY;
18785    image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
18786    image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
18787    const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y));
18788    if (touchesDiff > 5) {
18789      swiper.allowClick = false;
18790    }
18791    if (!image.isMoved && !isScaling) {
18792      if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {
18793        image.isTouched = false;
18794        allowTouchMove();
18795        return;
18796      }
18797      if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {
18798        image.isTouched = false;
18799        allowTouchMove();
18800        return;
18801      }
18802    }
18803    if (e.cancelable) {
18804      e.preventDefault();
18805    }
18806    e.stopPropagation();
18807    preventTouchMove();
18808    image.isMoved = true;
18809    const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
18810    const {
18811      originX,
18812      originY
18813    } = gesture;
18814    image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
18815    image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
18816    if (image.currentX < image.minX) {
18817      image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
18818    }
18819    if (image.currentX > image.maxX) {
18820      image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
18821    }
18822    if (image.currentY < image.minY) {
18823      image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
18824    }
18825    if (image.currentY > image.maxY) {
18826      image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
18827    }
18828
18829    // Velocity
18830    if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
18831    if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
18832    if (!velocity.prevTime) velocity.prevTime = Date.now();
18833    velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
18834    velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
18835    if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
18836    if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
18837    velocity.prevPositionX = image.touchesCurrent.x;
18838    velocity.prevPositionY = image.touchesCurrent.y;
18839    velocity.prevTime = Date.now();
18840    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
18841  }
18842  function onTouchEnd() {
18843    const zoom = swiper.zoom;
18844    evCache.length = 0;
18845    if (!gesture.imageEl) return;
18846    if (!image.isTouched || !image.isMoved) {
18847      image.isTouched = false;
18848      image.isMoved = false;
18849      return;
18850    }
18851    image.isTouched = false;
18852    image.isMoved = false;
18853    let momentumDurationX = 300;
18854    let momentumDurationY = 300;
18855    const momentumDistanceX = velocity.x * momentumDurationX;
18856    const newPositionX = image.currentX + momentumDistanceX;
18857    const momentumDistanceY = velocity.y * momentumDurationY;
18858    const newPositionY = image.currentY + momentumDistanceY;
18859
18860    // Fix duration
18861    if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
18862    if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
18863    const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
18864    image.currentX = newPositionX;
18865    image.currentY = newPositionY;
18866    // Define if we need image drag
18867    const scaledWidth = image.width * zoom.scale;
18868    const scaledHeight = image.height * zoom.scale;
18869    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
18870    image.maxX = -image.minX;
18871    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
18872    image.maxY = -image.minY;
18873    image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
18874    image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
18875    gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
18876    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
18877  }
18878  function onTransitionEnd() {
18879    const zoom = swiper.zoom;
18880    if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
18881      if (gesture.imageEl) {
18882        gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
18883      }
18884      if (gesture.imageWrapEl) {
18885        gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
18886      }
18887      gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
18888      zoom.scale = 1;
18889      currentScale = 1;
18890      gesture.slideEl = undefined;
18891      gesture.imageEl = undefined;
18892      gesture.imageWrapEl = undefined;
18893      gesture.originX = 0;
18894      gesture.originY = 0;
18895    }
18896  }
18897  function onMouseMove(e) {
18898    // Only pan if zoomed in and mouse panning is enabled
18899    if (currentScale <= 1 || !gesture.imageWrapEl) return;
18900    if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
18901    const currentTransform = window.getComputedStyle(gesture.imageWrapEl).transform;
18902    const matrix = new window.DOMMatrix(currentTransform);
18903    if (!isPanningWithMouse) {
18904      isPanningWithMouse = true;
18905      mousePanStart.x = e.clientX;
18906      mousePanStart.y = e.clientY;
18907      image.startX = matrix.e;
18908      image.startY = matrix.f;
18909      image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
18910      image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
18911      gesture.slideWidth = gesture.slideEl.offsetWidth;
18912      gesture.slideHeight = gesture.slideEl.offsetHeight;
18913      return;
18914    }
18915    const deltaX = (e.clientX - mousePanStart.x) * mousePanSensitivity;
18916    const deltaY = (e.clientY - mousePanStart.y) * mousePanSensitivity;
18917    const scaledWidth = image.width * currentScale;
18918    const scaledHeight = image.height * currentScale;
18919    const slideWidth = gesture.slideWidth;
18920    const slideHeight = gesture.slideHeight;
18921    const minX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
18922    const maxX = -minX;
18923    const minY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
18924    const maxY = -minY;
18925    const newX = Math.max(Math.min(image.startX + deltaX, maxX), minX);
18926    const newY = Math.max(Math.min(image.startY + deltaY, maxY), minY);
18927    gesture.imageWrapEl.style.transitionDuration = '0ms';
18928    gesture.imageWrapEl.style.transform = `translate3d(${newX}px, ${newY}px, 0)`;
18929    mousePanStart.x = e.clientX;
18930    mousePanStart.y = e.clientY;
18931    image.startX = newX;
18932    image.startY = newY;
18933    image.currentX = newX;
18934    image.currentY = newY;
18935  }
18936  function zoomIn(e) {
18937    const zoom = swiper.zoom;
18938    const params = swiper.params.zoom;
18939    if (!gesture.slideEl) {
18940      if (e && e.target) {
18941        gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
18942      }
18943      if (!gesture.slideEl) {
18944        if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
18945          gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
18946        } else {
18947          gesture.slideEl = swiper.slides[swiper.activeIndex];
18948        }
18949      }
18950      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
18951      if (imageEl) {
18952        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
18953      }
18954      gesture.imageEl = imageEl;
18955      if (imageEl) {
18956        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
18957      } else {
18958        gesture.imageWrapEl = undefined;
18959      }
18960    }
18961    if (!gesture.imageEl || !gesture.imageWrapEl) return;
18962    if (swiper.params.cssMode) {
18963      swiper.wrapperEl.style.overflow = 'hidden';
18964      swiper.wrapperEl.style.touchAction = 'none';
18965    }
18966    gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
18967    let touchX;
18968    let touchY;
18969    let offsetX;
18970    let offsetY;
18971    let diffX;
18972    let diffY;
18973    let translateX;
18974    let translateY;
18975    let imageWidth;
18976    let imageHeight;
18977    let scaledWidth;
18978    let scaledHeight;
18979    let translateMinX;
18980    let translateMinY;
18981    let translateMaxX;
18982    let translateMaxY;
18983    let slideWidth;
18984    let slideHeight;
18985    if (typeof image.touchesStart.x === 'undefined' && e) {
18986      touchX = e.pageX;
18987      touchY = e.pageY;
18988    } else {
18989      touchX = image.touchesStart.x;
18990      touchY = image.touchesStart.y;
18991    }
18992    const prevScale = currentScale;
18993    const forceZoomRatio = typeof e === 'number' ? e : null;
18994    if (currentScale === 1 && forceZoomRatio) {
18995      touchX = undefined;
18996      touchY = undefined;
18997      image.touchesStart.x = undefined;
18998      image.touchesStart.y = undefined;
18999    }
19000    const maxRatio = getMaxRatio();
19001    zoom.scale = forceZoomRatio || maxRatio;
19002    currentScale = forceZoomRatio || maxRatio;
19003    if (e && !(currentScale === 1 && forceZoomRatio)) {
19004      slideWidth = gesture.slideEl.offsetWidth;
19005      slideHeight = gesture.slideEl.offsetHeight;
19006      offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
19007      offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
19008      diffX = offsetX + slideWidth / 2 - touchX;
19009      diffY = offsetY + slideHeight / 2 - touchY;
19010      imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
19011      imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
19012      scaledWidth = imageWidth * zoom.scale;
19013      scaledHeight = imageHeight * zoom.scale;
19014      translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
19015      translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
19016      translateMaxX = -translateMinX;
19017      translateMaxY = -translateMinY;
19018      if (prevScale > 0 && forceZoomRatio && typeof image.currentX === 'number' && typeof image.currentY === 'number') {
19019        translateX = image.currentX * zoom.scale / prevScale;
19020        translateY = image.currentY * zoom.scale / prevScale;
19021      } else {
19022        translateX = diffX * zoom.scale;
19023        translateY = diffY * zoom.scale;
19024      }
19025      if (translateX < translateMinX) {
19026        translateX = translateMinX;
19027      }
19028      if (translateX > translateMaxX) {
19029        translateX = translateMaxX;
19030      }
19031      if (translateY < translateMinY) {
19032        translateY = translateMinY;
19033      }
19034      if (translateY > translateMaxY) {
19035        translateY = translateMaxY;
19036      }
19037    } else {
19038      translateX = 0;
19039      translateY = 0;
19040    }
19041    if (forceZoomRatio && zoom.scale === 1) {
19042      gesture.originX = 0;
19043      gesture.originY = 0;
19044    }
19045    image.currentX = translateX;
19046    image.currentY = translateY;
19047    gesture.imageWrapEl.style.transitionDuration = '300ms';
19048    gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
19049    gesture.imageEl.style.transitionDuration = '300ms';
19050    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
19051  }
19052  function zoomOut() {
19053    const zoom = swiper.zoom;
19054    const params = swiper.params.zoom;
19055    if (!gesture.slideEl) {
19056      if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
19057        gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
19058      } else {
19059        gesture.slideEl = swiper.slides[swiper.activeIndex];
19060      }
19061      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
19062      if (imageEl) {
19063        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
19064      }
19065      gesture.imageEl = imageEl;
19066      if (imageEl) {
19067        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
19068      } else {
19069        gesture.imageWrapEl = undefined;
19070      }
19071    }
19072    if (!gesture.imageEl || !gesture.imageWrapEl) return;
19073    if (swiper.params.cssMode) {
19074      swiper.wrapperEl.style.overflow = '';
19075      swiper.wrapperEl.style.touchAction = '';
19076    }
19077    zoom.scale = 1;
19078    currentScale = 1;
19079    image.currentX = undefined;
19080    image.currentY = undefined;
19081    image.touchesStart.x = undefined;
19082    image.touchesStart.y = undefined;
19083    gesture.imageWrapEl.style.transitionDuration = '300ms';
19084    gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
19085    gesture.imageEl.style.transitionDuration = '300ms';
19086    gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
19087    gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
19088    gesture.slideEl = undefined;
19089    gesture.originX = 0;
19090    gesture.originY = 0;
19091    if (swiper.params.zoom.panOnMouseMove) {
19092      mousePanStart = {
19093        x: 0,
19094        y: 0
19095      };
19096      if (isPanningWithMouse) {
19097        isPanningWithMouse = false;
19098        image.startX = 0;
19099        image.startY = 0;
19100      }
19101    }
19102  }
19103
19104  // Toggle Zoom
19105  function zoomToggle(e) {
19106    const zoom = swiper.zoom;
19107    if (zoom.scale && zoom.scale !== 1) {
19108      // Zoom Out
19109      zoomOut();
19110    } else {
19111      // Zoom In
19112      zoomIn(e);
19113    }
19114  }
19115  function getListeners() {
19116    const passiveListener = swiper.params.passiveListeners ? {
19117      passive: true,
19118      capture: false
19119    } : false;
19120    const activeListenerWithCapture = swiper.params.passiveListeners ? {
19121      passive: false,
19122      capture: true
19123    } : true;
19124    return {
19125      passiveListener,
19126      activeListenerWithCapture
19127    };
19128  }
19129
19130  // Attach/Detach Events
19131  function enable() {
19132    const zoom = swiper.zoom;
19133    if (zoom.enabled) return;
19134    zoom.enabled = true;
19135    const {
19136      passiveListener,
19137      activeListenerWithCapture
19138    } = getListeners();
19139
19140    // Scale image
19141    swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
19142    swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
19143    ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
19144      swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
19145    });
19146
19147    // Move image
19148    swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
19149  }
19150  function disable() {
19151    const zoom = swiper.zoom;
19152    if (!zoom.enabled) return;
19153    zoom.enabled = false;
19154    const {
19155      passiveListener,
19156      activeListenerWithCapture
19157    } = getListeners();
19158
19159    // Scale image
19160    swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
19161    swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
19162    ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
19163      swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
19164    });
19165
19166    // Move image
19167    swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
19168  }
19169  on('init', () => {
19170    if (swiper.params.zoom.enabled) {
19171      enable();
19172    }
19173  });
19174  on('destroy', () => {
19175    disable();
19176  });
19177  on('touchStart', (_s, e) => {
19178    if (!swiper.zoom.enabled) return;
19179    onTouchStart(e);
19180  });
19181  on('touchEnd', (_s, e) => {
19182    if (!swiper.zoom.enabled) return;
19183    onTouchEnd();
19184  });
19185  on('doubleTap', (_s, e) => {
19186    if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
19187      zoomToggle(e);
19188    }
19189  });
19190  on('transitionEnd', () => {
19191    if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
19192      onTransitionEnd();
19193    }
19194  });
19195  on('slideChange', () => {
19196    if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
19197      onTransitionEnd();
19198    }
19199  });
19200  Object.assign(swiper.zoom, {
19201    enable,
19202    disable,
19203    in: zoomIn,
19204    out: zoomOut,
19205    toggle: zoomToggle
19206  });
19207}
19208
19209
19210
19211;// ./node_modules/swiper/modules/controller.mjs
19212
19213
19214/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
19215function Controller(_ref) {
19216  let {
19217    swiper,
19218    extendParams,
19219    on
19220  } = _ref;
19221  extendParams({
19222    controller: {
19223      control: undefined,
19224      inverse: false,
19225      by: 'slide' // or 'container'
19226    }
19227  });
19228
19229  swiper.controller = {
19230    control: undefined
19231  };
19232  function LinearSpline(x, y) {
19233    const binarySearch = function search() {
19234      let maxIndex;
19235      let minIndex;
19236      let guess;
19237      return (array, val) => {
19238        minIndex = -1;
19239        maxIndex = array.length;
19240        while (maxIndex - minIndex > 1) {
19241          guess = maxIndex + minIndex >> 1;
19242          if (array[guess] <= val) {
19243            minIndex = guess;
19244          } else {
19245            maxIndex = guess;
19246          }
19247        }
19248        return maxIndex;
19249      };
19250    }();
19251    this.x = x;
19252    this.y = y;
19253    this.lastIndex = x.length - 1;
19254    // Given an x value (x2), return the expected y2 value:
19255    // (x1,y1) is the known point before given value,
19256    // (x3,y3) is the known point after given value.
19257    let i1;
19258    let i3;
19259    this.interpolate = function interpolate(x2) {
19260      if (!x2) return 0;
19261
19262      // Get the indexes of x1 and x3 (the array indexes before and after given x2):
19263      i3 = binarySearch(this.x, x2);
19264      i1 = i3 - 1;
19265
19266      // We have our indexes i1 & i3, so we can calculate already:
19267      // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
19268      return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
19269    };
19270    return this;
19271  }
19272  function getInterpolateFunction(c) {
19273    swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);
19274  }
19275  function setTranslate(_t, byController) {
19276    const controlled = swiper.controller.control;
19277    let multiplier;
19278    let controlledTranslate;
19279    const Swiper = swiper.constructor;
19280    function setControlledTranslate(c) {
19281      if (c.destroyed) return;
19282
19283      // this will create an Interpolate function based on the snapGrids
19284      // x is the Grid of the scrolled scroller and y will be the controlled scroller
19285      // it makes sense to create this only once and recall it for the interpolation
19286      // the function does a lot of value caching for performance
19287      const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
19288      if (swiper.params.controller.by === 'slide') {
19289        getInterpolateFunction(c);
19290        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
19291        // but it did not work out
19292        controlledTranslate = -swiper.controller.spline.interpolate(-translate);
19293      }
19294      if (!controlledTranslate || swiper.params.controller.by === 'container') {
19295        multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
19296        if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
19297          multiplier = 1;
19298        }
19299        controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
19300      }
19301      if (swiper.params.controller.inverse) {
19302        controlledTranslate = c.maxTranslate() - controlledTranslate;
19303      }
19304      c.updateProgress(controlledTranslate);
19305      c.setTranslate(controlledTranslate, swiper);
19306      c.updateActiveIndex();
19307      c.updateSlidesClasses();
19308    }
19309    if (Array.isArray(controlled)) {
19310      for (let i = 0; i < controlled.length; i += 1) {
19311        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
19312          setControlledTranslate(controlled[i]);
19313        }
19314      }
19315    } else if (controlled instanceof Swiper && byController !== controlled) {
19316      setControlledTranslate(controlled);
19317    }
19318  }
19319  function setTransition(duration, byController) {
19320    const Swiper = swiper.constructor;
19321    const controlled = swiper.controller.control;
19322    let i;
19323    function setControlledTransition(c) {
19324      if (c.destroyed) return;
19325      c.setTransition(duration, swiper);
19326      if (duration !== 0) {
19327        c.transitionStart();
19328        if (c.params.autoHeight) {
19329          nextTick(() => {
19330            c.updateAutoHeight();
19331          });
19332        }
19333        elementTransitionEnd(c.wrapperEl, () => {
19334          if (!controlled) return;
19335          c.transitionEnd();
19336        });
19337      }
19338    }
19339    if (Array.isArray(controlled)) {
19340      for (i = 0; i < controlled.length; i += 1) {
19341        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
19342          setControlledTransition(controlled[i]);
19343        }
19344      }
19345    } else if (controlled instanceof Swiper && byController !== controlled) {
19346      setControlledTransition(controlled);
19347    }
19348  }
19349  function removeSpline() {
19350    if (!swiper.controller.control) return;
19351    if (swiper.controller.spline) {
19352      swiper.controller.spline = undefined;
19353      delete swiper.controller.spline;
19354    }
19355  }
19356  on('beforeInit', () => {
19357    if (typeof window !== 'undefined' && (
19358    // eslint-disable-line
19359    typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) {
19360      const controlElements = typeof swiper.params.controller.control === 'string' ? [...document.querySelectorAll(swiper.params.controller.control)] : [swiper.params.controller.control];
19361      controlElements.forEach(controlElement => {
19362        if (!swiper.controller.control) swiper.controller.control = [];
19363        if (controlElement && controlElement.swiper) {
19364          swiper.controller.control.push(controlElement.swiper);
19365        } else if (controlElement) {
19366          const eventName = `${swiper.params.eventsPrefix}init`;
19367          const onControllerSwiper = e => {
19368            swiper.controller.control.push(e.detail[0]);
19369            swiper.update();
19370            controlElement.removeEventListener(eventName, onControllerSwiper);
19371          };
19372          controlElement.addEventListener(eventName, onControllerSwiper);
19373        }
19374      });
19375      return;
19376    }
19377    swiper.controller.control = swiper.params.controller.control;
19378  });
19379  on('update', () => {
19380    removeSpline();
19381  });
19382  on('resize', () => {
19383    removeSpline();
19384  });
19385  on('observerUpdate', () => {
19386    removeSpline();
19387  });
19388  on('setTranslate', (_s, translate, byController) => {
19389    if (!swiper.controller.control || swiper.controller.control.destroyed) return;
19390    swiper.controller.setTranslate(translate, byController);
19391  });
19392  on('setTransition', (_s, duration, byController) => {
19393    if (!swiper.controller.control || swiper.controller.control.destroyed) return;
19394    swiper.controller.setTransition(duration, byController);
19395  });
19396  Object.assign(swiper.controller, {
19397    setTranslate,
19398    setTransition
19399  });
19400}
19401
19402
19403
19404;// ./node_modules/swiper/modules/a11y.mjs
19405
19406
19407
19408
19409function A11y(_ref) {
19410  let {
19411    swiper,
19412    extendParams,
19413    on
19414  } = _ref;
19415  extendParams({
19416    a11y: {
19417      enabled: true,
19418      notificationClass: 'swiper-notification',
19419      prevSlideMessage: 'Previous slide',
19420      nextSlideMessage: 'Next slide',
19421      firstSlideMessage: 'This is the first slide',
19422      lastSlideMessage: 'This is the last slide',
19423      paginationBulletMessage: 'Go to slide {{index}}',
19424      slideLabelMessage: '{{index}} / {{slidesLength}}',
19425      containerMessage: null,
19426      containerRoleDescriptionMessage: null,
19427      containerRole: null,
19428      itemRoleDescriptionMessage: null,
19429      slideRole: 'group',
19430      id: null,
19431      scrollOnFocus: true
19432    }
19433  });
19434  swiper.a11y = {
19435    clicked: false
19436  };
19437  let liveRegion = null;
19438  let preventFocusHandler;
19439  let focusTargetSlideEl;
19440  let visibilityChangedTimestamp = new Date().getTime();
19441  function notify(message) {
19442    const notification = liveRegion;
19443    if (notification.length === 0) return;
19444    setInnerHTML(notification, message);
19445  }
19446  function getRandomNumber(size) {
19447    if (size === void 0) {
19448      size = 16;
19449    }
19450    const randomChar = () => Math.round(16 * Math.random()).toString(16);
19451    return 'x'.repeat(size).replace(/x/g, randomChar);
19452  }
19453  function makeElFocusable(el) {
19454    el = makeElementsArray(el);
19455    el.forEach(subEl => {
19456      subEl.setAttribute('tabIndex', '0');
19457    });
19458  }
19459  function makeElNotFocusable(el) {
19460    el = makeElementsArray(el);
19461    el.forEach(subEl => {
19462      subEl.setAttribute('tabIndex', '-1');
19463    });
19464  }
19465  function addElRole(el, role) {
19466    el = makeElementsArray(el);
19467    el.forEach(subEl => {
19468      subEl.setAttribute('role', role);
19469    });
19470  }
19471  function addElRoleDescription(el, description) {
19472    el = makeElementsArray(el);
19473    el.forEach(subEl => {
19474      subEl.setAttribute('aria-roledescription', description);
19475    });
19476  }
19477  function addElControls(el, controls) {
19478    el = makeElementsArray(el);
19479    el.forEach(subEl => {
19480      subEl.setAttribute('aria-controls', controls);
19481    });
19482  }
19483  function addElLabel(el, label) {
19484    el = makeElementsArray(el);
19485    el.forEach(subEl => {
19486      subEl.setAttribute('aria-label', label);
19487    });
19488  }
19489  function addElId(el, id) {
19490    el = makeElementsArray(el);
19491    el.forEach(subEl => {
19492      subEl.setAttribute('id', id);
19493    });
19494  }
19495  function addElLive(el, live) {
19496    el = makeElementsArray(el);
19497    el.forEach(subEl => {
19498      subEl.setAttribute('aria-live', live);
19499    });
19500  }
19501  function disableEl(el) {
19502    el = makeElementsArray(el);
19503    el.forEach(subEl => {
19504      subEl.setAttribute('aria-disabled', true);
19505    });
19506  }
19507  function enableEl(el) {
19508    el = makeElementsArray(el);
19509    el.forEach(subEl => {
19510      subEl.setAttribute('aria-disabled', false);
19511    });
19512  }
19513  function onEnterOrSpaceKey(e) {
19514    if (e.keyCode !== 13 && e.keyCode !== 32) return;
19515    const params = swiper.params.a11y;
19516    const targetEl = e.target;
19517    if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
19518      if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
19519    }
19520    if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
19521      const prevEls = makeElementsArray(swiper.navigation.prevEl);
19522      const nextEls = makeElementsArray(swiper.navigation.nextEl);
19523      if (nextEls.includes(targetEl)) {
19524        if (!(swiper.isEnd && !swiper.params.loop)) {
19525          swiper.slideNext();
19526        }
19527        if (swiper.isEnd) {
19528          notify(params.lastSlideMessage);
19529        } else {
19530          notify(params.nextSlideMessage);
19531        }
19532      }
19533      if (prevEls.includes(targetEl)) {
19534        if (!(swiper.isBeginning && !swiper.params.loop)) {
19535          swiper.slidePrev();
19536        }
19537        if (swiper.isBeginning) {
19538          notify(params.firstSlideMessage);
19539        } else {
19540          notify(params.prevSlideMessage);
19541        }
19542      }
19543    }
19544    if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
19545      targetEl.click();
19546    }
19547  }
19548  function updateNavigation() {
19549    if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
19550    const {
19551      nextEl,
19552      prevEl
19553    } = swiper.navigation;
19554    if (prevEl) {
19555      if (swiper.isBeginning) {
19556        disableEl(prevEl);
19557        makeElNotFocusable(prevEl);
19558      } else {
19559        enableEl(prevEl);
19560        makeElFocusable(prevEl);
19561      }
19562    }
19563    if (nextEl) {
19564      if (swiper.isEnd) {
19565        disableEl(nextEl);
19566        makeElNotFocusable(nextEl);
19567      } else {
19568        enableEl(nextEl);
19569        makeElFocusable(nextEl);
19570      }
19571    }
19572  }
19573  function hasPagination() {
19574    return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
19575  }
19576  function hasClickablePagination() {
19577    return hasPagination() && swiper.params.pagination.clickable;
19578  }
19579  function updatePagination() {
19580    const params = swiper.params.a11y;
19581    if (!hasPagination()) return;
19582    swiper.pagination.bullets.forEach(bulletEl => {
19583      if (swiper.params.pagination.clickable) {
19584        makeElFocusable(bulletEl);
19585        if (!swiper.params.pagination.renderBullet) {
19586          addElRole(bulletEl, 'button');
19587          addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
19588        }
19589      }
19590      if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
19591        bulletEl.setAttribute('aria-current', 'true');
19592      } else {
19593        bulletEl.removeAttribute('aria-current');
19594      }
19595    });
19596  }
19597  const initNavEl = (el, wrapperId, message) => {
19598    makeElFocusable(el);
19599    if (el.tagName !== 'BUTTON') {
19600      addElRole(el, 'button');
19601      el.addEventListener('keydown', onEnterOrSpaceKey);
19602    }
19603    addElLabel(el, message);
19604    addElControls(el, wrapperId);
19605  };
19606  const handlePointerDown = e => {
19607    if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) {
19608      preventFocusHandler = true;
19609    }
19610    swiper.a11y.clicked = true;
19611  };
19612  const handlePointerUp = () => {
19613    preventFocusHandler = false;
19614    requestAnimationFrame(() => {
19615      requestAnimationFrame(() => {
19616        if (!swiper.destroyed) {
19617          swiper.a11y.clicked = false;
19618        }
19619      });
19620    });
19621  };
19622  const onVisibilityChange = e => {
19623    visibilityChangedTimestamp = new Date().getTime();
19624  };
19625  const handleFocus = e => {
19626    if (swiper.a11y.clicked || !swiper.params.a11y.scrollOnFocus) return;
19627    if (new Date().getTime() - visibilityChangedTimestamp < 100) return;
19628    const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
19629    if (!slideEl || !swiper.slides.includes(slideEl)) return;
19630    focusTargetSlideEl = slideEl;
19631    const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
19632    const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
19633    if (isActive || isVisible) return;
19634    if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
19635    if (swiper.isHorizontal()) {
19636      swiper.el.scrollLeft = 0;
19637    } else {
19638      swiper.el.scrollTop = 0;
19639    }
19640    requestAnimationFrame(() => {
19641      if (preventFocusHandler) return;
19642      if (swiper.params.loop) {
19643        swiper.slideToLoop(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index'))), 0);
19644      } else {
19645        swiper.slideTo(swiper.getSlideIndexWhenGrid(swiper.slides.indexOf(slideEl)), 0);
19646      }
19647      preventFocusHandler = false;
19648    });
19649  };
19650  const initSlides = () => {
19651    const params = swiper.params.a11y;
19652    if (params.itemRoleDescriptionMessage) {
19653      addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
19654    }
19655    if (params.slideRole) {
19656      addElRole(swiper.slides, params.slideRole);
19657    }
19658    const slidesLength = swiper.slides.length;
19659    if (params.slideLabelMessage) {
19660      swiper.slides.forEach((slideEl, index) => {
19661        const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
19662        const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
19663        addElLabel(slideEl, ariaLabelMessage);
19664      });
19665    }
19666  };
19667  const init = () => {
19668    const params = swiper.params.a11y;
19669    swiper.el.append(liveRegion);
19670
19671    // Container
19672    const containerEl = swiper.el;
19673    if (params.containerRoleDescriptionMessage) {
19674      addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
19675    }
19676    if (params.containerMessage) {
19677      addElLabel(containerEl, params.containerMessage);
19678    }
19679    if (params.containerRole) {
19680      addElRole(containerEl, params.containerRole);
19681    }
19682
19683    // Wrapper
19684    const wrapperEl = swiper.wrapperEl;
19685    const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
19686    const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
19687    addElId(wrapperEl, wrapperId);
19688    addElLive(wrapperEl, live);
19689
19690    // Slide
19691    initSlides();
19692
19693    // Navigation
19694    let {
19695      nextEl,
19696      prevEl
19697    } = swiper.navigation ? swiper.navigation : {};
19698    nextEl = makeElementsArray(nextEl);
19699    prevEl = makeElementsArray(prevEl);
19700    if (nextEl) {
19701      nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage));
19702    }
19703    if (prevEl) {
19704      prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage));
19705    }
19706
19707    // Pagination
19708    if (hasClickablePagination()) {
19709      const paginationEl = makeElementsArray(swiper.pagination.el);
19710      paginationEl.forEach(el => {
19711        el.addEventListener('keydown', onEnterOrSpaceKey);
19712      });
19713    }
19714
19715    // Tab focus
19716    const document = getDocument();
19717    document.addEventListener('visibilitychange', onVisibilityChange);
19718    swiper.el.addEventListener('focus', handleFocus, true);
19719    swiper.el.addEventListener('focus', handleFocus, true);
19720    swiper.el.addEventListener('pointerdown', handlePointerDown, true);
19721    swiper.el.addEventListener('pointerup', handlePointerUp, true);
19722  };
19723  function destroy() {
19724    if (liveRegion) liveRegion.remove();
19725    let {
19726      nextEl,
19727      prevEl
19728    } = swiper.navigation ? swiper.navigation : {};
19729    nextEl = makeElementsArray(nextEl);
19730    prevEl = makeElementsArray(prevEl);
19731    if (nextEl) {
19732      nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
19733    }
19734    if (prevEl) {
19735      prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
19736    }
19737
19738    // Pagination
19739    if (hasClickablePagination()) {
19740      const paginationEl = makeElementsArray(swiper.pagination.el);
19741      paginationEl.forEach(el => {
19742        el.removeEventListener('keydown', onEnterOrSpaceKey);
19743      });
19744    }
19745    const document = getDocument();
19746    document.removeEventListener('visibilitychange', onVisibilityChange);
19747    // Tab focus
19748    if (swiper.el && typeof swiper.el !== 'string') {
19749      swiper.el.removeEventListener('focus', handleFocus, true);
19750      swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
19751      swiper.el.removeEventListener('pointerup', handlePointerUp, true);
19752    }
19753  }
19754  on('beforeInit', () => {
19755    liveRegion = createElement('span', swiper.params.a11y.notificationClass);
19756    liveRegion.setAttribute('aria-live', 'assertive');
19757    liveRegion.setAttribute('aria-atomic', 'true');
19758  });
19759  on('afterInit', () => {
19760    if (!swiper.params.a11y.enabled) return;
19761    init();
19762  });
19763  on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
19764    if (!swiper.params.a11y.enabled) return;
19765    initSlides();
19766  });
19767  on('fromEdge toEdge afterInit lock unlock', () => {
19768    if (!swiper.params.a11y.enabled) return;
19769    updateNavigation();
19770  });
19771  on('paginationUpdate', () => {
19772    if (!swiper.params.a11y.enabled) return;
19773    updatePagination();
19774  });
19775  on('destroy', () => {
19776    if (!swiper.params.a11y.enabled) return;
19777    destroy();
19778  });
19779}
19780
19781
19782
19783;// ./node_modules/swiper/modules/history.mjs
19784
19785
19786function History(_ref) {
19787  let {
19788    swiper,
19789    extendParams,
19790    on
19791  } = _ref;
19792  extendParams({
19793    history: {
19794      enabled: false,
19795      root: '',
19796      replaceState: false,
19797      key: 'slides',
19798      keepQuery: false
19799    }
19800  });
19801  let initialized = false;
19802  let paths = {};
19803  const slugify = text => {
19804    return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
19805  };
19806  const getPathValues = urlOverride => {
19807    const window = getWindow();
19808    let location;
19809    if (urlOverride) {
19810      location = new URL(urlOverride);
19811    } else {
19812      location = window.location;
19813    }
19814    const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
19815    const total = pathArray.length;
19816    const key = pathArray[total - 2];
19817    const value = pathArray[total - 1];
19818    return {
19819      key,
19820      value
19821    };
19822  };
19823  const setHistory = (key, index) => {
19824    const window = getWindow();
19825    if (!initialized || !swiper.params.history.enabled) return;
19826    let location;
19827    if (swiper.params.url) {
19828      location = new URL(swiper.params.url);
19829    } else {
19830      location = window.location;
19831    }
19832    const slide = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${index}"]`) : swiper.slides[index];
19833    let value = slugify(slide.getAttribute('data-history'));
19834    if (swiper.params.history.root.length > 0) {
19835      let root = swiper.params.history.root;
19836      if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
19837      value = `${root}/${key ? `${key}/` : ''}${value}`;
19838    } else if (!location.pathname.includes(key)) {
19839      value = `${key ? `${key}/` : ''}${value}`;
19840    }
19841    if (swiper.params.history.keepQuery) {
19842      value += location.search;
19843    }
19844    const currentState = window.history.state;
19845    if (currentState && currentState.value === value) {
19846      return;
19847    }
19848    if (swiper.params.history.replaceState) {
19849      window.history.replaceState({
19850        value
19851      }, null, value);
19852    } else {
19853      window.history.pushState({
19854        value
19855      }, null, value);
19856    }
19857  };
19858  const scrollToSlide = (speed, value, runCallbacks) => {
19859    if (value) {
19860      for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
19861        const slide = swiper.slides[i];
19862        const slideHistory = slugify(slide.getAttribute('data-history'));
19863        if (slideHistory === value) {
19864          const index = swiper.getSlideIndex(slide);
19865          swiper.slideTo(index, speed, runCallbacks);
19866        }
19867      }
19868    } else {
19869      swiper.slideTo(0, speed, runCallbacks);
19870    }
19871  };
19872  const setHistoryPopState = () => {
19873    paths = getPathValues(swiper.params.url);
19874    scrollToSlide(swiper.params.speed, paths.value, false);
19875  };
19876  const init = () => {
19877    const window = getWindow();
19878    if (!swiper.params.history) return;
19879    if (!window.history || !window.history.pushState) {
19880      swiper.params.history.enabled = false;
19881      swiper.params.hashNavigation.enabled = true;
19882      return;
19883    }
19884    initialized = true;
19885    paths = getPathValues(swiper.params.url);
19886    if (!paths.key && !paths.value) {
19887      if (!swiper.params.history.replaceState) {
19888        window.addEventListener('popstate', setHistoryPopState);
19889      }
19890      return;
19891    }
19892    scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
19893    if (!swiper.params.history.replaceState) {
19894      window.addEventListener('popstate', setHistoryPopState);
19895    }
19896  };
19897  const destroy = () => {
19898    const window = getWindow();
19899    if (!swiper.params.history.replaceState) {
19900      window.removeEventListener('popstate', setHistoryPopState);
19901    }
19902  };
19903  on('init', () => {
19904    if (swiper.params.history.enabled) {
19905      init();
19906    }
19907  });
19908  on('destroy', () => {
19909    if (swiper.params.history.enabled) {
19910      destroy();
19911    }
19912  });
19913  on('transitionEnd _freeModeNoMomentumRelease', () => {
19914    if (initialized) {
19915      setHistory(swiper.params.history.key, swiper.activeIndex);
19916    }
19917  });
19918  on('slideChange', () => {
19919    if (initialized && swiper.params.cssMode) {
19920      setHistory(swiper.params.history.key, swiper.activeIndex);
19921    }
19922  });
19923}
19924
19925
19926
19927;// ./node_modules/swiper/modules/hash-navigation.mjs
19928
19929
19930
19931function HashNavigation(_ref) {
19932  let {
19933    swiper,
19934    extendParams,
19935    emit,
19936    on
19937  } = _ref;
19938  let initialized = false;
19939  const document = getDocument();
19940  const window = getWindow();
19941  extendParams({
19942    hashNavigation: {
19943      enabled: false,
19944      replaceState: false,
19945      watchState: false,
19946      getSlideIndex(_s, hash) {
19947        if (swiper.virtual && swiper.params.virtual.enabled) {
19948          const slideWithHash = swiper.slides.find(slideEl => slideEl.getAttribute('data-hash') === hash);
19949          if (!slideWithHash) return 0;
19950          const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
19951          return index;
19952        }
19953        return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]);
19954      }
19955    }
19956  });
19957  const onHashChange = () => {
19958    emit('hashChange');
19959    const newHash = document.location.hash.replace('#', '');
19960    const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
19961    const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
19962    if (newHash !== activeSlideHash) {
19963      const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
19964      if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
19965      swiper.slideTo(newIndex);
19966    }
19967  };
19968  const setHash = () => {
19969    if (!initialized || !swiper.params.hashNavigation.enabled) return;
19970    const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
19971    const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : '';
19972    if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
19973      window.history.replaceState(null, null, `#${activeSlideHash}` || '');
19974      emit('hashSet');
19975    } else {
19976      document.location.hash = activeSlideHash || '';
19977      emit('hashSet');
19978    }
19979  };
19980  const init = () => {
19981    if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
19982    initialized = true;
19983    const hash = document.location.hash.replace('#', '');
19984    if (hash) {
19985      const speed = 0;
19986      const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
19987      swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
19988    }
19989    if (swiper.params.hashNavigation.watchState) {
19990      window.addEventListener('hashchange', onHashChange);
19991    }
19992  };
19993  const destroy = () => {
19994    if (swiper.params.hashNavigation.watchState) {
19995      window.removeEventListener('hashchange', onHashChange);
19996    }
19997  };
19998  on('init', () => {
19999    if (swiper.params.hashNavigation.enabled) {
20000      init();
20001    }
20002  });
20003  on('destroy', () => {
20004    if (swiper.params.hashNavigation.enabled) {
20005      destroy();
20006    }
20007  });
20008  on('transitionEnd _freeModeNoMomentumRelease', () => {
20009    if (initialized) {
20010      setHash();
20011    }
20012  });
20013  on('slideChange', () => {
20014    if (initialized && swiper.params.cssMode) {
20015      setHash();
20016    }
20017  });
20018}
20019
20020
20021
20022;// ./node_modules/swiper/modules/autoplay.mjs
20023
20024
20025/* eslint no-underscore-dangle: "off" */
20026/* eslint no-use-before-define: "off" */
20027function Autoplay(_ref) {
20028  let {
20029    swiper,
20030    extendParams,
20031    on,
20032    emit,
20033    params
20034  } = _ref;
20035  swiper.autoplay = {
20036    running: false,
20037    paused: false,
20038    timeLeft: 0
20039  };
20040  extendParams({
20041    autoplay: {
20042      enabled: false,
20043      delay: 3000,
20044      waitForTransition: true,
20045      disableOnInteraction: false,
20046      stopOnLastSlide: false,
20047      reverseDirection: false,
20048      pauseOnMouseEnter: false
20049    }
20050  });
20051  let timeout;
20052  let raf;
20053  let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
20054  let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
20055  let autoplayTimeLeft;
20056  let autoplayStartTime = new Date().getTime();
20057  let wasPaused;
20058  let isTouched;
20059  let pausedByTouch;
20060  let touchStartTimeout;
20061  let slideChanged;
20062  let pausedByInteraction;
20063  let pausedByPointerEnter;
20064  function onTransitionEnd(e) {
20065    if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
20066    if (e.target !== swiper.wrapperEl) return;
20067    swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
20068    if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
20069      return;
20070    }
20071    resume();
20072  }
20073  const calcTimeLeft = () => {
20074    if (swiper.destroyed || !swiper.autoplay.running) return;
20075    if (swiper.autoplay.paused) {
20076      wasPaused = true;
20077    } else if (wasPaused) {
20078      autoplayDelayCurrent = autoplayTimeLeft;
20079      wasPaused = false;
20080    }
20081    const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
20082    swiper.autoplay.timeLeft = timeLeft;
20083    emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
20084    raf = requestAnimationFrame(() => {
20085      calcTimeLeft();
20086    });
20087  };
20088  const getSlideDelay = () => {
20089    let activeSlideEl;
20090    if (swiper.virtual && swiper.params.virtual.enabled) {
20091      activeSlideEl = swiper.slides.find(slideEl => slideEl.classList.contains('swiper-slide-active'));
20092    } else {
20093      activeSlideEl = swiper.slides[swiper.activeIndex];
20094    }
20095    if (!activeSlideEl) return undefined;
20096    const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
20097    return currentSlideDelay;
20098  };
20099  const run = delayForce => {
20100    if (swiper.destroyed || !swiper.autoplay.running) return;
20101    cancelAnimationFrame(raf);
20102    calcTimeLeft();
20103    let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
20104    autoplayDelayTotal = swiper.params.autoplay.delay;
20105    autoplayDelayCurrent = swiper.params.autoplay.delay;
20106    const currentSlideDelay = getSlideDelay();
20107    if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
20108      delay = currentSlideDelay;
20109      autoplayDelayTotal = currentSlideDelay;
20110      autoplayDelayCurrent = currentSlideDelay;
20111    }
20112    autoplayTimeLeft = delay;
20113    const speed = swiper.params.speed;
20114    const proceed = () => {
20115      if (!swiper || swiper.destroyed) return;
20116      if (swiper.params.autoplay.reverseDirection) {
20117        if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
20118          swiper.slidePrev(speed, true, true);
20119          emit('autoplay');
20120        } else if (!swiper.params.autoplay.stopOnLastSlide) {
20121          swiper.slideTo(swiper.slides.length - 1, speed, true, true);
20122          emit('autoplay');
20123        }
20124      } else {
20125        if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
20126          swiper.slideNext(speed, true, true);
20127          emit('autoplay');
20128        } else if (!swiper.params.autoplay.stopOnLastSlide) {
20129          swiper.slideTo(0, speed, true, true);
20130          emit('autoplay');
20131        }
20132      }
20133      if (swiper.params.cssMode) {
20134        autoplayStartTime = new Date().getTime();
20135        requestAnimationFrame(() => {
20136          run();
20137        });
20138      }
20139    };
20140    if (delay > 0) {
20141      clearTimeout(timeout);
20142      timeout = setTimeout(() => {
20143        proceed();
20144      }, delay);
20145    } else {
20146      requestAnimationFrame(() => {
20147        proceed();
20148      });
20149    }
20150
20151    // eslint-disable-next-line
20152    return delay;
20153  };
20154  const start = () => {
20155    autoplayStartTime = new Date().getTime();
20156    swiper.autoplay.running = true;
20157    run();
20158    emit('autoplayStart');
20159  };
20160  const stop = () => {
20161    swiper.autoplay.running = false;
20162    clearTimeout(timeout);
20163    cancelAnimationFrame(raf);
20164    emit('autoplayStop');
20165  };
20166  const pause = (internal, reset) => {
20167    if (swiper.destroyed || !swiper.autoplay.running) return;
20168    clearTimeout(timeout);
20169    if (!internal) {
20170      pausedByInteraction = true;
20171    }
20172    const proceed = () => {
20173      emit('autoplayPause');
20174      if (swiper.params.autoplay.waitForTransition) {
20175        swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
20176      } else {
20177        resume();
20178      }
20179    };
20180    swiper.autoplay.paused = true;
20181    if (reset) {
20182      if (slideChanged) {
20183        autoplayTimeLeft = swiper.params.autoplay.delay;
20184      }
20185      slideChanged = false;
20186      proceed();
20187      return;
20188    }
20189    const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
20190    autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
20191    if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
20192    if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
20193    proceed();
20194  };
20195  const resume = () => {
20196    if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
20197    autoplayStartTime = new Date().getTime();
20198    if (pausedByInteraction) {
20199      pausedByInteraction = false;
20200      run(autoplayTimeLeft);
20201    } else {
20202      run();
20203    }
20204    swiper.autoplay.paused = false;
20205    emit('autoplayResume');
20206  };
20207  const onVisibilityChange = () => {
20208    if (swiper.destroyed || !swiper.autoplay.running) return;
20209    const document = ssr_window_esm_getDocument();
20210    if (document.visibilityState === 'hidden') {
20211      pausedByInteraction = true;
20212      pause(true);
20213    }
20214    if (document.visibilityState === 'visible') {
20215      resume();
20216    }
20217  };
20218  const onPointerEnter = e => {
20219    if (e.pointerType !== 'mouse') return;
20220    pausedByInteraction = true;
20221    pausedByPointerEnter = true;
20222    if (swiper.animating || swiper.autoplay.paused) return;
20223    pause(true);
20224  };
20225  const onPointerLeave = e => {
20226    if (e.pointerType !== 'mouse') return;
20227    pausedByPointerEnter = false;
20228    if (swiper.autoplay.paused) {
20229      resume();
20230    }
20231  };
20232  const attachMouseEvents = () => {
20233    if (swiper.params.autoplay.pauseOnMouseEnter) {
20234      swiper.el.addEventListener('pointerenter', onPointerEnter);
20235      swiper.el.addEventListener('pointerleave', onPointerLeave);
20236    }
20237  };
20238  const detachMouseEvents = () => {
20239    if (swiper.el && typeof swiper.el !== 'string') {
20240      swiper.el.removeEventListener('pointerenter', onPointerEnter);
20241      swiper.el.removeEventListener('pointerleave', onPointerLeave);
20242    }
20243  };
20244  const attachDocumentEvents = () => {
20245    const document = ssr_window_esm_getDocument();
20246    document.addEventListener('visibilitychange', onVisibilityChange);
20247  };
20248  const detachDocumentEvents = () => {
20249    const document = ssr_window_esm_getDocument();
20250    document.removeEventListener('visibilitychange', onVisibilityChange);
20251  };
20252  on('init', () => {
20253    if (swiper.params.autoplay.enabled) {
20254      attachMouseEvents();
20255      attachDocumentEvents();
20256      start();
20257    }
20258  });
20259  on('destroy', () => {
20260    detachMouseEvents();
20261    detachDocumentEvents();
20262    if (swiper.autoplay.running) {
20263      stop();
20264    }
20265  });
20266  on('_freeModeStaticRelease', () => {
20267    if (pausedByTouch || pausedByInteraction) {
20268      resume();
20269    }
20270  });
20271  on('_freeModeNoMomentumRelease', () => {
20272    if (!swiper.params.autoplay.disableOnInteraction) {
20273      pause(true, true);
20274    } else {
20275      stop();
20276    }
20277  });
20278  on('beforeTransitionStart', (_s, speed, internal) => {
20279    if (swiper.destroyed || !swiper.autoplay.running) return;
20280    if (internal || !swiper.params.autoplay.disableOnInteraction) {
20281      pause(true, true);
20282    } else {
20283      stop();
20284    }
20285  });
20286  on('sliderFirstMove', () => {
20287    if (swiper.destroyed || !swiper.autoplay.running) return;
20288    if (swiper.params.autoplay.disableOnInteraction) {
20289      stop();
20290      return;
20291    }
20292    isTouched = true;
20293    pausedByTouch = false;
20294    pausedByInteraction = false;
20295    touchStartTimeout = setTimeout(() => {
20296      pausedByInteraction = true;
20297      pausedByTouch = true;
20298      pause(true);
20299    }, 200);
20300  });
20301  on('touchEnd', () => {
20302    if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
20303    clearTimeout(touchStartTimeout);
20304    clearTimeout(timeout);
20305    if (swiper.params.autoplay.disableOnInteraction) {
20306      pausedByTouch = false;
20307      isTouched = false;
20308      return;
20309    }
20310    if (pausedByTouch && swiper.params.cssMode) resume();
20311    pausedByTouch = false;
20312    isTouched = false;
20313  });
20314  on('slideChange', () => {
20315    if (swiper.destroyed || !swiper.autoplay.running) return;
20316    slideChanged = true;
20317  });
20318  Object.assign(swiper.autoplay, {
20319    start,
20320    stop,
20321    pause,
20322    resume
20323  });
20324}
20325
20326
20327
20328;// ./node_modules/swiper/modules/thumbs.mjs
20329
20330
20331
20332function Thumb(_ref) {
20333  let {
20334    swiper,
20335    extendParams,
20336    on
20337  } = _ref;
20338  extendParams({
20339    thumbs: {
20340      swiper: null,
20341      multipleActiveThumbs: true,
20342      autoScrollOffset: 0,
20343      slideThumbActiveClass: 'swiper-slide-thumb-active',
20344      thumbsContainerClass: 'swiper-thumbs'
20345    }
20346  });
20347  let initialized = false;
20348  let swiperCreated = false;
20349  swiper.thumbs = {
20350    swiper: null
20351  };
20352  function onThumbClick() {
20353    const thumbsSwiper = swiper.thumbs.swiper;
20354    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20355    const clickedIndex = thumbsSwiper.clickedIndex;
20356    const clickedSlide = thumbsSwiper.clickedSlide;
20357    if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
20358    if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
20359    let slideToIndex;
20360    if (thumbsSwiper.params.loop) {
20361      slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
20362    } else {
20363      slideToIndex = clickedIndex;
20364    }
20365    if (swiper.params.loop) {
20366      swiper.slideToLoop(slideToIndex);
20367    } else {
20368      swiper.slideTo(slideToIndex);
20369    }
20370  }
20371  function init() {
20372    const {
20373      thumbs: thumbsParams
20374    } = swiper.params;
20375    if (initialized) return false;
20376    initialized = true;
20377    const SwiperClass = swiper.constructor;
20378    if (thumbsParams.swiper instanceof SwiperClass) {
20379      if (thumbsParams.swiper.destroyed) {
20380        initialized = false;
20381        return false;
20382      }
20383      swiper.thumbs.swiper = thumbsParams.swiper;
20384      Object.assign(swiper.thumbs.swiper.originalParams, {
20385        watchSlidesProgress: true,
20386        slideToClickedSlide: false
20387      });
20388      Object.assign(swiper.thumbs.swiper.params, {
20389        watchSlidesProgress: true,
20390        slideToClickedSlide: false
20391      });
20392      swiper.thumbs.swiper.update();
20393    } else if (isObject(thumbsParams.swiper)) {
20394      const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
20395      Object.assign(thumbsSwiperParams, {
20396        watchSlidesProgress: true,
20397        slideToClickedSlide: false
20398      });
20399      swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
20400      swiperCreated = true;
20401    }
20402    swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
20403    swiper.thumbs.swiper.on('tap', onThumbClick);
20404    return true;
20405  }
20406  function update(initial) {
20407    const thumbsSwiper = swiper.thumbs.swiper;
20408    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20409    const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
20410
20411    // Activate thumbs
20412    let thumbsToActivate = 1;
20413    const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
20414    if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
20415      thumbsToActivate = swiper.params.slidesPerView;
20416    }
20417    if (!swiper.params.thumbs.multipleActiveThumbs) {
20418      thumbsToActivate = 1;
20419    }
20420    thumbsToActivate = Math.floor(thumbsToActivate);
20421    thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
20422    if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
20423      for (let i = 0; i < thumbsToActivate; i += 1) {
20424        elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
20425          slideEl.classList.add(thumbActiveClass);
20426        });
20427      }
20428    } else {
20429      for (let i = 0; i < thumbsToActivate; i += 1) {
20430        if (thumbsSwiper.slides[swiper.realIndex + i]) {
20431          thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
20432        }
20433      }
20434    }
20435    const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
20436    const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
20437    if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
20438      const currentThumbsIndex = thumbsSwiper.activeIndex;
20439      let newThumbsIndex;
20440      let direction;
20441      if (thumbsSwiper.params.loop) {
20442        const newThumbsSlide = thumbsSwiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`);
20443        newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
20444        direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
20445      } else {
20446        newThumbsIndex = swiper.realIndex;
20447        direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
20448      }
20449      if (useOffset) {
20450        newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
20451      }
20452      if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
20453        if (thumbsSwiper.params.centeredSlides) {
20454          if (newThumbsIndex > currentThumbsIndex) {
20455            newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
20456          } else {
20457            newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
20458          }
20459        } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ;
20460        thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
20461      }
20462    }
20463  }
20464  on('beforeInit', () => {
20465    const {
20466      thumbs
20467    } = swiper.params;
20468    if (!thumbs || !thumbs.swiper) return;
20469    if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
20470      const document = getDocument();
20471      const getThumbsElementAndInit = () => {
20472        const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
20473        if (thumbsElement && thumbsElement.swiper) {
20474          thumbs.swiper = thumbsElement.swiper;
20475          init();
20476          update(true);
20477        } else if (thumbsElement) {
20478          const eventName = `${swiper.params.eventsPrefix}init`;
20479          const onThumbsSwiper = e => {
20480            thumbs.swiper = e.detail[0];
20481            thumbsElement.removeEventListener(eventName, onThumbsSwiper);
20482            init();
20483            update(true);
20484            thumbs.swiper.update();
20485            swiper.update();
20486          };
20487          thumbsElement.addEventListener(eventName, onThumbsSwiper);
20488        }
20489        return thumbsElement;
20490      };
20491      const watchForThumbsToAppear = () => {
20492        if (swiper.destroyed) return;
20493        const thumbsElement = getThumbsElementAndInit();
20494        if (!thumbsElement) {
20495          requestAnimationFrame(watchForThumbsToAppear);
20496        }
20497      };
20498      requestAnimationFrame(watchForThumbsToAppear);
20499    } else {
20500      init();
20501      update(true);
20502    }
20503  });
20504  on('slideChange update resize observerUpdate', () => {
20505    update();
20506  });
20507  on('setTransition', (_s, duration) => {
20508    const thumbsSwiper = swiper.thumbs.swiper;
20509    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20510    thumbsSwiper.setTransition(duration);
20511  });
20512  on('beforeDestroy', () => {
20513    const thumbsSwiper = swiper.thumbs.swiper;
20514    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20515    if (swiperCreated) {
20516      thumbsSwiper.destroy();
20517    }
20518  });
20519  Object.assign(swiper.thumbs, {
20520    init,
20521    update
20522  });
20523}
20524
20525
20526
20527;// ./node_modules/swiper/modules/free-mode.mjs
20528
20529
20530function freeMode(_ref) {
20531  let {
20532    swiper,
20533    extendParams,
20534    emit,
20535    once
20536  } = _ref;
20537  extendParams({
20538    freeMode: {
20539      enabled: false,
20540      momentum: true,
20541      momentumRatio: 1,
20542      momentumBounce: true,
20543      momentumBounceRatio: 1,
20544      momentumVelocityRatio: 1,
20545      sticky: false,
20546      minimumVelocity: 0.02
20547    }
20548  });
20549  function onTouchStart() {
20550    if (swiper.params.cssMode) return;
20551    const translate = swiper.getTranslate();
20552    swiper.setTranslate(translate);
20553    swiper.setTransition(0);
20554    swiper.touchEventsData.velocities.length = 0;
20555    swiper.freeMode.onTouchEnd({
20556      currentPos: swiper.rtl ? swiper.translate : -swiper.translate
20557    });
20558  }
20559  function onTouchMove() {
20560    if (swiper.params.cssMode) return;
20561    const {
20562      touchEventsData: data,
20563      touches
20564    } = swiper;
20565    // Velocity
20566    if (data.velocities.length === 0) {
20567      data.velocities.push({
20568        position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
20569        time: data.touchStartTime
20570      });
20571    }
20572    data.velocities.push({
20573      position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
20574      time: now()
20575    });
20576  }
20577  function onTouchEnd(_ref2) {
20578    let {
20579      currentPos
20580    } = _ref2;
20581    if (swiper.params.cssMode) return;
20582    const {
20583      params,
20584      wrapperEl,
20585      rtlTranslate: rtl,
20586      snapGrid,
20587      touchEventsData: data
20588    } = swiper;
20589    // Time diff
20590    const touchEndTime = now();
20591    const timeDiff = touchEndTime - data.touchStartTime;
20592    if (currentPos < -swiper.minTranslate()) {
20593      swiper.slideTo(swiper.activeIndex);
20594      return;
20595    }
20596    if (currentPos > -swiper.maxTranslate()) {
20597      if (swiper.slides.length < snapGrid.length) {
20598        swiper.slideTo(snapGrid.length - 1);
20599      } else {
20600        swiper.slideTo(swiper.slides.length - 1);
20601      }
20602      return;
20603    }
20604    if (params.freeMode.momentum) {
20605      if (data.velocities.length > 1) {
20606        const lastMoveEvent = data.velocities.pop();
20607        const velocityEvent = data.velocities.pop();
20608        const distance = lastMoveEvent.position - velocityEvent.position;
20609        const time = lastMoveEvent.time - velocityEvent.time;
20610        swiper.velocity = distance / time;
20611        swiper.velocity /= 2;
20612        if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
20613          swiper.velocity = 0;
20614        }
20615        // this implies that the user stopped moving a finger then released.
20616        // There would be no events with distance zero, so the last event is stale.
20617        if (time > 150 || now() - lastMoveEvent.time > 300) {
20618          swiper.velocity = 0;
20619        }
20620      } else {
20621        swiper.velocity = 0;
20622      }
20623      swiper.velocity *= params.freeMode.momentumVelocityRatio;
20624      data.velocities.length = 0;
20625      let momentumDuration = 1000 * params.freeMode.momentumRatio;
20626      const momentumDistance = swiper.velocity * momentumDuration;
20627      let newPosition = swiper.translate + momentumDistance;
20628      if (rtl) newPosition = -newPosition;
20629      let doBounce = false;
20630      let afterBouncePosition;
20631      const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
20632      let needsLoopFix;
20633      if (newPosition < swiper.maxTranslate()) {
20634        if (params.freeMode.momentumBounce) {
20635          if (newPosition + swiper.maxTranslate() < -bounceAmount) {
20636            newPosition = swiper.maxTranslate() - bounceAmount;
20637          }
20638          afterBouncePosition = swiper.maxTranslate();
20639          doBounce = true;
20640          data.allowMomentumBounce = true;
20641        } else {
20642          newPosition = swiper.maxTranslate();
20643        }
20644        if (params.loop && params.centeredSlides) needsLoopFix = true;
20645      } else if (newPosition > swiper.minTranslate()) {
20646        if (params.freeMode.momentumBounce) {
20647          if (newPosition - swiper.minTranslate() > bounceAmount) {
20648            newPosition = swiper.minTranslate() + bounceAmount;
20649          }
20650          afterBouncePosition = swiper.minTranslate();
20651          doBounce = true;
20652          data.allowMomentumBounce = true;
20653        } else {
20654          newPosition = swiper.minTranslate();
20655        }
20656        if (params.loop && params.centeredSlides) needsLoopFix = true;
20657      } else if (params.freeMode.sticky) {
20658        let nextSlide;
20659        for (let j = 0; j < snapGrid.length; j += 1) {
20660          if (snapGrid[j] > -newPosition) {
20661            nextSlide = j;
20662            break;
20663          }
20664        }
20665        if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
20666          newPosition = snapGrid[nextSlide];
20667        } else {
20668          newPosition = snapGrid[nextSlide - 1];
20669        }
20670        newPosition = -newPosition;
20671      }
20672      if (needsLoopFix) {
20673        once('transitionEnd', () => {
20674          swiper.loopFix();
20675        });
20676      }
20677      // Fix duration
20678      if (swiper.velocity !== 0) {
20679        if (rtl) {
20680          momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
20681        } else {
20682          momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
20683        }
20684        if (params.freeMode.sticky) {
20685          // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
20686          // event, then durations can be 20+ seconds to slide one (or zero!) slides.
20687          // It's easy to see this when simulating touch with mouse events. To fix this,
20688          // limit single-slide swipes to the default slide duration. This also has the
20689          // nice side effect of matching slide speed if the user stopped moving before
20690          // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
20691          // For faster swipes, also apply limits (albeit higher ones).
20692          const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
20693          const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
20694          if (moveDistance < currentSlideSize) {
20695            momentumDuration = params.speed;
20696          } else if (moveDistance < 2 * currentSlideSize) {
20697            momentumDuration = params.speed * 1.5;
20698          } else {
20699            momentumDuration = params.speed * 2.5;
20700          }
20701        }
20702      } else if (params.freeMode.sticky) {
20703        swiper.slideToClosest();
20704        return;
20705      }
20706      if (params.freeMode.momentumBounce && doBounce) {
20707        swiper.updateProgress(afterBouncePosition);
20708        swiper.setTransition(momentumDuration);
20709        swiper.setTranslate(newPosition);
20710        swiper.transitionStart(true, swiper.swipeDirection);
20711        swiper.animating = true;
20712        elementTransitionEnd(wrapperEl, () => {
20713          if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
20714          emit('momentumBounce');
20715          swiper.setTransition(params.speed);
20716          setTimeout(() => {
20717            swiper.setTranslate(afterBouncePosition);
20718            elementTransitionEnd(wrapperEl, () => {
20719              if (!swiper || swiper.destroyed) return;
20720              swiper.transitionEnd();
20721            });
20722          }, 0);
20723        });
20724      } else if (swiper.velocity) {
20725        emit('_freeModeNoMomentumRelease');
20726        swiper.updateProgress(newPosition);
20727        swiper.setTransition(momentumDuration);
20728        swiper.setTranslate(newPosition);
20729        swiper.transitionStart(true, swiper.swipeDirection);
20730        if (!swiper.animating) {
20731          swiper.animating = true;
20732          elementTransitionEnd(wrapperEl, () => {
20733            if (!swiper || swiper.destroyed) return;
20734            swiper.transitionEnd();
20735          });
20736        }
20737      } else {
20738        swiper.updateProgress(newPosition);
20739      }
20740      swiper.updateActiveIndex();
20741      swiper.updateSlidesClasses();
20742    } else if (params.freeMode.sticky) {
20743      swiper.slideToClosest();
20744      return;
20745    } else if (params.freeMode) {
20746      emit('_freeModeNoMomentumRelease');
20747    }
20748    if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
20749      emit('_freeModeStaticRelease');
20750      swiper.updateProgress();
20751      swiper.updateActiveIndex();
20752      swiper.updateSlidesClasses();
20753    }
20754  }
20755  Object.assign(swiper, {
20756    freeMode: {
20757      onTouchStart,
20758      onTouchMove,
20759      onTouchEnd
20760    }
20761  });
20762}
20763
20764
20765
20766;// ./node_modules/swiper/modules/manipulation.mjs
20767
20768
20769function appendSlide(slides) {
20770  const swiper = this;
20771  const {
20772    params,
20773    slidesEl
20774  } = swiper;
20775  if (params.loop) {
20776    swiper.loopDestroy();
20777  }
20778  const appendElement = slideEl => {
20779    if (typeof slideEl === 'string') {
20780      const tempDOM = document.createElement('div');
20781      setInnerHTML(tempDOM, slideEl);
20782      slidesEl.append(tempDOM.children[0]);
20783      setInnerHTML(tempDOM, '');
20784    } else {
20785      slidesEl.append(slideEl);
20786    }
20787  };
20788  if (typeof slides === 'object' && 'length' in slides) {
20789    for (let i = 0; i < slides.length; i += 1) {
20790      if (slides[i]) appendElement(slides[i]);
20791    }
20792  } else {
20793    appendElement(slides);
20794  }
20795  swiper.recalcSlides();
20796  if (params.loop) {
20797    swiper.loopCreate();
20798  }
20799  if (!params.observer || swiper.isElement) {
20800    swiper.update();
20801  }
20802}
20803
20804function prependSlide(slides) {
20805  const swiper = this;
20806  const {
20807    params,
20808    activeIndex,
20809    slidesEl
20810  } = swiper;
20811  if (params.loop) {
20812    swiper.loopDestroy();
20813  }
20814  let newActiveIndex = activeIndex + 1;
20815  const prependElement = slideEl => {
20816    if (typeof slideEl === 'string') {
20817      const tempDOM = document.createElement('div');
20818      setInnerHTML(tempDOM, slideEl);
20819      slidesEl.prepend(tempDOM.children[0]);
20820      setInnerHTML(tempDOM, '');
20821    } else {
20822      slidesEl.prepend(slideEl);
20823    }
20824  };
20825  if (typeof slides === 'object' && 'length' in slides) {
20826    for (let i = 0; i < slides.length; i += 1) {
20827      if (slides[i]) prependElement(slides[i]);
20828    }
20829    newActiveIndex = activeIndex + slides.length;
20830  } else {
20831    prependElement(slides);
20832  }
20833  swiper.recalcSlides();
20834  if (params.loop) {
20835    swiper.loopCreate();
20836  }
20837  if (!params.observer || swiper.isElement) {
20838    swiper.update();
20839  }
20840  swiper.slideTo(newActiveIndex, 0, false);
20841}
20842
20843function addSlide(index, slides) {
20844  const swiper = this;
20845  const {
20846    params,
20847    activeIndex,
20848    slidesEl
20849  } = swiper;
20850  let activeIndexBuffer = activeIndex;
20851  if (params.loop) {
20852    activeIndexBuffer -= swiper.loopedSlides;
20853    swiper.loopDestroy();
20854    swiper.recalcSlides();
20855  }
20856  const baseLength = swiper.slides.length;
20857  if (index <= 0) {
20858    swiper.prependSlide(slides);
20859    return;
20860  }
20861  if (index >= baseLength) {
20862    swiper.appendSlide(slides);
20863    return;
20864  }
20865  let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
20866  const slidesBuffer = [];
20867  for (let i = baseLength - 1; i >= index; i -= 1) {
20868    const currentSlide = swiper.slides[i];
20869    currentSlide.remove();
20870    slidesBuffer.unshift(currentSlide);
20871  }
20872  if (typeof slides === 'object' && 'length' in slides) {
20873    for (let i = 0; i < slides.length; i += 1) {
20874      if (slides[i]) slidesEl.append(slides[i]);
20875    }
20876    newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
20877  } else {
20878    slidesEl.append(slides);
20879  }
20880  for (let i = 0; i < slidesBuffer.length; i += 1) {
20881    slidesEl.append(slidesBuffer[i]);
20882  }
20883  swiper.recalcSlides();
20884  if (params.loop) {
20885    swiper.loopCreate();
20886  }
20887  if (!params.observer || swiper.isElement) {
20888    swiper.update();
20889  }
20890  if (params.loop) {
20891    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
20892  } else {
20893    swiper.slideTo(newActiveIndex, 0, false);
20894  }
20895}
20896
20897function removeSlide(slidesIndexes) {
20898  const swiper = this;
20899  const {
20900    params,
20901    activeIndex
20902  } = swiper;
20903  let activeIndexBuffer = activeIndex;
20904  if (params.loop) {
20905    activeIndexBuffer -= swiper.loopedSlides;
20906    swiper.loopDestroy();
20907  }
20908  let newActiveIndex = activeIndexBuffer;
20909  let indexToRemove;
20910  if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
20911    for (let i = 0; i < slidesIndexes.length; i += 1) {
20912      indexToRemove = slidesIndexes[i];
20913      if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
20914      if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
20915    }
20916    newActiveIndex = Math.max(newActiveIndex, 0);
20917  } else {
20918    indexToRemove = slidesIndexes;
20919    if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
20920    if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
20921    newActiveIndex = Math.max(newActiveIndex, 0);
20922  }
20923  swiper.recalcSlides();
20924  if (params.loop) {
20925    swiper.loopCreate();
20926  }
20927  if (!params.observer || swiper.isElement) {
20928    swiper.update();
20929  }
20930  if (params.loop) {
20931    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
20932  } else {
20933    swiper.slideTo(newActiveIndex, 0, false);
20934  }
20935}
20936
20937function removeAllSlides() {
20938  const swiper = this;
20939  const slidesIndexes = [];
20940  for (let i = 0; i < swiper.slides.length; i += 1) {
20941    slidesIndexes.push(i);
20942  }
20943  swiper.removeSlide(slidesIndexes);
20944}
20945
20946function Manipulation(_ref) {
20947  let {
20948    swiper
20949  } = _ref;
20950  Object.assign(swiper, {
20951    appendSlide: appendSlide.bind(swiper),
20952    prependSlide: prependSlide.bind(swiper),
20953    addSlide: addSlide.bind(swiper),
20954    removeSlide: removeSlide.bind(swiper),
20955    removeAllSlides: removeAllSlides.bind(swiper)
20956  });
20957}
20958
20959
20960
20961;// ./node_modules/swiper/shared/effect-target.mjs
20962
20963
20964function effect_target_effectTarget(effectParams, slideEl) {
20965  const transformEl = getSlideTransformEl(slideEl);
20966  if (transformEl !== slideEl) {
20967    transformEl.style.backfaceVisibility = 'hidden';
20968    transformEl.style['-webkit-backface-visibility'] = 'hidden';
20969  }
20970  return transformEl;
20971}
20972
20973
20974
20975;// ./node_modules/swiper/shared/effect-virtual-transition-end.mjs
20976
20977
20978function effect_virtual_transition_end_effectVirtualTransitionEnd(_ref) {
20979  let {
20980    swiper,
20981    duration,
20982    transformElements,
20983    allSlides
20984  } = _ref;
20985  const {
20986    activeIndex
20987  } = swiper;
20988  const getSlide = el => {
20989    if (!el.parentElement) {
20990      // assume shadow root
20991      const slide = swiper.slides.find(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode);
20992      return slide;
20993    }
20994    return el.parentElement;
20995  };
20996  if (swiper.params.virtualTranslate && duration !== 0) {
20997    let eventTriggered = false;
20998    let transitionEndTarget;
20999    if (allSlides) {
21000      transitionEndTarget = transformElements;
21001    } else {
21002      transitionEndTarget = transformElements.filter(transformEl => {
21003        const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
21004        return swiper.getSlideIndex(el) === activeIndex;
21005      });
21006    }
21007    transitionEndTarget.forEach(el => {
21008      elementTransitionEnd(el, () => {
21009        if (eventTriggered) return;
21010        if (!swiper || swiper.destroyed) return;
21011        eventTriggered = true;
21012        swiper.animating = false;
21013        const evt = new window.CustomEvent('transitionend', {
21014          bubbles: true,
21015          cancelable: true
21016        });
21017        swiper.wrapperEl.dispatchEvent(evt);
21018      });
21019    });
21020  }
21021}
21022
21023
21024
21025;// ./node_modules/swiper/modules/effect-fade.mjs
21026
21027
21028
21029
21030
21031function EffectFade(_ref) {
21032  let {
21033    swiper,
21034    extendParams,
21035    on
21036  } = _ref;
21037  extendParams({
21038    fadeEffect: {
21039      crossFade: false
21040    }
21041  });
21042  const setTranslate = () => {
21043    const {
21044      slides
21045    } = swiper;
21046    const params = swiper.params.fadeEffect;
21047    for (let i = 0; i < slides.length; i += 1) {
21048      const slideEl = swiper.slides[i];
21049      const offset = slideEl.swiperSlideOffset;
21050      let tx = -offset;
21051      if (!swiper.params.virtualTranslate) tx -= swiper.translate;
21052      let ty = 0;
21053      if (!swiper.isHorizontal()) {
21054        ty = tx;
21055        tx = 0;
21056      }
21057      const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
21058      const targetEl = effectTarget(params, slideEl);
21059      targetEl.style.opacity = slideOpacity;
21060      targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
21061    }
21062  };
21063  const setTransition = duration => {
21064    const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21065    transformElements.forEach(el => {
21066      el.style.transitionDuration = `${duration}ms`;
21067    });
21068    effectVirtualTransitionEnd({
21069      swiper,
21070      duration,
21071      transformElements,
21072      allSlides: true
21073    });
21074  };
21075  effectInit({
21076    effect: 'fade',
21077    swiper,
21078    on,
21079    setTranslate,
21080    setTransition,
21081    overwriteParams: () => ({
21082      slidesPerView: 1,
21083      slidesPerGroup: 1,
21084      watchSlidesProgress: true,
21085      spaceBetween: 0,
21086      virtualTranslate: !swiper.params.cssMode
21087    })
21088  });
21089}
21090
21091
21092
21093;// ./node_modules/swiper/modules/effect-cube.mjs
21094
21095
21096
21097function EffectCube(_ref) {
21098  let {
21099    swiper,
21100    extendParams,
21101    on
21102  } = _ref;
21103  extendParams({
21104    cubeEffect: {
21105      slideShadows: true,
21106      shadow: true,
21107      shadowOffset: 20,
21108      shadowScale: 0.94
21109    }
21110  });
21111  const createSlideShadows = (slideEl, progress, isHorizontal) => {
21112    let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21113    let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21114    if (!shadowBefore) {
21115      shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' '));
21116      slideEl.append(shadowBefore);
21117    }
21118    if (!shadowAfter) {
21119      shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' '));
21120      slideEl.append(shadowAfter);
21121    }
21122    if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
21123    if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
21124  };
21125  const recreateShadows = () => {
21126    // create new ones
21127    const isHorizontal = swiper.isHorizontal();
21128    swiper.slides.forEach(slideEl => {
21129      const progress = Math.max(Math.min(slideEl.progress, 1), -1);
21130      createSlideShadows(slideEl, progress, isHorizontal);
21131    });
21132  };
21133  const setTranslate = () => {
21134    const {
21135      el,
21136      wrapperEl,
21137      slides,
21138      width: swiperWidth,
21139      height: swiperHeight,
21140      rtlTranslate: rtl,
21141      size: swiperSize,
21142      browser
21143    } = swiper;
21144    const r = getRotateFix(swiper);
21145    const params = swiper.params.cubeEffect;
21146    const isHorizontal = swiper.isHorizontal();
21147    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
21148    let wrapperRotate = 0;
21149    let cubeShadowEl;
21150    if (params.shadow) {
21151      if (isHorizontal) {
21152        cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow');
21153        if (!cubeShadowEl) {
21154          cubeShadowEl = createElement('div', 'swiper-cube-shadow');
21155          swiper.wrapperEl.append(cubeShadowEl);
21156        }
21157        cubeShadowEl.style.height = `${swiperWidth}px`;
21158      } else {
21159        cubeShadowEl = el.querySelector('.swiper-cube-shadow');
21160        if (!cubeShadowEl) {
21161          cubeShadowEl = createElement('div', 'swiper-cube-shadow');
21162          el.append(cubeShadowEl);
21163        }
21164      }
21165    }
21166    for (let i = 0; i < slides.length; i += 1) {
21167      const slideEl = slides[i];
21168      let slideIndex = i;
21169      if (isVirtual) {
21170        slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
21171      }
21172      let slideAngle = slideIndex * 90;
21173      let round = Math.floor(slideAngle / 360);
21174      if (rtl) {
21175        slideAngle = -slideAngle;
21176        round = Math.floor(-slideAngle / 360);
21177      }
21178      const progress = Math.max(Math.min(slideEl.progress, 1), -1);
21179      let tx = 0;
21180      let ty = 0;
21181      let tz = 0;
21182      if (slideIndex % 4 === 0) {
21183        tx = -round * 4 * swiperSize;
21184        tz = 0;
21185      } else if ((slideIndex - 1) % 4 === 0) {
21186        tx = 0;
21187        tz = -round * 4 * swiperSize;
21188      } else if ((slideIndex - 2) % 4 === 0) {
21189        tx = swiperSize + round * 4 * swiperSize;
21190        tz = swiperSize;
21191      } else if ((slideIndex - 3) % 4 === 0) {
21192        tx = -swiperSize;
21193        tz = 3 * swiperSize + swiperSize * 4 * round;
21194      }
21195      if (rtl) {
21196        tx = -tx;
21197      }
21198      if (!isHorizontal) {
21199        ty = tx;
21200        tx = 0;
21201      }
21202      const transform = `rotateX(${r(isHorizontal ? 0 : -slideAngle)}deg) rotateY(${r(isHorizontal ? slideAngle : 0)}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
21203      if (progress <= 1 && progress > -1) {
21204        wrapperRotate = slideIndex * 90 + progress * 90;
21205        if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
21206      }
21207      slideEl.style.transform = transform;
21208      if (params.slideShadows) {
21209        createSlideShadows(slideEl, progress, isHorizontal);
21210      }
21211    }
21212    wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
21213    wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
21214    if (params.shadow) {
21215      if (isHorizontal) {
21216        cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(89.99deg) rotateZ(0deg) scale(${params.shadowScale})`;
21217      } else {
21218        const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
21219        const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
21220        const scale1 = params.shadowScale;
21221        const scale2 = params.shadowScale / multiplier;
21222        const offset = params.shadowOffset;
21223        cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-89.99deg)`;
21224      }
21225    }
21226    const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
21227    wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${r(swiper.isHorizontal() ? 0 : wrapperRotate)}deg) rotateY(${r(swiper.isHorizontal() ? -wrapperRotate : 0)}deg)`;
21228    wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
21229  };
21230  const setTransition = duration => {
21231    const {
21232      el,
21233      slides
21234    } = swiper;
21235    slides.forEach(slideEl => {
21236      slideEl.style.transitionDuration = `${duration}ms`;
21237      slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => {
21238        subEl.style.transitionDuration = `${duration}ms`;
21239      });
21240    });
21241    if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
21242      const shadowEl = el.querySelector('.swiper-cube-shadow');
21243      if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
21244    }
21245  };
21246  effectInit({
21247    effect: 'cube',
21248    swiper,
21249    on,
21250    setTranslate,
21251    setTransition,
21252    recreateShadows,
21253    getEffectParams: () => swiper.params.cubeEffect,
21254    perspective: () => true,
21255    overwriteParams: () => ({
21256      slidesPerView: 1,
21257      slidesPerGroup: 1,
21258      watchSlidesProgress: true,
21259      resistanceRatio: 0,
21260      spaceBetween: 0,
21261      centeredSlides: false,
21262      virtualTranslate: true
21263    })
21264  });
21265}
21266
21267
21268
21269;// ./node_modules/swiper/shared/create-shadow.mjs
21270
21271
21272function create_shadow_createShadow(suffix, slideEl, side) {
21273  const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`;
21274  const shadowContainer = getSlideTransformEl(slideEl);
21275  let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`);
21276  if (!shadowEl) {
21277    shadowEl = createElement('div', shadowClass.split(' '));
21278    shadowContainer.append(shadowEl);
21279  }
21280  return shadowEl;
21281}
21282
21283
21284
21285;// ./node_modules/swiper/modules/effect-flip.mjs
21286
21287
21288
21289
21290
21291
21292function EffectFlip(_ref) {
21293  let {
21294    swiper,
21295    extendParams,
21296    on
21297  } = _ref;
21298  extendParams({
21299    flipEffect: {
21300      slideShadows: true,
21301      limitRotation: true
21302    }
21303  });
21304  const createSlideShadows = (slideEl, progress) => {
21305    let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21306    let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21307    if (!shadowBefore) {
21308      shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top');
21309    }
21310    if (!shadowAfter) {
21311      shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
21312    }
21313    if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
21314    if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
21315  };
21316  const recreateShadows = () => {
21317    // Set shadows
21318    swiper.params.flipEffect;
21319    swiper.slides.forEach(slideEl => {
21320      let progress = slideEl.progress;
21321      if (swiper.params.flipEffect.limitRotation) {
21322        progress = Math.max(Math.min(slideEl.progress, 1), -1);
21323      }
21324      createSlideShadows(slideEl, progress);
21325    });
21326  };
21327  const setTranslate = () => {
21328    const {
21329      slides,
21330      rtlTranslate: rtl
21331    } = swiper;
21332    const params = swiper.params.flipEffect;
21333    const rotateFix = getRotateFix(swiper);
21334    for (let i = 0; i < slides.length; i += 1) {
21335      const slideEl = slides[i];
21336      let progress = slideEl.progress;
21337      if (swiper.params.flipEffect.limitRotation) {
21338        progress = Math.max(Math.min(slideEl.progress, 1), -1);
21339      }
21340      const offset = slideEl.swiperSlideOffset;
21341      const rotate = -180 * progress;
21342      let rotateY = rotate;
21343      let rotateX = 0;
21344      let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
21345      let ty = 0;
21346      if (!swiper.isHorizontal()) {
21347        ty = tx;
21348        tx = 0;
21349        rotateX = -rotateY;
21350        rotateY = 0;
21351      } else if (rtl) {
21352        rotateY = -rotateY;
21353      }
21354      slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
21355      if (params.slideShadows) {
21356        createSlideShadows(slideEl, progress);
21357      }
21358      const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateFix(rotateX)}deg) rotateY(${rotateFix(rotateY)}deg)`;
21359      const targetEl = effectTarget(params, slideEl);
21360      targetEl.style.transform = transform;
21361    }
21362  };
21363  const setTransition = duration => {
21364    const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21365    transformElements.forEach(el => {
21366      el.style.transitionDuration = `${duration}ms`;
21367      el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
21368        shadowEl.style.transitionDuration = `${duration}ms`;
21369      });
21370    });
21371    effectVirtualTransitionEnd({
21372      swiper,
21373      duration,
21374      transformElements
21375    });
21376  };
21377  effectInit({
21378    effect: 'flip',
21379    swiper,
21380    on,
21381    setTranslate,
21382    setTransition,
21383    recreateShadows,
21384    getEffectParams: () => swiper.params.flipEffect,
21385    perspective: () => true,
21386    overwriteParams: () => ({
21387      slidesPerView: 1,
21388      slidesPerGroup: 1,
21389      watchSlidesProgress: true,
21390      spaceBetween: 0,
21391      virtualTranslate: !swiper.params.cssMode
21392    })
21393  });
21394}
21395
21396
21397
21398;// ./node_modules/swiper/modules/effect-coverflow.mjs
21399
21400
21401
21402
21403
21404function EffectCoverflow(_ref) {
21405  let {
21406    swiper,
21407    extendParams,
21408    on
21409  } = _ref;
21410  extendParams({
21411    coverflowEffect: {
21412      rotate: 50,
21413      stretch: 0,
21414      depth: 100,
21415      scale: 1,
21416      modifier: 1,
21417      slideShadows: true
21418    }
21419  });
21420  const setTranslate = () => {
21421    const {
21422      width: swiperWidth,
21423      height: swiperHeight,
21424      slides,
21425      slidesSizesGrid
21426    } = swiper;
21427    const params = swiper.params.coverflowEffect;
21428    const isHorizontal = swiper.isHorizontal();
21429    const transform = swiper.translate;
21430    const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
21431    const rotate = isHorizontal ? params.rotate : -params.rotate;
21432    const translate = params.depth;
21433    const r = getRotateFix(swiper);
21434    // Each slide offset from center
21435    for (let i = 0, length = slides.length; i < length; i += 1) {
21436      const slideEl = slides[i];
21437      const slideSize = slidesSizesGrid[i];
21438      const slideOffset = slideEl.swiperSlideOffset;
21439      const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
21440      const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
21441      let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
21442      let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
21443      // var rotateZ = 0
21444      let translateZ = -translate * Math.abs(offsetMultiplier);
21445      let stretch = params.stretch;
21446      // Allow percentage to make a relative stretch for responsive sliders
21447      if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
21448        stretch = parseFloat(params.stretch) / 100 * slideSize;
21449      }
21450      let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
21451      let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
21452      let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
21453
21454      // Fix for ultra small values
21455      if (Math.abs(translateX) < 0.001) translateX = 0;
21456      if (Math.abs(translateY) < 0.001) translateY = 0;
21457      if (Math.abs(translateZ) < 0.001) translateZ = 0;
21458      if (Math.abs(rotateY) < 0.001) rotateY = 0;
21459      if (Math.abs(rotateX) < 0.001) rotateX = 0;
21460      if (Math.abs(scale) < 0.001) scale = 0;
21461      const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px)  rotateX(${r(rotateX)}deg) rotateY(${r(rotateY)}deg) scale(${scale})`;
21462      const targetEl = effectTarget(params, slideEl);
21463      targetEl.style.transform = slideTransform;
21464      slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
21465      if (params.slideShadows) {
21466        // Set shadows
21467        let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21468        let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21469        if (!shadowBeforeEl) {
21470          shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top');
21471        }
21472        if (!shadowAfterEl) {
21473          shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom');
21474        }
21475        if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
21476        if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
21477      }
21478    }
21479  };
21480  const setTransition = duration => {
21481    const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21482    transformElements.forEach(el => {
21483      el.style.transitionDuration = `${duration}ms`;
21484      el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
21485        shadowEl.style.transitionDuration = `${duration}ms`;
21486      });
21487    });
21488  };
21489  effectInit({
21490    effect: 'coverflow',
21491    swiper,
21492    on,
21493    setTranslate,
21494    setTransition,
21495    perspective: () => true,
21496    overwriteParams: () => ({
21497      watchSlidesProgress: true
21498    })
21499  });
21500}
21501
21502
21503
21504;// ./node_modules/swiper/modules/effect-creative.mjs
21505
21506
21507
21508
21509
21510
21511function EffectCreative(_ref) {
21512  let {
21513    swiper,
21514    extendParams,
21515    on
21516  } = _ref;
21517  extendParams({
21518    creativeEffect: {
21519      limitProgress: 1,
21520      shadowPerProgress: false,
21521      progressMultiplier: 1,
21522      perspective: true,
21523      prev: {
21524        translate: [0, 0, 0],
21525        rotate: [0, 0, 0],
21526        opacity: 1,
21527        scale: 1
21528      },
21529      next: {
21530        translate: [0, 0, 0],
21531        rotate: [0, 0, 0],
21532        opacity: 1,
21533        scale: 1
21534      }
21535    }
21536  });
21537  const getTranslateValue = value => {
21538    if (typeof value === 'string') return value;
21539    return `${value}px`;
21540  };
21541  const setTranslate = () => {
21542    const {
21543      slides,
21544      wrapperEl,
21545      slidesSizesGrid
21546    } = swiper;
21547    const params = swiper.params.creativeEffect;
21548    const {
21549      progressMultiplier: multiplier
21550    } = params;
21551    const isCenteredSlides = swiper.params.centeredSlides;
21552    const rotateFix = getRotateFix(swiper);
21553    if (isCenteredSlides) {
21554      const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
21555      wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
21556    }
21557    for (let i = 0; i < slides.length; i += 1) {
21558      const slideEl = slides[i];
21559      const slideProgress = slideEl.progress;
21560      const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
21561      let originalProgress = progress;
21562      if (!isCenteredSlides) {
21563        originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
21564      }
21565      const offset = slideEl.swiperSlideOffset;
21566      const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
21567      const r = [0, 0, 0];
21568      let custom = false;
21569      if (!swiper.isHorizontal()) {
21570        t[1] = t[0];
21571        t[0] = 0;
21572      }
21573      let data = {
21574        translate: [0, 0, 0],
21575        rotate: [0, 0, 0],
21576        scale: 1,
21577        opacity: 1
21578      };
21579      if (progress < 0) {
21580        data = params.next;
21581        custom = true;
21582      } else if (progress > 0) {
21583        data = params.prev;
21584        custom = true;
21585      }
21586      // set translate
21587      t.forEach((value, index) => {
21588        t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
21589      });
21590      // set rotates
21591      r.forEach((value, index) => {
21592        let val = data.rotate[index] * Math.abs(progress * multiplier);
21593        r[index] = val;
21594      });
21595      slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
21596      const translateString = t.join(', ');
21597      const rotateString = `rotateX(${rotateFix(r[0])}deg) rotateY(${rotateFix(r[1])}deg) rotateZ(${rotateFix(r[2])}deg)`;
21598      const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
21599      const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
21600      const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
21601
21602      // Set shadows
21603      if (custom && data.shadow || !custom) {
21604        let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
21605        if (!shadowEl && data.shadow) {
21606          shadowEl = createShadow('creative', slideEl);
21607        }
21608        if (shadowEl) {
21609          const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
21610          shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
21611        }
21612      }
21613      const targetEl = effectTarget(params, slideEl);
21614      targetEl.style.transform = transform;
21615      targetEl.style.opacity = opacityString;
21616      if (data.origin) {
21617        targetEl.style.transformOrigin = data.origin;
21618      }
21619    }
21620  };
21621  const setTransition = duration => {
21622    const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21623    transformElements.forEach(el => {
21624      el.style.transitionDuration = `${duration}ms`;
21625      el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
21626        shadowEl.style.transitionDuration = `${duration}ms`;
21627      });
21628    });
21629    effectVirtualTransitionEnd({
21630      swiper,
21631      duration,
21632      transformElements,
21633      allSlides: true
21634    });
21635  };
21636  effectInit({
21637    effect: 'creative',
21638    swiper,
21639    on,
21640    setTranslate,
21641    setTransition,
21642    perspective: () => swiper.params.creativeEffect.perspective,
21643    overwriteParams: () => ({
21644      watchSlidesProgress: true,
21645      virtualTranslate: !swiper.params.cssMode
21646    })
21647  });
21648}
21649
21650
21651
21652;// ./node_modules/swiper/modules/effect-cards.mjs
21653
21654
21655
21656
21657
21658
21659function EffectCards(_ref) {
21660  let {
21661    swiper,
21662    extendParams,
21663    on
21664  } = _ref;
21665  extendParams({
21666    cardsEffect: {
21667      slideShadows: true,
21668      rotate: true,
21669      perSlideRotate: 2,
21670      perSlideOffset: 8
21671    }
21672  });
21673  const setTranslate = () => {
21674    const {
21675      slides,
21676      activeIndex,
21677      rtlTranslate: rtl
21678    } = swiper;
21679    const params = swiper.params.cardsEffect;
21680    const {
21681      startTranslate,
21682      isTouched
21683    } = swiper.touchEventsData;
21684    const currentTranslate = rtl ? -swiper.translate : swiper.translate;
21685    for (let i = 0; i < slides.length; i += 1) {
21686      const slideEl = slides[i];
21687      const slideProgress = slideEl.progress;
21688      const progress = Math.min(Math.max(slideProgress, -4), 4);
21689      let offset = slideEl.swiperSlideOffset;
21690      if (swiper.params.centeredSlides && !swiper.params.cssMode) {
21691        swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
21692      }
21693      if (swiper.params.centeredSlides && swiper.params.cssMode) {
21694        offset -= slides[0].swiperSlideOffset;
21695      }
21696      let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
21697      let tY = 0;
21698      const tZ = -100 * Math.abs(progress);
21699      let scale = 1;
21700      let rotate = -params.perSlideRotate * progress;
21701      let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
21702      const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
21703      const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;
21704      const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;
21705      if (isSwipeToNext || isSwipeToPrev) {
21706        const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
21707        rotate += -28 * progress * subProgress;
21708        scale += -0.5 * subProgress;
21709        tXAdd += 96 * subProgress;
21710        tY = `${-25 * subProgress * Math.abs(progress)}%`;
21711      }
21712      if (progress < 0) {
21713        // next
21714        tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
21715      } else if (progress > 0) {
21716        // prev
21717        tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
21718      } else {
21719        tX = `${tX}px`;
21720      }
21721      if (!swiper.isHorizontal()) {
21722        const prevY = tY;
21723        tY = tX;
21724        tX = prevY;
21725      }
21726      const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
21727
21728      /* eslint-disable */
21729      const transform = `
21730        translate3d(${tX}, ${tY}, ${tZ}px)
21731        rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg)
21732        scale(${scaleString})
21733      `;
21734      /* eslint-enable */
21735
21736      if (params.slideShadows) {
21737        // Set shadows
21738        let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
21739        if (!shadowEl) {
21740          shadowEl = createShadow('cards', slideEl);
21741        }
21742        if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
21743      }
21744      slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
21745      const targetEl = effectTarget(params, slideEl);
21746      targetEl.style.transform = transform;
21747    }
21748  };
21749  const setTransition = duration => {
21750    const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21751    transformElements.forEach(el => {
21752      el.style.transitionDuration = `${duration}ms`;
21753      el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
21754        shadowEl.style.transitionDuration = `${duration}ms`;
21755      });
21756    });
21757    effectVirtualTransitionEnd({
21758      swiper,
21759      duration,
21760      transformElements
21761    });
21762  };
21763  effectInit({
21764    effect: 'cards',
21765    swiper,
21766    on,
21767    setTranslate,
21768    setTransition,
21769    perspective: () => true,
21770    overwriteParams: () => ({
21771      _loopSwapReset: false,
21772      watchSlidesProgress: true,
21773      loopAdditionalSlides: swiper.params.cardsEffect.rotate ? 3 : 2,
21774      centeredSlides: true,
21775      virtualTranslate: !swiper.params.cssMode
21776    })
21777  });
21778}
21779
21780
21781
21782;// ./node_modules/swiper/modules/index.mjs
21783
21784
21785
21786
21787
21788
21789
21790
21791
21792
21793
21794
21795
21796
21797
21798
21799
21800
21801
21802
21803
21804
21805
21806;// ./wp-content/themes/sfrtheme/assets/js/slider.js
21807
21808
21809
21810
21811
21812
21813// On parcourt tous les sliders
21814document.addEventListener("DOMContentLoaded", () => {
21815  document.querySelectorAll(".swiper").forEach(swiperElement => {
21816    const id = swiperElement.getAttribute("id");
21817    const spacingAttr = swiperElement.getAttribute("data-spacing");
21818    const spacing = spacingAttr !== null ? parseInt(spacingAttr, 10) : 0;
21819    const mobileSpacingAttr = swiperElement.getAttribute("data-mobile-spacing");
21820    const mobileSpacing = mobileSpacingAttr !== null ? parseInt(mobileSpacingAttr, 10) : 0;
21821    const autoHeight = String(swiperElement.getAttribute("data-auto-height")) === "true";
21822    const autoPlay = String(swiperElement.getAttribute("data-auto-play")) === "true";
21823    const autoPlayDelayAttr = swiperElement.getAttribute("data-auto-play-delay");
21824    const autoPlayDelay = autoPlayDelayAttr !== null ? parseInt(autoPlayDelayAttr, 10) : 3000;
21825
21826    // On peut définir un breakpoint via data-attribute ou par défaut (ex: null pour toujours actif)
21827    const minWidth = swiperElement.getAttribute("data-mobile-no-slide") === "true" ? 1080 : swiperElement.getAttribute("data-min-width");
21828    const maxWidth = swiperElement.getAttribute("data-max-width");
21829    let swiperInstance = null;
21830    let mql = null;
21831    if (minWidth) {
21832      //actif au dessus de la min width
21833      mql = window.matchMedia(`(min-width: ${minWidth}px)`);
21834    } else if (maxWidth) {
21835      //actif en dessous de la max width
21836      mql = window.matchMedia(`(max-width: ${maxWidth}px)`);
21837    }
21838    const initSwiper = () => {
21839      if (swiperInstance) return;
21840      const autoplay = autoPlay ? {
21841        delay: autoPlayDelay,
21842        disableOnInteraction: false
21843      } : false;
21844      swiperInstance = new Swiper(swiperElement, {
21845        autoplay,
21846        slidesPerView: "auto",
21847        watchOverflow: true,
21848        breakpoints: {
21849          // quand la largeur est >= 320px
21850          320: {
21851            spaceBetween: mobileSpacing
21852          },
21853          // quand la largeur est >= 1340px
21854          1340: {
21855            spaceBetween: spacing
21856          }
21857        },
21858        grabCursor: true,
21859        autoHeight,
21860        pagination: {
21861          el: `#swiper-pagination-${id}`,
21862          clickable: true
21863        },
21864        navigation: {
21865          nextEl: `#swiper-button-next-${id}`,
21866          prevEl: `#swiper-button-prev-${id}`
21867        },
21868        scrollbar: {
21869          el: `#swiper-scrollbar-${id}`,
21870          draggable: true
21871        },
21872        modules: [Navigation, Pagination, Autoplay]
21873      });
21874    };
21875    const destroySwiper = () => {
21876      if (swiperInstance) {
21877        swiperInstance.destroy(true, true);
21878        swiperInstance = null;
21879      }
21880    };
21881    const handleMediaChange = e => {
21882      if (e.matches) {
21883        initSwiper();
21884      } else {
21885        destroySwiper();
21886      }
21887    };
21888    if (mql) {
21889      mql.addEventListener("change", handleMediaChange);
21890      if (mql.matches) {
21891        initSwiper();
21892      }
21893    } else {
21894      initSwiper();
21895    }
21896  });
21897});
21898;// ./wp-content/themes/sfrtheme/assets/js/jquery.easy-autocomplete.min.js
21899
21900
21901/*
21902 * easy-autocomplete
21903 * jQuery plugin for autocompletion
21904 *
21905 * @author Łukasz Pawełczak (http://github.com/pawelczak)
21906 * @version 1.3.5
21907 * Copyright  License:
21908 */
21909
21910var EasyAutocomplete = function (a) {
21911    return a.Configuration = function (a) {
21912      function b() {
21913        if ("xml" === a.dataType && (a.getValue || (a.getValue = function (a) {
21914          return $(a).text();
21915        }), a.list || (a.list = {}), a.list.sort || (a.list.sort = {}), a.list.sort.method = function (b, c) {
21916          return b = a.getValue(b), c = a.getValue(c), c > b ? -1 : b > c ? 1 : 0;
21917        }, a.list.match || (a.list.match = {}), a.list.match.method = function (a, b) {
21918          return a.search(b) > -1;
21919        }), void 0 !== a.categories && a.categories instanceof Array) {
21920          for (var b = [], c = 0, d = a.categories.length; d > c; c += 1) {
21921            var e = a.categories[c];
21922            for (var f in h.categories[0]) void 0 === e[f] && (e[f] = h.categories[0][f]);
21923            b.push(e);
21924          }
21925          a.categories = b;
21926        }
21927      }
21928      function c() {
21929        function b(a, c) {
21930          var d = a || {};
21931          for (var e in a) void 0 !== c[e] && null !== c[e] && ("object" != typeof c[e] || c[e] instanceof Array ? d[e] = c[e] : b(a[e], c[e]));
21932          return void 0 !== c.data && null !== c.data && "object" == typeof c.data && (d.data = c.data), d;
21933        }
21934        h = b(h, a);
21935      }
21936      function d() {
21937        if ("list-required" !== h.url && "function" != typeof h.url) {
21938          var b = h.url;
21939          h.url = function () {
21940            return b;
21941          };
21942        }
21943        if (void 0 !== h.ajaxSettings.url && "function" != typeof h.ajaxSettings.url) {
21944          var b = h.ajaxSettings.url;
21945          h.ajaxSettings.url = function () {
21946            return b;
21947          };
21948        }
21949        if ("string" == typeof h.listLocation) {
21950          var c = h.listLocation;
21951          "XML" === h.dataType.toUpperCase() ? h.listLocation = function (a) {
21952            return $(a).find(c);
21953          } : h.listLocation = function (a) {
21954            return a[c];
21955          };
21956        }
21957        if ("string" == typeof h.getValue) {
21958          var d = h.getValue;
21959          h.getValue = function (a) {
21960            return a[d];
21961          };
21962        }
21963        void 0 !== a.categories && (h.categoriesAssigned = !0);
21964      }
21965      function e() {
21966        void 0 !== a.ajaxSettings && "object" == typeof a.ajaxSettings ? h.ajaxSettings = a.ajaxSettings : h.ajaxSettings = {};
21967      }
21968      function f(a) {
21969        return void 0 !== h[a] && null !== h[a];
21970      }
21971      function g(a, b) {
21972        function c(b, d) {
21973          for (var e in d) void 0 === b[e] && a.log("Property '" + e + "' does not exist in EasyAutocomplete options API."), "object" == typeof b[e] && -1 === $.inArray(e, i) && c(b[e], d[e]);
21974        }
21975        c(h, b);
21976      }
21977      var h = {
21978          data: "list-required",
21979          url: "list-required",
21980          dataType: "json",
21981          listLocation: function (a) {
21982            return a;
21983          },
21984          xmlElementName: "",
21985          getValue: function (a) {
21986            return a;
21987          },
21988          autocompleteOff: !0,
21989          placeholder: !1,
21990          ajaxCallback: function () {},
21991          matchResponseProperty: !1,
21992          list: {
21993            sort: {
21994              enabled: !1,
21995              method: function (a, b) {
21996                return a = h.getValue(a), b = h.getValue(b), b > a ? -1 : a > b ? 1 : 0;
21997              }
21998            },
21999            maxNumberOfElements: 6,
22000            hideOnEmptyPhrase: !0,
22001            match: {
22002              enabled: !1,
22003              caseSensitive: !1,
22004              method: function (a, b) {
22005                return a.search(b) > -1;
22006              }
22007            },
22008            showAnimation: {
22009              type: "normal",
22010              time: 400,
22011              callback: function () {}
22012            },
22013            hideAnimation: {
22014              type: "normal",
22015              time: 400,
22016              callback: function () {}
22017            },
22018            onClickEvent: function () {},
22019            onSelectItemEvent: function () {},
22020            onLoadEvent: function () {},
22021            onChooseEvent: function () {},
22022            onKeyEnterEvent: function () {},
22023            onMouseOverEvent: function () {},
22024            onMouseOutEvent: function () {},
22025            onShowListEvent: function () {},
22026            onHideListEvent: function () {}
22027          },
22028          highlightPhrase: !0,
22029          theme: "",
22030          cssClasses: "",
22031          minCharNumber: 0,
22032          requestDelay: 0,
22033          adjustWidth: !0,
22034          ajaxSettings: {},
22035          preparePostData: function (a, b) {
22036            return a;
22037          },
22038          loggerEnabled: !0,
22039          template: "",
22040          categoriesAssigned: !1,
22041          categories: [{
22042            maxNumberOfElements: 4
22043          }]
22044        },
22045        i = ["ajaxSettings", "template"];
22046      this.get = function (a) {
22047        return h[a];
22048      }, this.equals = function (a, b) {
22049        return !(!f(a) || h[a] !== b);
22050      }, this.checkDataUrlProperties = function () {
22051        return "list-required" !== h.url || "list-required" !== h.data;
22052      }, this.checkRequiredProperties = function () {
22053        for (var a in h) if ("required" === h[a]) return logger.error("Option " + a + " must be defined"), !1;
22054        return !0;
22055      }, this.printPropertiesThatDoesntExist = function (a, b) {
22056        g(a, b);
22057      }, b(), c(), h.loggerEnabled === !0 && g(console, a), e(), d();
22058    }, a;
22059  }(EasyAutocomplete || {}),
22060  EasyAutocomplete = function (a) {
22061    return a.Logger = function () {
22062      this.error = function (a) {
22063        console.log("ERROR: " + a);
22064      }, this.warning = function (a) {
22065        console.log("WARNING: " + a);
22066      };
22067    }, a;
22068  }(EasyAutocomplete || {}),
22069  EasyAutocomplete = function (a) {
22070    return a.Constans = function () {
22071      var a = {
22072        CONTAINER_CLASS: "easy-autocomplete-container",
22073        CONTAINER_ID: "eac-container-",
22074        WRAPPER_CSS_CLASS: "easy-autocomplete"
22075      };
22076      this.getValue = function (b) {
22077        return a[b];
22078      };
22079    }, a;
22080  }(EasyAutocomplete || {}),
22081  EasyAutocomplete = function (a) {
22082    return a.ListBuilderService = function (a, b) {
22083      function c(b, c) {
22084        function d() {
22085          var d,
22086            e = {};
22087          return void 0 !== b.xmlElementName && (e.xmlElementName = b.xmlElementName), void 0 !== b.listLocation ? d = b.listLocation : void 0 !== a.get("listLocation") && (d = a.get("listLocation")), void 0 !== d ? "string" == typeof d ? e.data = $(c).find(d) : "function" == typeof d && (e.data = d(c)) : e.data = c, e;
22088        }
22089        function e() {
22090          var a = {};
22091          return void 0 !== b.listLocation ? "string" == typeof b.listLocation ? a.data = c[b.listLocation] : "function" == typeof b.listLocation && (a.data = b.listLocation(c)) : a.data = c, a;
22092        }
22093        var f = {};
22094        if (f = "XML" === a.get("dataType").toUpperCase() ? d() : e(), void 0 !== b.header && (f.header = b.header), void 0 !== b.maxNumberOfElements && (f.maxNumberOfElements = b.maxNumberOfElements), void 0 !== a.get("list").maxNumberOfElements && (f.maxListSize = a.get("list").maxNumberOfElements), void 0 !== b.getValue) {
22095          if ("string" == typeof b.getValue) {
22096            var g = b.getValue;
22097            f.getValue = function (a) {
22098              return a[g];
22099            };
22100          } else "function" == typeof b.getValue && (f.getValue = b.getValue);
22101        } else f.getValue = a.get("getValue");
22102        return f;
22103      }
22104      function d(b) {
22105        var c = [];
22106        return void 0 === b.xmlElementName && (b.xmlElementName = a.get("xmlElementName")), $(b.data).find(b.xmlElementName).each(function () {
22107          c.push(this);
22108        }), c;
22109      }
22110      this.init = function (b) {
22111        var c = [],
22112          d = {};
22113        return d.data = a.get("listLocation")(b), d.getValue = a.get("getValue"), d.maxListSize = a.get("list").maxNumberOfElements, c.push(d), c;
22114      }, this.updateCategories = function (b, d) {
22115        if (a.get("categoriesAssigned")) {
22116          b = [];
22117          for (var e = 0; e < a.get("categories").length; e += 1) {
22118            var f = c(a.get("categories")[e], d);
22119            b.push(f);
22120          }
22121        }
22122        return b;
22123      }, this.convertXml = function (b) {
22124        if ("XML" === a.get("dataType").toUpperCase()) for (var c = 0; c < b.length; c += 1) b[c].data = d(b[c]);
22125        return b;
22126      }, this.processData = function (c, d) {
22127        for (var e = 0, f = c.length; f > e; e += 1) c[e].data = b(a, c[e], d);
22128        return c;
22129      }, this.checkIfDataExists = function (a) {
22130        for (var b = 0, c = a.length; c > b; b += 1) if (void 0 !== a[b].data && a[b].data instanceof Array && a[b].data.length > 0) return !0;
22131        return !1;
22132      };
22133    }, a;
22134  }(EasyAutocomplete || {}),
22135  EasyAutocomplete = function (a) {
22136    return a.proccess = function (b, c, d) {
22137      function e(a, c) {
22138        var d = [],
22139          e = "";
22140        if (b.get("list").match.enabled) for (var g = 0, h = a.length; h > g; g += 1) e = b.get("getValue")(a[g]), f(e, c) && d.push(a[g]);else d = a;
22141        return d;
22142      }
22143      function f(a, c) {
22144        return b.get("list").match.caseSensitive || ("string" == typeof a && (a = a.toLowerCase()), c = c.toLowerCase()), !!b.get("list").match.method(a, c);
22145      }
22146      function g(a) {
22147        return void 0 !== c.maxNumberOfElements && a.length > c.maxNumberOfElements && (a = a.slice(0, c.maxNumberOfElements)), a;
22148      }
22149      function h(a) {
22150        return b.get("list").sort.enabled && a.sort(b.get("list").sort.method), a;
22151      }
22152      a.proccess.match = f;
22153      var i = c.data,
22154        j = d;
22155      return i = e(i, j), i = g(i), i = h(i);
22156    }, a;
22157  }(EasyAutocomplete || {}),
22158  EasyAutocomplete = function (a) {
22159    return a.Template = function (a) {
22160      var b = {
22161          basic: {
22162            type: "basic",
22163            method: function (a) {
22164              return a;
22165            },
22166            cssClass: ""
22167          },
22168          description: {
22169            type: "description",
22170            fields: {
22171              description: "description"
22172            },
22173            method: function (a) {
22174              return a + " - description";
22175            },
22176            cssClass: "eac-description"
22177          },
22178          iconLeft: {
22179            type: "iconLeft",
22180            fields: {
22181              icon: ""
22182            },
22183            method: function (a) {
22184              return a;
22185            },
22186            cssClass: "eac-icon-left"
22187          },
22188          iconRight: {
22189            type: "iconRight",
22190            fields: {
22191              iconSrc: ""
22192            },
22193            method: function (a) {
22194              return a;
22195            },
22196            cssClass: "eac-icon-right"
22197          },
22198          links: {
22199            type: "links",
22200            fields: {
22201              link: ""
22202            },
22203            method: function (a) {
22204              return a;
22205            },
22206            cssClass: ""
22207          },
22208          custom: {
22209            type: "custom",
22210            method: function () {},
22211            cssClass: ""
22212          }
22213        },
22214        c = function (a) {
22215          var c,
22216            d = a.fields;
22217          return "description" === a.type ? (c = b.description.method, "string" == typeof d.description ? c = function (a, b) {
22218            return a + " - <span>" + b[d.description] + "</span>";
22219          } : "function" == typeof d.description && (c = function (a, b) {
22220            return a + " - <span>" + d.description(b) + "</span>";
22221          }), c) : "iconRight" === a.type ? ("string" == typeof d.iconSrc ? c = function (a, b) {
22222            return a + "<img class='eac-icon' src='" + b[d.iconSrc] + "' />";
22223          } : "function" == typeof d.iconSrc && (c = function (a, b) {
22224            return a + "<img class='eac-icon' src='" + d.iconSrc(b) + "' />";
22225          }), c) : "iconLeft" === a.type ? ("string" == typeof d.iconSrc ? c = function (a, b) {
22226            return "<img class='eac-icon' src='" + b[d.iconSrc] + "' />" + a;
22227          } : "function" == typeof d.iconSrc && (c = function (a, b) {
22228            return "<img class='eac-icon' src='" + d.iconSrc(b) + "' />" + a;
22229          }), c) : "links" === a.type ? ("string" == typeof d.link ? c = function (a, b) {
22230            return "<a href='" + b[d.link] + "' >" + a + "</a>";
22231          } : "function" == typeof d.link && (c = function (a, b) {
22232            return "<a href='" + d.link(b) + "' >" + a + "</a>";
22233          }), c) : "custom" === a.type ? a.method : b.basic.method;
22234        },
22235        d = function (a) {
22236          return a && a.type && a.type && b[a.type] ? c(a) : b.basic.method;
22237        },
22238        e = function (a) {
22239          var c = function () {
22240            return "";
22241          };
22242          return a && a.type && a.type && b[a.type] ? function () {
22243            var c = b[a.type].cssClass;
22244            return function () {
22245              return c;
22246            };
22247          }() : c;
22248        };
22249      this.getTemplateClass = e(a), this.build = d(a);
22250    }, a;
22251  }(EasyAutocomplete || {}),
22252  EasyAutocomplete = function (a) {
22253    return a.main = function (b, c) {
22254      function d() {
22255        return 0 === t.length ? void p.error("Input field doesn't exist.") : o.checkDataUrlProperties() ? o.checkRequiredProperties() ? (e(), void g()) : void p.error("Will not work without mentioned properties.") : void p.error("One of options variables 'data' or 'url' must be defined.");
22256      }
22257      function e() {
22258        function a() {
22259          var a = $("<div>"),
22260            c = n.getValue("WRAPPER_CSS_CLASS");
22261          o.get("theme") && "" !== o.get("theme") && (c += " eac-" + o.get("theme")), o.get("cssClasse
22261s") && "" !== o.get("cssClasses") && (c += " " + o.get("cssClasses")), "" !== q.getTemplateClass() && (c += " " + q.getTemplateClass()), a.addClass(c), t.wrap(a), o.get("adjustWidth") === !0 && b();
22262        }
22263        function b() {
22264          var a = t.outerWidth();
22265          t.parent().css("width", a);
22266        }
22267        function c() {
22268          t.unwrap();
22269        }
22270        function d() {
22271          var a = $("<div>").addClass(n.getValue("CONTAINER_CLASS"));
22272          a.attr("id", f()).prepend($("<ul>")), function () {
22273            a.on("show.eac", function () {
22274              switch (o.get("list").showAnimation.type) {
22275                case "slide":
22276                  var b = o.get("list").showAnimation.time,
22277                    c = o.get("list").showAnimation.callback;
22278                  a.find("ul").slideDown(b, c);
22279                  break;
22280                case "fade":
22281                  var b = o.get("list").showAnimation.time,
22282                    c = o.get("list").showAnimation.callback;
22283                  a.find("ul").fadeIn(b), c;
22284                  break;
22285                default:
22286                  a.find("ul").show();
22287              }
22288              o.get("list").onShowListEvent();
22289            }).on("hide.eac", function () {
22290              switch (o.get("list").hideAnimation.type) {
22291                case "slide":
22292                  var b = o.get("list").hideAnimation.time,
22293                    c = o.get("list").hideAnimation.callback;
22294                  a.find("ul").slideUp(b, c);
22295                  break;
22296                case "fade":
22297                  var b = o.get("list").hideAnimation.time,
22298                    c = o.get("list").hideAnimation.callback;
22299                  a.find("ul").fadeOut(b, c);
22300                  break;
22301                default:
22302                  a.find("ul").hide();
22303              }
22304              o.get("list").onHideListEvent();
22305            }).on("selectElement.eac", function () {
22306              a.find("ul li").removeClass("selected"), a.find("ul li").eq(w).addClass("selected"), o.get("list").onSelectItemEvent();
22307            }).on("loadElements.eac", function (b, c, d) {
22308              var e = "",
22309                f = a.find("ul");
22310              f.empty().detach(), v = [];
22311              for (var h = 0, i = 0, k = c.length; k > i; i += 1) {
22312                var l = c[i].data;
22313                if (0 !== l.length) {
22314                  void 0 !== c[i].header && c[i].header.length > 0 && f.append("<div class='eac-category' >" + c[i].header + "</div>");
22315                  for (var m = 0, n = l.length; n > m && h < c[i].maxListSize; m += 1) e = $("<li><div class='eac-item'></div></li>"), function () {
22316                    var a = m,
22317                      b = h,
22318                      f = c[i].getValue(l[a]);
22319                    e.find(" > div").on("click", function () {
22320                      t.val(f).trigger("change"), w = b, j(b), o.get("list").onClickEvent(), o.get("list").onChooseEvent();
22321                    }).mouseover(function () {
22322                      w = b, j(b), o.get("list").onMouseOverEvent();
22323                    }).mouseout(function () {
22324                      o.get("list").onMouseOutEvent();
22325                    }).html(q.build(g(f, d), l[a]));
22326                  }(), f.append(e), v.push(l[m]), h += 1;
22327                }
22328              }
22329              a.append(f), o.get("list").onLoadEvent();
22330            });
22331          }(), t.after(a);
22332        }
22333        function e() {
22334          t.next("." + n.getValue("CONTAINER_CLASS")).remove();
22335        }
22336        function g(a, b) {
22337          return o.get("highlightPhrase") && "" !== b ? i(a, b) : a;
22338        }
22339        function h(a) {
22340          return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
22341        }
22342        function i(a, b) {
22343          var c = h(b);
22344          return (a + "").replace(new RegExp("(" + c + ")", "gi"), "<b>$1</b>");
22345        }
22346        t.parent().hasClass(n.getValue("WRAPPER_CSS_CLASS")) && (e(), c()), a(), d(), u = $("#" + f()), o.get("placeholder") && t.attr("placeholder", o.get("placeholder"));
22347      }
22348      function f() {
22349        var a = t.attr("id");
22350        return a = n.getValue("CONTAINER_ID") + a;
22351      }
22352      function g() {
22353        function a() {
22354          s("autocompleteOff", !0) && n(), b(), c(), d(), e(), f(), g();
22355        }
22356        function b() {
22357          t.focusout(function () {
22358            var a,
22359              b = t.val();
22360            o.get("list").match.caseSensitive || (b = b.toLowerCase());
22361            for (var c = 0, d = v.length; d > c; c += 1) if (a = o.get("getValue")(v[c]), o.get("list").match.caseSensitive || (a = a.toLowerCase()), a === b) return w = c, void j(w);
22362          });
22363        }
22364        function c() {
22365          t.off("keyup").keyup(function (a) {
22366            function b(a) {
22367              function b() {
22368                var a = {},
22369                  b = o.get("ajaxSettings") || {};
22370                for (var c in b) a[c] = b[c];
22371                return a;
22372              }
22373              function c(a, b) {
22374                return o.get("matchResponseProperty") !== !1 ? "string" == typeof o.get("matchResponseProperty") ? b[o.get("matchResponseProperty")] === a : "function" == typeof o.get("matchResponseProperty") ? o.get("matchResponseProperty")(b) === a : !0 : !0;
22375              }
22376              if (!(a.length < o.get("minCharNumber"))) {
22377                if ("list-required" !== o.get("data")) {
22378                  var d = o.get("data"),
22379                    e = r.init(d);
22380                  e = r.updateCategories(e, d), e = r.processData(e, a), k(e, a), t.parent().find("li").length > 0 ? h() : i();
22381                }
22382                var f = b();
22383                void 0 !== f.url && "" !== f.url || (f.url = o.get("url")), void 0 !== f.dataType && "" !== f.dataType || (f.dataType = o.get("dataType")), void 0 !== f.url && "list-required" !== f.url && (f.url = f.url(a), f.data = o.get("preparePostData")(f.data, a), $.ajax(f).done(function (b) {
22384                  var d = r.init(b);
22385                  d = r.updateCategories(d, b), d = r.convertXml(d), c(a, b) && (d = r.processData(d, a), k(d, a)), r.checkIfDataExists(d) && t.parent().find("li").length > 0 ? h() : i(), o.get("ajaxCallback")();
22386                }).fail(function () {
22387                  p.warning("Fail to load response data");
22388                }).always(function () {}));
22389              }
22390            }
22391            switch (a.keyCode) {
22392              case 27:
22393                i(), l();
22394                break;
22395              case 38:
22396                a.preventDefault(), v.length > 0 && w > 0 && (w -= 1, t.val(o.get("getValue")(v[w])), j(w));
22397                break;
22398              case 40:
22399                a.preventDefault(), v.length > 0 && w < v.length - 1 && (w += 1, t.val(o.get("getValue")(v[w])), j(w));
22400                break;
22401              default:
22402                if (a.keyCode > 40 || 8 === a.keyCode) {
22403                  var c = t.val();
22404                  o.get("list").hideOnEmptyPhrase !== !0 || 8 !== a.keyCode || "" !== c ? o.get("requestDelay") > 0 ? (void 0 !== m && clearTimeout(m), m = setTimeout(function () {
22405                    b(c);
22406                  }, o.get("requestDelay"))) : b(c) : i();
22407                }
22408            }
22409          });
22410        }
22411        function d() {
22412          t.on("keydown", function (a) {
22413            a = a || window.event;
22414            var b = a.keyCode;
22415            return 38 === b ? (suppressKeypress = !0, !1) : void 0;
22416          }).keydown(function (a) {
22417            13 === a.keyCode && w > -1 && (t.val(o.get("getValue")(v[w])), o.get("list").onKeyEnterEvent(), o.get("list").onChooseEvent(), w = -1, i(), a.preventDefault());
22418          });
22419        }
22420        function e() {
22421          t.off("keypress");
22422        }
22423        function f() {
22424          t.focus(function () {
22425            "" !== t.val() && v.length > 0 && (w = -1, h());
22426          });
22427        }
22428        function g() {
22429          t.blur(function () {
22430            setTimeout(function () {
22431              w = -1, i();
22432            }, 250);
22433          });
22434        }
22435        function n() {
22436          t.attr("autocomplete", "off");
22437        }
22438        a();
22439      }
22440      function h() {
22441        u.trigger("show.eac");
22442      }
22443      function i() {
22444        u.trigger("hide.eac");
22445      }
22446      function j(a) {
22447        u.trigger("selectElement.eac", a);
22448      }
22449      function k(a, b) {
22450        u.trigger("loadElements.eac", [a, b]);
22451      }
22452      function l() {
22453        t.trigger("blur");
22454      }
22455      var m,
22456        n = new a.Constans(),
22457        o = new a.Configuration(c),
22458        p = new a.Logger(),
22459        q = new a.Template(c.template),
22460        r = new a.ListBuilderService(o, a.proccess),
22461        s = o.equals,
22462        t = b,
22463        u = "",
22464        v = [],
22465        w = -1;
22466      a.consts = n, this.getConstants = function () {
22467        return n;
22468      }, this.getConfiguration = function () {
22469        return o;
22470      }, this.getContainer = function () {
22471        return u;
22472      }, this.getSelectedItemIndex = function () {
22473        return w;
22474      }, this.getItems = function () {
22475        return v;
22476      }, this.getItemData = function (a) {
22477        return v.length < a || void 0 === v[a] ? -1 : v[a];
22478      }, this.getSelectedItemData = function () {
22479        return this.getItemData(w);
22480      }, this.build = function () {
22481        e();
22482      }, this.init = function () {
22483        d();
22484      };
22485    }, a.eacHandles = [], a.getHandle = function (b) {
22486      return a.eacHandles[b];
22487    }, a.inputHasId = function (a) {
22488      return void 0 !== $(a).attr("id") && $(a).attr("id").length > 0;
22489    }, a.assignRandomId = function (b) {
22490      var c = "";
22491      do c = "eac-" + Math.floor(1e4 * Math.random()); while (0 !== $("#" + c).length);
22492      elementId = a.consts.getValue("CONTAINER_ID") + c, $(b).attr("id", c);
22493    }, a.setHandle = function (b, c) {
22494      a.eacHandles[c] = b;
22495    }, a;
22496  }(EasyAutocomplete || {});
22497!function (a) {
22498  a.fn.easyAutocomplete = function (b) {
22499    return this.each(function () {
22500      var c = a(this),
22501        d = new EasyAutocomplete.main(c, b);
22502      EasyAutocomplete.inputHasId(c) || EasyAutocomplete.assignRandomId(c), d.init(), EasyAutocomplete.setHandle(d, c.attr("id"));
22503    });
22504  }, a.fn.getSelectedItemIndex = function () {
22505    var b = a(this).attr("id");
22506    return void 0 !== b ? EasyAutocomplete.getHandle(b).getSelectedItemIndex() : -1;
22507  }, a.fn.getItems = function () {
22508    var b = a(this).attr("id");
22509    return void 0 !== b ? EasyAutocomplete.getHandle(b).getItems() : -1;
22510  }, a.fn.getItemData = function (b) {
22511    var c = a(this).attr("id");
22512    return void 0 !== c && b > -1 ? EasyAutocomplete.getHandle(c).getItemData(b) : -1;
22513  }, a.fn.getSelectedItemData = function () {
22514    var b = a(this).attr("id");
22515    return void 0 !== b ? EasyAutocomplete.getHandle(b).getSelectedItemData() : -1;
22516  };
22517}((jquery_default()));
22518;// ./wp-content/themes/sfrtheme/assets/js/LazyLoad.js
22519class LazyLoad {
22520  constructor(element = 'lazy', threshold = 0, timeout = 70) {
22521    this.element = element;
22522    this.threshold = threshold;
22523    this.timeout = timeout;
22524    this.onChange = this.onChange.bind(this);
22525    this.observer = new IntersectionObserver(this.onChange, {
22526      threshold: [this.threshold]
22527    });
22528    this.lazyLoadinit;
22529  }
22530  get lazyLoadinit() {
22531    const {
22532      element,
22533      observer
22534    } = this;
22535    $.each($(`.${element}`), (index, img) => {
22536      observer.observe(img);
22537    });
22538    return this.element;
22539  }
22540  onChange(changes) {
22541    let i = 0;
22542    const {
22543      observer,
22544      timeout
22545    } = this;
22546    $.each(changes, (index, change) => {
22547      if (change.isIntersecting) {
22548        if (change.target.classList.contains('lazy') && !change.target.classList.contains('anim')) {
22549          if (change.target.localName === 'img') {
22550            change.target.src = change.target.dataset.src;
22551          } else {
22552            change.target.style.backgroundImage = 'url("' + change.target.dataset.src + '")';
22553          }
22554        }
22555        setTimeout(function () {
22556          change.target.classList.add('visible');
22557        }, timeout * i);
22558        i++;
22559        observer.unobserve(change.target);
22560      }
22561    });
22562  }
22563}
22564;// ./wp-content/themes/sfrtheme/assets/js/popins.js
22565function ajaxGetPopinContent(contentID, phoneID) {
22566  $('body').append('<div class="loader"></div>');
22567  $('body').addClass('loading');
22568  var params = {
22569    contentID: contentID
22570  };
22571  if (phoneID != false) {
22572    var params = {
22573      contentID: contentID,
22574      phoneID: phoneID
22575    };
22576  }
22577  $.ajax({
22578    url: sfrJSVars.ajaxurl,
22579    method: 'POST',
22580    data: {
22581      'action': 'ajaxGetPopinContentHTML',
22582      'params': params
22583    },
22584    success: function (data) {
22585      data = JSON.parse(data);
22586      $(data).insertAfter('.footer');
22587      modalActions();
22588      $('body').addClass('stop_scrolling');
22589      $('body').removeClass('loading');
22590      $('body>.loader').remove();
22591    },
22592    error: function (request, error) {
22593      console.log(error);
22594    }
22595  });
22596}
22597function initForfaitTypePopin() {
22598  $(document).on('click', '.forfait-type-learn-more', function (e) {
22599    e.preventDefault();
22600    const forfaitType = $(this).data('forfait-type');
22601    $('body').append('<div class="loader"></div>');
22602    $('body').addClass('loading');
22603    $.ajax({
22604      url: sfrJSVars.ajaxurl,
22605      method: 'POST',
22606      data: {
22607        action: 'ajaxGetPopinContentHTML',
22608        params: {
22609          contentID: 'forfait_type',
22610          forfaitType: forfaitType
22611        }
22612      },
22613      success: function (data) {
22614        data = JSON.parse(data);
22615        $(data).insertAfter('.footer');
22616        modalActions();
22617        $('body').addClass('stop_scrolling');
22618        $('body').removeClass('loading');
22619        $('body>.loader').remove();
22620      },
22621      error: function (request, error) {
22622        console.log(error);
22623        $('body').removeClass('loading');
22624        $('body>.loader').remove();
22625      }
22626    });
22627  });
22628}
22629
22630// Handle energy class modal click
22631function initEnergyClassModal() {
22632  $('.energy-class-modal').on('click', function (e) {
22633    e.preventDefault();
22634    const phoneId = $(this).data('phone-id');
22635    const energyClass = $(this).data('class');
22636    $('body').append('<div class="loader"></div>');
22637    $('body').addClass('loading');
22638    $.ajax({
22639      url: sfrJSVars.ajaxurl,
22640      method: 'POST',
22641      data: {
22642        'action': 'ajaxGetPopinContentHTML',
22643        'params': {
22644          'contentID': 'energy_class',
22645          'phoneID': phoneId,
22646          'class': energyClass
22647        }
22648      },
22649      success: function (data) {
22650        data = JSON.parse(data);
22651        $(data).insertAfter('.footer');
22652        modalActions();
22653        $('body').addClass('stop_scrolling');
22654        $('body').removeClass('loading');
22655        $('body>.loader').remove();
22656      },
22657      error: function (request, error) {
22658        console.log(error);
22659      }
22660    });
22661  });
22662}
22663function modalActions() {
22664  $('.modal footer>p').click(function () {
22665    $(this).parents('footer').find('>div').slideToggle(200);
22666    $('.modal .content').animate({
22667      scrollTop: $('.modal footer').offset().top
22668    }, 200);
22669  });
22670  $('.modal .close').click(function () {
22671    $(this).parents('.modal').remove();
22672    $('body').removeClass('stop_scrolling');
22673  });
22674  $('.modal .choose_accessory').click(function () {
22675    $(this).parents('.modal').remove();
22676    $('body').removeClass('stop_scrolling');
22677  });
22678}
22679;// ./wp-content/themes/sfrtheme/assets/js/datalayer/planTracking.js
22680const STORAGE_PLAN_KEY = 'plan_tracking';
22681const STORAGE_USER_KEY = 'plan_user_data';
22682const parsePrice = text => {
22683  const normalized = String(text || '').replace(/\s/g, '');
22684  const match = normalized.match(/([\d]+)[,.]([\d]+)/);
22685  if (!match) {
22686    return 0;
22687  }
22688  return parseFloat(`${match[1]}.${match[2]}`);
22689};
22690const PlanTracking = {
22691  config: {
22692    planName: '',
22693    planPrice: 0,
22694    phonePrefix: '+33'
22695  },
22696  sha256(value) {
22697    if (!value || !window.crypto?.subtle) {
22698      return Promise.resolve('');
22699    }
22700    return window.crypto.subtle.digest('SHA-256', new TextEncoder().encode(value)).then(buffer => Array.from(new Uint8Array(buffer)).map(byte => byte.toString(16).padStart(2, '0')).join(''));
22701  },
22702  normalizeEmail(email) {
22703    return String(email || '').trim().toLowerCase();
22704  },
22705  normalizePhone(phone, prefix = this.config.phonePrefix) {
22706    let digits = String(phone || '').replace(/\D/g, '');
22707    const phonePrefix = prefix || '+33';
22708    if (digits.startsWith('0')) {
22709      digits = phonePrefix.replace('+', '') + digits.slice(1);
22710    } else if (!digits.startsWith(phonePrefix.replace('+', ''))) {
22711      digits = phonePrefix.replace('+', '') + digits;
22712    }
22713    return '+' + digits.replace(/^\+/, '');
22714  },
22715  async buildUserData(email, phone) {
22716    const userData = {};
22717    if (email) {
22718      userData.sha256_email_address = await this.sha256(this.normalizeEmail(email));
22719    }
22720    if (phone) {
22721      userData.sha256_phone_number = await this.sha256(this.normalizePhone(phone));
22722    }
22723    return userData;
22724  },
22725  persistPlan(planName, planPrice) {
22726    const plan = {
22727      planName,
22728      planPrice: Number(planPrice) || 0
22729    };
22730    sessionStorage.setItem(STORAGE_PLAN_KEY, JSON.stringify(plan));
22731    this.config.planName = planName;
22732    this.config.planPrice = plan.planPrice;
22733  },
22734  loadPlan() {
22735    const stored = sessionStorage.getItem(STORAGE_PLAN_KEY);
22736    if (!stored) {
22737      return null;
22738    }
22739    try {
22740      const plan = JSON.parse(stored);
22741      if (plan.planName) {
22742        this.config.planName = plan.planName;
22743      }
22744      if (typeof plan.planPrice !== 'undefined') {
22745        this.config.planPrice = Number(plan.planPrice) || 0;
22746      }
22747      return plan;
22748    } catch (error) {
22749      return null;
22750    }
22751  },
22752  readPlanData($element) {
22753    const planName = $element.attr('data-plan-name') || $element.data('plan-name') || '';
22754    const planPriceRaw = $element.attr('data-plan-price') ?? $element.data('plan-price');
22755    const planPrice = planPriceRaw !== undefined && planPriceRaw !== '' ? Number(planPriceRaw) : NaN;
22756    return {
22757      planName: String(planName).trim(),
22758      planPrice
22759    };
22760  },
22761  getPlanFromElement($element) {
22762    const $card = $element.closest('#archive_ff li, .forfait, li');
22763    let {
22764      planName,
22765      planPrice
22766    } = this.readPlanData($element);
22767    if (!planName || Number.isNaN(planPrice)) {
22768      const $visiblePrice = $card.find('.prices li:visible').first();
22769      const visiblePlan = this.readPlanData($visiblePrice);
22770      planName = planName || visiblePlan.planName;
22771      planPrice = Number.isNaN(planPrice) ? visiblePlan.planPrice : planPrice;
22772    }
22773    if (!planName) {
22774      planName = $card.find('.title-price .title').first().text().trim() || $card.find('h2 span').first().text().trim();
22775    }
22776    if (Number.isNaN(planPrice) || !planPrice) {
22777      planPrice = parsePrice($card.find('.prices li:visible .current').first().text());
22778    }
22779    return {
22780      planName,
22781      planPrice: Number(planPrice) || 0
22782    };
22783  },
22784  buildPayload(eventName, planName, planPrice, extra = {}) {
22785    return {
22786      event: eventName,
22787      plan_name: planName,
22788      plan_price: Number(planPrice) || 0,
22789      ...extra
22790    };
22791  },
22792  push(eventName, extra = {}) {
22793    const payload = this.buildPayload(eventName, this.config.planName, this.config.planPrice, extra);
22794    window.dataLayer = window.dataLayer || [];
22795    window.dataLayer.push(payload);
22796  },
22797  pushPlanEvent(eventName, planName, planPrice, extra = {}) {
22798    this.persistPlan(planName, planPrice);
22799    const payload = this.buildPayload(eventName, planName, planPrice, extra);
22800    window.dataLayer = window.dataLayer || [];
22801    window.dataLayer.push(payload);
22802  },
22803  pushPlanEventWithUserData(eventName, planName, planPrice, userData, extra = {}) {
22804    const payloadExtra = {
22805      ...extra
22806    };
22807    if (userData && Object.keys(userData).length > 0) {
22808      payloadExtra.user_data = userData;
22809    }
22810    this.pushPlanEvent(eventName, planName, planPrice, payloadExtra);
22811  }
22812};
22813PlanTracking.loadPlan();
22814/* harmony default export */ const planTracking = (PlanTracking);
22815;// ./wp-content/themes/sfrtheme/assets/js/pageForfaits.js
22816
22817
22818
22819
22820
22821jquery_default()(document).ready(function () {
22822  forfaitPageEventListener();
22823  //carrouselForfait();
22824  forfaitsFiltersListener();
22825  forfaitsFiltersPosition();
22826  initEngagementFilter();
22827  initPlanAddPhonePopin();
22828});
22829function forfaitsFiltersListener() {
22830  // Gestion des filtres mob/box (comportement existant avec AJAX)
22831  // Utiliser la délégation d'événements pour gérer les éléments ajoutés dynamiquement
22832  jquery_default()(document).on("click", "#archive_ff .filters form:not(.engagement-filter) label", function (e) {
22833    if (jquery_default()("#archive_ff .filters form").hasClass("busy")) {
22834      e.preventDefault();
22835    }
22836  });
22837  jquery_default()(document).on("change", "#archive_ff .filters form:not(.engagement-filter) input", function (e) {
22838    if (!jquery_default()("#archive_ff .filters form").hasClass("busy")) {
22839      const action = jquery_default()(this).parents("form").hasClass("mob") ? "ajaxChangeForfaitMobType" : "ajaxChangeForfaitBoxType";
22840      changeSessionSettings({
22841        params: {
22842          postType: jquery_default()("#archive_ff").data("posttype"),
22843          pageID: jquery_default()("#archive_ff").data("pageid"),
22844          forfaitType: jquery_default()(this).val()
22845        },
22846        action
22847      });
22848    }
22849  });
22850
22851  // Gestion du filtre d'engagement (filtrage côté client, sans AJAX)
22852  jquery_default()(document).on("change", ".engagement-filter input", function (e) {
22853    applyFilters();
22854  });
22855
22856  // Gestion du filtre Gold/Silver avec boutons (filtrage côté client, sans AJAX)
22857  jquery_default()(document).on("click", ".forfait_type_btn", function (e) {
22858    // Ne rien faire si le bouton cliqué est déjà actif
22859    if (jquery_default()(this).hasClass("active")) {
22860      return;
22861    }
22862
22863    // Retirer la classe active de tous les boutons et l'ajouter au bouton cliqué
22864    jquery_default()(".forfait_type_btn").removeClass("active");
22865    jquery_default()(this).addClass("active");
22866
22867    // Mettre à jour le titre en fonction du type sélectionné
22868    updateForfaitTypeTitle(jquery_default()(this).data("forfait-type"));
22869
22870    // Appliquer les filtres
22871    applyFilters();
22872  });
22873}
22874function updateForfaitTypeTitle(type) {
22875  const $goldTitle = jquery_default()(".forfait-type-title.gold");
22876  const $silverTitle = jquery_default()(".forfait-type-title.silver");
22877  const $goldContent = jquery_default()(".forfait-type-contents .gold");
22878  const $silverContent = jquery_default()(".forfait-type-contents .silver");
22879  if (type === "gold") {
22880    $goldTitle.addClass("active");
22881    $silverTitle.removeClass("active");
22882    $goldContent.addClass("active");
22883    $silverContent.removeClass("active");
22884  } else if (type === "silver") {
22885    $silverTitle.addClass("active");
22886    $goldTitle.removeClass("active");
22887    $silverContent.addClass("active");
22888    $goldContent.removeClass("active");
22889  }
22890}
22891function applyFilters() {
22892  jquery_default()(".forfaits_container").each(function () {
22893    const $container = jquery_default()(this);
22894    const selectedEngagement = $container.find(".engagement-filter input:checked").val();
22895
22896    // On ne récupère le type que si le filtre est visible
22897    const $typeFilter = $container.find(".forfait-type-filter");
22898    const selectedForfaitType = $typeFilter.length > 0 && !$typeFilter.hasClass("hidden") ? $container.find(".forfait_type_btn.active").data("forfait-type") : null;
22899
22900    // Masquer tous les prix du conteneur d'abord
22901    $container.find(".advantages > li .prices ul li").hide();
22902
22903    // Appliquer les filtres forfait par forfait
22904    $container.find(".advantages > li").each(function () {
22905      const $forfait = jquery_default()(this);
22906      const $forfaitPrices = $forfait.find(".prices ul li");
22907
22908      // Vérifier si un prix "Silver" existe dans ce forfait précis
22909      let hasSilver = false;
22910      $forfaitPrices.each(function () {
22911        if ((jquery_default()(this).data("forfait-type") || "").toLowerCase() === "silver") {
22912          hasSilver = true;
22913        }
22914      });
22915      let hasMatchingPrice = false;
22916      $forfaitPrices.each(function (index) {
22917        const $price = jquery_default()(this);
22918        const priceEngagement = $price.data("engagement");
22919        const priceType = $price.data("forfait-type");
22920        const planPrice = $price.attr("data-plan-price");
22921        const hasPrice = planPrice !== undefined && planPrice !== "";
22922        let matchesEngagement = false;
22923        let matchesForfaitType = false;
22924        if (selectedEngagement) {
22925          matchesEngagement = priceEngagement === selectedEngagement;
22926        } else {
22927          matchesEngagement = true;
22928        }
22929        if (selectedForfaitType) {
22930          matchesForfaitType = priceType === selectedForfaitType;
22931        } else if (!selectedEngagement) {
22932          if (hasSilver) {
22933            matchesForfaitType = priceType === "silver";
22934          } else {
22935            matchesForfaitType = index === 0;
22936          }
22937        } else {
22938          matchesForfaitType = true;
22939        }
22940        if (matchesEngagement && matchesForfaitType && hasPrice) {
22941          $price.show();
22942          hasMatchingPrice = true;
22943        }
22944      });
22945      if (selectedEngagement) {
22946        $forfait.toggle(hasMatchingPrice);
22947      } else {
22948        $forfait.show();
22949      }
22950      updateDynamicFormulaButtons($forfait);
22951    });
22952    const $noResult = $container.find(".engagement-no-result");
22953    if ($noResult.length) {
22954      const hasVisibleForfait = $container.find(".advantages > li:visible").length > 0;
22955      $noResult.toggle(!!selectedEngagement && !hasVisibleForfait);
22956    }
22957  });
22958}
22959function initEngagementFilter() {
22960  applyFilters();
22961  jquery_default()('#archive_ff .forfaits_container .advantages > li').each(function () {
22962    updateDynamicFormulaButtons(jquery_default()(this));
22963  });
22964}
22965function updateDynamicFormulaButtons($forfait) {
22966  // Trouver le prix visible (celui qui n'est pas caché)
22967  const $visiblePrice = $forfait.find(".prices ul li:visible").first();
22968  if ($visiblePrice.length === 0) return;
22969
22970  // Récupérer les données de la formule visible
22971  const formulaId = $visiblePrice.data("formula-id");
22972  const lockedFormulaId = $visiblePrice.data("locked-formula-id");
22973  const planName = $visiblePrice.attr("data-plan-name") || $visiblePrice.data("plan-name");
22974  const planPrice = $visiblePrice.attr("data-plan-price") || $visiblePrice.data("plan-price");
22975  const $dynamicButtons = $forfait.find(".actions .dynamic-formula-btn");
22976  $dynamicButtons.each(function () {
22977    const $btn = jquery_default()(this);
22978    if (planName) {
22979      $btn.attr("data-plan-name", planName);
22980    }
22981    if (planPrice !== undefined && planPrice !== "") {
22982      $btn.attr("data-plan-price", planPrice);
22983    }
22984    if ($btn.is("a")) {
22985      const currentHref = $btn.attr("href");
22986
22987      // Remplacer l'ID de la formule dans l'URL
22988      const newHref = currentHref.replace(/formula=\d+/, "formula=" + formulaId);
22989      $btn.attr("href", newHref);
22990    }
22991    // Si c'est un span avec popin_action
22992    else if ($btn.is("span") && $btn.hasClass("popin_action")) {
22993      if (lockedFormulaId) {
22994        $btn.attr("data-id", lockedFormulaId);
22995      }
22996    } else {
22997      $btn.attr("data-formula-id", formulaId);
22998    }
22999  });
23000}
23001function forfaitsFiltersPosition() {
23002  if (jquery_default()("#archive_ff").length > 0 && jquery_default()("#archive_ff .filters").length > 0) {
23003    var $filters = jquery_default()("#archive_ff .filters");
23004
23005    // Create or find the spacer element
23006    var $spacer = jquery_default()("#archive_ff .filters-spacer");
23007    if ($spacer.length === 0) {
23008      // Create spacer if it doesn't exist
23009      $spacer = jquery_default()('<div class="filters-spacer"></div>');
23010      $filters.before($spacer);
23011    }
23012    onScrollMoveFilters($filters, $spacer);
23013    jquery_default()(document).on("scroll", function () {
23014      onScrollMoveFilters($filters, $spacer);
23015    });
23016    jquery_default()(window).resize(function () {
23017      onScrollMoveFilters($filters, $spacer);
23018    });
23019  }
23020}
23021function onScrollMoveFilters($filters, $spacer) {
23022  // Add null/existence checks
23023  if (!$filters || $filters.length === 0 || !$spacer || $spacer.length === 0) {
23024    return;
23025  }
23026  var filtersTop = parseInt($spacer.offset().top),
23027    filtersHeight = $filters.innerHeight(),
23028    siteHeaderHeight = jquery_default()("#heading").innerHeight() + (jquery_default()("#wpadminbar").length > 0 ? jquery_default()("#wpadminbar").innerHeight() : 0),
23029    screenTopScrollPosition = jquery_default()(document).scrollTop(),
23030    $container = jquery_default()("#archive_ff .forfait_list");
23031
23032  // Check if container exists
23033  if ($container.length === 0) {
23034    return;
23035  }
23036  var containerBottomPosition = parseInt($container.offset().top) + $container.innerHe
23036ight(),
23037    startPosition = screenTopScrollPosition + siteHeaderHeight,
23038    stopPosition = containerBottomPosition - (siteHeaderHeight + filtersHeight);
23039  if (filtersTop < startPosition) {
23040    if (stopPosition > screenTopScrollPosition) {
23041      $filters.addClass("scrolled");
23042      $filters.css({
23043        top: `${siteHeaderHeight}px`
23044      });
23045      $spacer.css({
23046        height: `${filtersHeight}px`
23047      });
23048    } else {
23049      $filters.css({
23050        top: `${siteHeaderHeight - (screenTopScrollPosition - stopPosition)}px`
23051      });
23052    }
23053  } else {
23054    $filters.removeClass("scrolled");
23055    $filters.css({
23056      top: `auto`
23057    });
23058    $spacer.css({
23059      height: `0`
23060    });
23061  }
23062}
23063
23064/**
23065 * FOR DATAS
23066 **/
23067function forfaitPageEventListener() {
23068  // Utiliser la délégation d'événements pour tous les listeners
23069  jquery_default()(document).on("click", "#archive_ff .phone_block .phone_btn", function (e) {
23070    if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) {
23071      const phoneOption = jquery_default()(this).data("phone-option");
23072      const displayPhone = phoneOption === "with";
23073
23074      // Ne rien faire si le bouton cliqué est déjà actif
23075      if (jquery_default()(this).hasClass("active")) {
23076        return;
23077      }
23078      jquery_default()(this).parents(".forfaits_container").addClass("busy");
23079
23080      // Retirer la classe active de tous les boutons et l'ajouter au bouton cliqué
23081      jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .phone_btn").removeClass("active");
23082      jquery_default()(this).parents(".forfaits_container").parent().find('.phone_block .phone_btn[data-phone-option="' + phoneOption + '"]').addClass("active");
23083
23084      // Automatisation JS : "Sans téléphone" décoche "Avec engagement"
23085      const $container = jquery_default()(this).parents(".forfaits_container");
23086      const $withoutEngagementLi = $container.find(".without-engagement-li");
23087      if (displayPhone) {
23088        $container.find('.engagement-filter input[value="with-engagement"]').prop("checked", true);
23089        $withoutEngagementLi.hide();
23090      } else {
23091        $container.find('.engagement-filter input[value="without-engagement"]').prop("checked", true);
23092        $withoutEngagementLi.show();
23093      }
23094
23095      // Afficher/masquer le filtre Gold/Silver en fonction du choix
23096      const $forfaitTypeFilter = jquery_default()(this).parents(".forfaits_container").parent().find(".forfait-type-filter");
23097      if (displayPhone) {
23098        $forfaitTypeFilter.removeClass("hidden");
23099      } else {
23100        $forfaitTypeFilter.addClass("hidden");
23101      }
23102      changeSessionSettings({
23103        params: {
23104          postType: jquery_default()("#archive_ff").data("posttype"),
23105          pageID: jquery_default()("#archive_ff").data("pageid"),
23106          displayPhone: displayPhone
23107        },
23108        action: "ajaxToggleAddPhoneToForfait",
23109        reload: true // On garde le reload ici pour que le PHP se synchronise
23110      });
23111    }
23112  });
23113  jquery_default()(document).on("click", ".container .advantages > li .accordion .title", function () {
23114    if (jquery_default()(this).closest(".forfaits_blocs").hasClass("loading")) {
23115      return;
23116    }
23117    const $title = jquery_default()(this);
23118    const $list = $title.siblings("ul").first();
23119    if (!$list.length) {
23120      return;
23121    }
23122    const isOpen = $list.is(":visible");
23123    $list.stop(true, true);
23124    if (isOpen) {
23125      $list.slideUp();
23126      $title.removeClass("open");
23127    } else {
23128      $list.slideDown();
23129      $title.addClass("open");
23130    }
23131  });
23132  jquery_default()(document).on("click", "#archive_ff .popin_action", function () {
23133    if (jquery_default()(this).data("phoneid")) {
23134      ajaxGetPopinContent(jquery_default()(this).data("id"), jquery_default()(this).data("phoneid"));
23135    } else {
23136      ajaxGetPopinContent(jquery_default()(this).data("id"));
23137    }
23138  });
23139  jquery_default()(document).on("click", "#archive_ff .phone_block .portabilite", function (e) {
23140    if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) {
23141      jquery_default()(this).parents(".forfaits_container").addClass("busy");
23142      jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .portabilite").toggleClass("active");
23143      let portability = false;
23144      if (jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .portabilite").hasClass("active")) {
23145        portability = true;
23146      }
23147      changeSessionSettings({
23148        params: {
23149          postType: jquery_default()("#archive_ff").data("posttype"),
23150          pageID: jquery_default()("#archive_ff").data("pageid"),
23151          portability: portability
23152        },
23153        action: "ajaxTogglePortability"
23154      });
23155    }
23156  });
23157  jquery_default()(document).on("click", ".switchboxtv", function (e) {
23158    e.preventDefault();
23159    if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) {
23160      jquery_default()(this).parents(".forfaits_container").addClass("busy");
23161      jquery_default()(this).toggleClass("active");
23162      let isBoxTV = jquery_default()(this).hasClass("active");
23163      const archiveRoot = jquery_default()(this).closest("#archive_ff");
23164      changeSessionSettings({
23165        params: {
23166          postType: archiveRoot.data("posttype"),
23167          pageID: archiveRoot.data("pageid"),
23168          isBoxTV: isBoxTV
23169        },
23170        action: "ajaxToggleBoxTV",
23171        archiveRoot: archiveRoot.length ? archiveRoot : null
23172      });
23173    }
23174  });
23175}
23176function changeSessionSettings({
23177  params,
23178  action,
23179  reload = true,
23180  archiveRoot = null
23181}) {
23182  if (params.postType && params.pageID) {
23183    const $archive = archiveRoot && archiveRoot.length ? archiveRoot : jquery_default()("#archive_ff").first();
23184    if (reload) {
23185      $archive.find(".forfait_list .forfaits_blocs").addClass("loading");
23186    }
23187    jquery_default().ajax({
23188      url: sfrJSVars.ajaxurl,
23189      method: "POST",
23190      data: {
23191        action: action,
23192        params: params
23193      },
23194      success: function (data) {
23195        if (reload) {
23196          reloadForfaitVue(params, $archive);
23197        } else {
23198          jquery_default()(".forfaits_container").removeClass("busy");
23199        }
23200      },
23201      error: function (request, error) {
23202        console.log(error);
23203        jquery_default()(".forfaits_container").removeClass("busy");
23204        if (reload) {
23205          $archive.find(".forfait_list .forfaits_blocs").removeClass("loading");
23206        }
23207      }
23208    });
23209  } else {
23210    console.log("Error no postType has been set");
23211  }
23212}
23213function reloadForfaitVue(params, archiveRoot = null) {
23214  if (params.postType && params.pageID) {
23215    const $archive = archiveRoot && archiveRoot.length ? archiveRoot : jquery_default()("#archive_ff").first();
23216    jquery_default().ajax({
23217      url: sfrJSVars.ajaxurl,
23218      method: "POST",
23219      data: {
23220        action: "reloadForfaitVue",
23221        params: params
23222      },
23223      success: function (data) {
23224        $archive.find(".forfait_list .forfaits_blocs").html(data).append('<div class="loader"></div>').removeClass("loading");
23225        jquery_default()(".forfaits_container").removeClass("busy");
23226        new LazyLoad("lazy", 0);
23227        if (typeof initTooltips === "function") {
23228          initTooltips();
23229        }
23230        initEngagementFilter();
23231        const activeForfaitType = jquery_default()(".forfait_type_btn.active").data("forfait-type");
23232        if (activeForfaitType) {
23233          updateForfaitTypeTitle(activeForfaitType);
23234        }
23235      },
23236      error: function (request, error) {
23237        console.log(error);
23238        $archive.find(".forfait_list .forfaits_blocs").removeClass("loading");
23239        jquery_default()(".forfaits_container").removeClass("busy");
23240      }
23241    });
23242  }
23243}
23244
23245/**
23246 * FOR CARROUSEL
23247 **/
23248
23249function carrouselForfait() {
23250  //Initialisatation du carrousel des forfaits
23251  $("#archive_ff .forfait_list article").each(function () {
23252    $(this).data("scrolled", 0);
23253    $(this).find(">.container>ul").css({
23254      transform: "translateX(0px)"
23255    });
23256    $(this).find(">.container>ul .loader").css({
23257      transform: "translateX(0px)"
23258    });
23259    $(this).find(".arrows span span.prev").addClass("hide");
23260  });
23261  resetFFCarrousel();
23262  onScrollCalculArrowForfaits();
23263  $(window).resize(function () {
23264    resetFFCarrousel();
23265    onScrollCalculArrowForfaits();
23266  });
23267
23268  //Action des clics sur les flèches
23269  $("#archive_ff .forfait_list article").each(function () {
23270    var $currentArticle = $(this);
23271    $currentArticle.find(".arrows span span").off("click");
23272    $currentArticle.find(".arrows span span").on("click", function () {
23273      $currentArticle.find(".arrows span span").removeClass("hide");
23274      var limit = 0;
23275      $currentArticle.find(">.container>ul:first-of-type>li").each(function () {
23276        limit += $currentArticle.find(">.container>ul:first-of-type>li").outerWidth(true);
23277      });
23278      if ($(this).hasClass("next")) {
23279        $currentArticle.data("scrolled", $currentArticle.data("scrolled") + 1);
23280      } else {
23281        $currentArticle.data("scrolled", $currentArticle.data("scrolled") - 1);
23282      }
23283      var distance = 0;
23284      for (let i = 1; i <= $currentArticle.data("scrolled"); i++) {
23285        distance += $currentArticle.find(">.container>ul:first-of-type>li:nth-child(" + i + ")").outerWidth(true);
23286      }
23287      $currentArticle.find(">.container>ul").css({
23288        transform: "translateX(-" + distance + "px)"
23289      });
23290      $currentArticle.find(">.container>ul .loader").css({
23291        transform: "translateX(" + distance + "px)"
23292      });
23293      if (distance + $currentArticle.innerWidth() > limit) {
23294        $currentArticle.find(".arrows span span.next").addClass("hide");
23295      }
23296      if ($currentArticle.data("scrolled") <= 0) {
23297        $currentArticle.find(".arrows span span.prev").addClass("hide");
23298      }
23299    });
23300  });
23301}
23302function resetFFCarrousel() {
23303  $("#archive_ff .forfait_list article").each(function () {
23304    var limit = 0;
23305    $(this).find(">.container>ul:first-of-type>li").each(function () {
23306      limit += $(this).outerWidth(true);
23307    });
23308    if ($(this).innerWidth() < limit) {
23309      if ($(this).data("scrolled") == 0) {
23310        $(this).find(".arrows span span.next").removeClass("hide");
23311        $(this).find(">.container ul").addClass("carr-ready");
23312      }
23313    } else {
23314      $(this).find(">.container ul").removeClass("carr-ready");
23315      $(this).find(".arrows span span.next").addClass("hide");
23316    }
23317  });
23318}
23319function onScrollCalculArrowForfaits() {
23320  if ($("#archive_ff").length > 0) {
23321    $(".forfait_list .wrapper article").each(function () {
23322      var $forfaitList = $(this),
23323        $forfaitListSpecialOffer = $forfaitList.find(".container .advantages > li > span"),
23324        arrowsTop = parseInt($forfaitList.find(".arrows").offset().top),
23325        forfaitListSpecialOfferHighest = 0; // Hauteur du header
23326
23327      $forfaitListSpecialOffer.each(function (index, element) {
23328        forfaitListSpecialOfferHighest = $(element).outerHeight(true) > forfaitListSpecialOfferHighest ? $(element).outerHeight(true) : forfaitListSpecialOfferHighest;
23329      });
23330      onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest);
23331      $(document).on("scroll", function () {
23332        onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest);
23333      });
23334    });
23335  }
23336}
23337function onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest) {
23338  var someHeightToAdd = parseInt($("body > #heading").height() + forfaitListSpecialOfferHighest / 2),
23339    forfaitListBottom = parseInt($forfaitList.offset().top + $forfaitList.find(".container").outerHeight(true)) + parseFloat($forfaitList.find(".container").css("margin-top")) + parseFloat($forfaitList.find(".container").css("padding-top")),
23340    arrowsTranslate = parseInt($(document).scrollTop()) - (arrowsTop - someHeightToAdd),
23341    newArrowsTop = arrowsTop + arrowsTranslate,
23342    arrowsBottom = parseInt(newArrowsTop + $forfaitList.find(".arrows").height());
23343  if (arrowsTop - someHeightToAdd < $(document).scrollTop() && forfaitListBottom > arrowsBottom) {
23344    $forfaitList.find(".arrows").animate({
23345      top: arrowsTranslate
23346    }, 0);
23347  }
23348}
23349let skipPlanAddPhonePopin = false;
23350let planAddPhonePendingBtn = null;
23351function closePlanAddPhonePopin() {
23352  jquery_default()(".plan-add-phone-popin").remove();
23353  jquery_default()("body").removeClass("stop_scrolling");
23354  planAddPhonePendingBtn = null;
23355  window.planAddPhonePendingBtn = null;
23356}
23357function openPlanAddPhonePopin($sourceBtn) {
23358  const $popinContent = jquery_default()("#plan-add-phone-popin");
23359  if ($popinContent.length === 0) {
23360    return false;
23361  }
23362  planAddPhonePendingBtn = $sourceBtn;
23363  window.planAddPhonePendingBtn = $sourceBtn.get(0);
23364  jquery_default()($popinContent.html()).insertAfter(".footer");
23365  jquery_default()("body").addClass("stop_scrolling");
23366  jquery_default()(document).on("click.planAddPhonePopin", ".plan-add-phone-popin .close", function () {
23367    closePlanAddPhonePopin();
23368  });
23369  return true;
23370}
23371function initPlanAddPhonePopin() {
23372  jquery_default()(document).on("click", "#archive_ff[data-posttype='sfr_forfaits_phone'] .dynamic-formula-btn.nophone:not(.popin_action), #archive_ff[data-posttype='sfr_forfaits_tab'] .dynamic-formula-btn.nophone:not(.popin_action)", function (event) {
23373    if (skipPlanAddPhonePopin || !jquery_default()(this).is("button")) {
23374      return;
23375    }
23376    const {
23377      planName,
23378      planPrice
23379    } = planTracking.getPlanFromElement(jquery_default()(this));
23380    if (planName) {
23381      planTracking.persistPlan(planName, planPrice);
23382    }
23383    if (!openPlanAddPhonePopin(jquery_default()(this))) {
23384      return;
23385    }
23386    event.preventDefault();
23387    event.stopImmediatePropagation();
23388  });
23389  jquery_default()(document).on("click", "[data-plan-tracking=\"modal_continue_without_phone\"]", function () {
23390    if (!planAddPhonePendingBtn) {
23391      return;
23392    }
23393    const $pendingBtn = planAddPhonePendingBtn;
23394    closePlanAddPhonePopin();
23395    window.planTrackingSkipSelectPlan = true;
23396    skipPlanAddPhonePopin = true;
23397    $pendingBtn.trigger("click");
23398    skipPlanAddPhonePopin = false;
23399  });
23400  jquery_default()(document).on("click", "[data-plan-tracking=\"modal_continue_with_phone\"]", function () {
23401    closePlanAddPhonePopin();
23402    const $phoneBtnWith = jquery_default()("#archive_ff .phone_btn_with").first();
23403    if ($phoneBtnWith.length && !$phoneBtnWith.hasClass("active")) {
23404      $phoneBtnWith.trigger("click");
23405    }
23406  });
23407}
23408;// ./wp-content/themes/sfrtheme/assets/js/pagePhone.js
23409
23410jquery_default()(document).ready(function () {
23411  phonePageEventListener();
23412});
23413function phonePageEventListener() {
23414  jquery_default()("#single-phone #phone .phone-description .informations .with_ff .phoneandforfait").click(function (e) {
23415    const link = jquery_default()(this).data('href');
23416    jquery_default().ajax({
23417      url: sfrJSVars.ajaxurl,
23418      method: 'POST',
23419      data: {
23420        'action': 'ajaxToggleAddPhoneToForfait',
23421        'params': {
23422          displayPhone: true
23423        }
23424      },
23425      success: function (data) {
23426        document.location.href = link;
23427      },
23428      error: function (request, error) {
23429        console.log(error);
23430      }
23431    });
23432  });
23433}
23434// EXTERNAL MODULE: ./wp-content/themes/sfrtheme/assets/js/polyfills.js
23435var polyfills = __webpack_require__(58);
23436;// ./wp-content/themes/sfrtheme/assets/js/utils/utils.js
23437const getPositionRelativeToDocument = ({
23438  el,
23439  parent = null,
23440  float = true
23441}) => {
23442  const box = el.getBoundingClientRect();
23443  let boxParent = {};
23444  if (parent) {
23445    boxParent = parent.getBoundingClientRect();
23446  }
23447  const body = document.body;
23448  const docEl = document.documentElement;
23449  const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
23450  const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
23451  const clientTop = boxParent.top || docEl.clientTop || body.clientTop || 0;
23452  const clientLeft = boxParent.left || docEl.clientLeft || body.clientLeft || 0;
23453  let top = box.top + scrollTop - clientTop;
23454  let left = box.left + scrollLeft - clientLeft;
23455  if (!float) {
23456    left = wrap(left, 0, window.outerWidth);
23457    top = wrap(top, 0, window.outerHeight);
23458  }
23459  return {
23460    top,
23461    left
23462  };
23463};
23464const wrap = (num, min, max) => {
23465  return ((num - min) % (max - min) + (max - min)) % (max - min) + min;
23466};
23467;// ./wp-content/themes/sfrtheme/assets/js/Tooltip.js
23468/**
23469 * Permet d'afficher des Tooltips
23470 */
23471
23472
23473class Tooltip {
23474  constructor(element) {
23475    this.element = element;
23476    this.content = element.querySelector('.tooltip-content');
23477    this.isShowed = false;
23478    this.horizontalSpacing = null;
23479    this.classNames = {
23480      show: 'show'
23481    };
23482    this.setListeners();
23483  }
23484
23485  /**
23486   * Permet de définir les events listeners
23487   */
23488  setListeners() {
23489    const {
23490      element
23491    } = this;
23492    element.addEventListener('mouseenter', () => {
23493      this.onMouseEnter();
23494    });
23495    element.addEventListener('mouseleave', () => {
23496      this.onMouseLeave();
23497    });
23498    this.setPosition();
23499    window.addEventListener('resize', () => {
23500      // Obligé de mettre un setTimeout, car on doit attendre le replacement du carrousel pour ne pas avoir
23501      // une position décalée
23502      setTimeout(() => {
23503        this.setPosition();
23504      }, 500);
23505    });
23506  }
23507
23508  /**
23509   * Lorsque la souris entre dans l'élément
23510   */
23511  onMouseEnter() {
23512    this.show();
23513  }
23514
23515  /**
23516   * Lorsque la souris sort de l'élément
23517   */
23518  onMouseLeave() {
23519    this.hide();
23520  }
23521
23522  /**
23523   * Permet de récupérer la position du contenu
23524   */
23525  setPosition() {
23526    const {
23527      element,
23528      content
23529    } = this;
23530    const rec = element.getBoundingClientRect();
23531    // On récupère la position de l'élément dans la fenêtre
23532    const positionRelative = getPositionRelativeToDocument({
23533      el: element,
23534      float: false
23535    });
23536    // On vérifie la place libre
23537    const spacing = positionRelative.left + rec.width;
23538    // Si il n'y a pas suffisamment de place libre
23539    if (content.scrollWidth >= spacing) {
23540      // On ajoute de l'espace
23541      this.horizontalSpacing = content.scrollWidth - spacing + 5;
23542    } else {
23543      this.horizontalSpacing = null;
23544    }
23545  }
23546
23547  /**
23548   * Permet d'afficher l'élément
23549   */
23550  show() {
23551    const {
23552      classNames,
23553      content,
23554      horizontalSpacing,
23555      element
23556    } = this;
23557    this.isShowed = true;
23558    content.style.right = horizontalSpacing ? `-${horizontalSpacing}px` : 0;
23559    element.classList.add(classNames.show);
23560  }
23561
23562  /**
23563   * Permet de cacher l'élément
23564   */
23565  hide() {
23566    const {
23567      classNames,
23568      element
23569    } = this;
23570    this.isShowed = false;
23571    element.classList.remove(classNames.show);
23572  }
23573}
23574;// ./wp-content/themes/sfrtheme/assets/js/datalayer/GtmDatalayer.js
23575
23576let GtmDatalayer_self;
23577class GtmDatalayer {
23578  constructor() {
23579    GtmDatalayer_self = this; // this.pushEvent ne fonctionne pas...
23580  }
23581
23582  /**
23583   * Si on est en development, on voit un console log, sinon on envoie au GTM
23584   * @param {String} e - L'event
23585   * @param {String} c - La catégorie
23586   * @param {String} a - L'action
23587   * @param {String} l - Le label
23588   * @param {Object} v - Variables custom
23589   */
23590  send(event, type, click, click_placement, v = {}) {
23591    const params = {
23592      'event': event,
23593      'type': type,
23594      'click': click,
23595      'click_placement': click_placement,
23596      ...v
23597    };
23598    if (typeof dataLayer !== 'undefined') {
23599      dataLayer.push(params);
23600    }
23601  }
23602
23603  /**
23604   * Au clic sur les éléments fournis en paramètres
23605   * @param elements - Texte du lien
23606   */
23607  handleClicks(elements, type = "navigation", event = "click", placement = "body") {
23608    elements.forEach(element => {
23609      const {
23610        selector,
23611        text,
23612        textSelector
23613      } = element;
23614      const e = element.event ? element.event : event;
23615      const t = element.type ? element.type : type;
23616      const p = element.placement ? element.placement : placement;
23617      const v = element.v ? element.v : {};
23618      $(document).on('click', selector, function () {
23619        GtmDatalayer_self.pushEvent($(this), text, textSelector, e, t, p, v);
23620      });
23621    });
23622  }
23623
23624  /**
23625   * Au clic sur les éléments fournis en paramètres
23626   * @param elements - Texte du lien
23627   */
23628  pushEvent(el, text, textSelector, event, type, placement, v = {}) {
23629    let request = textSelector == 'element' ? el.text() : el.find(textSelector).text();
23630    if (text) {
23631      request = text;
23632    }
23633    this.send(event, type, request, placement, v);
23634  }
23635}
23636/* harmony default export */ const datalayer_GtmDatalayer = (GtmDatalayer);
23637;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/ContactEvents.js
23638
23639const gtmDatalayer = new datalayer_GtmDatalayer();
23640
23641const ContactEvents_elements = [{
23642  selector: ".page-template-formEligibility form button",
23643  textSelector: "element"
23644}];
23645const ContactEvents = () => {
23646  const {
23647    handleClicks
23648  } = gtmDatalayer;
23649  handleClicks(ContactEvents_elements);
23650};
23651jquery_default()(document).on('click', ".bloc_full_page .btn", function () {
23652  const href = jquery_default()(this).attr('href');
23653  const {
23654    hostname
23655  } = new URL(href);
23656  const trackButtons = [{
23657    'domain': 'wa.me',
23658    'click': 'nous_contacter_whatsapp'
23659  }, {
23660    'domain': 'm.me',
23661    'click': 'nous_contacter_facebook'
23662  }];
23663  const button = trackButtons.find(b => b.domain == hostname);
23664  if (button) {
23665    gtmDatalayer.send('click', 'navigation', button.click, 'body');
23666  }
23667});
23668/* harmony default export */ const tracking_ContactEvents = (ContactEvents);
23669;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/EligibiliteEvents.js
23670
23671const EligibiliteEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23672const EligibiliteEvents_elements = [{
23673  selector: ".page-template-eligibility .searchform button",
23674  text: "recherche_adresse"
23675}];
23676const EligibiliteEvents = () => {
23677  const {
23678    handleClicks
23679  } = EligibiliteEvents_gtmDatalayer;
23680  handleClicks(EligibiliteEvents_elements);
23681};
23682/* harmony default export */ const tracking_EligibiliteEvents = (EligibiliteEvents);
23683;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/FooterEvents.js
23684
23685const FooterEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23686const FooterEvents_elements = [{
23687  selector: "#line-footer li a",
23688  textSelector: "element",
23689  placement: "footer"
23690}];
23691const FooterEvents = () => {
23692  const {
23693    handleClicks
23694  } = FooterEvents_gtmDatalayer;
23695  handleClicks(FooterEvents_elements);
23696};
23697/* harmony default export */ const tracking_FooterEvents = (FooterEvents);
23698;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/ForfaitMobileEvents.js
23699
23700const ForfaitMobileEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23701
23702const ForfaitMobileEvents_elements = [{
23703  selector: ".page-template-complement form button",
23704  textSelector: "element"
23705}];
23706const ForfaitMobileEvents = () => {
23707  const {
23708    handleClicks
23709  } = ForfaitMobileEvents_gtmDatalayer;
23710  handleClicks(ForfaitMobileEvents_elements);
23711};
23712const getProductName = $element => {
23713  const $card = $element.closest(".forfait, li");
23714  return $card.find(".title-price .title").first().text().trim() || $card.find("h2 span").first().text().trim();
23715};
23716jquery_default()('.post-type-archive-sfr_forfaits_phone .forfaits_container .advantages > li').each(function () {
23717  const title = jquery_default()(this).find("h2 span").text();
23718  jquery_default()(this).on('click', ".prices li .btn", function () {
23719    ForfaitMobileEvents_gtmDatalayer.send('click', 'navigation', title, 'body', {
23720      'achat_telephone': jquery_default()('.phone_block .phone').hasClass('active') ? 'acheter' : 'ne_pas_acheter',
23721      'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver'
23722    });
23723  });
23724});
23725jquery_default()(document).on('click', ".post-type-archive-sfr_forfaits_phone .forfaits_container .sfr_family li .btn", function () {
23726  ForfaitMobileEvents_gtmDatalayer.send('click', 'navigation', 'sfr_family', 'body', {
23727    'choix_techno': jquery_default()('.forfait_list .filters form ul li input:checked + label').text(),
23728    'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver',
23729    'achat_telephone': jquery_default()('.phone_block .phone').hasClass('active') ? 'acheter' : 'ne_pas_acheter'
23730  });
23731});
23732jquery_default()(document).on("click", ".post-type-archive-sfr_forfaits_phone .forfaits_container .actions .dynamic-formula-btn, .post-type-archive-sfr_forfaits_phone .forfaits_container .actions .btn.primary.red", function () {
23733  const productName = getProductName(jquery_default()(this));
23734  ForfaitMobileEvents_gtmDatalayer.send("click", "navigation", "choisir_ce_forfait", "body", {
23735    produit: productName,
23736    choix_numero: jquery_default()(".phone_block .portabilite").hasClass("active") ? "conserver" : "ne_pas_conserver",
23737    achat_telephone: jquery_default()(".phone_block .phone").hasClass("active") ? "acheter" : "ne_pas_acheter"
23738  });
23739});
23740jquery_default()(document).on("click", ".post-type-archive-sfr_forfaits_phone .forfaits_container .actions .accordion .title", function () {
23741  const productName = getProductName(jquery_default()(this));
23742  ForfaitMobileEvents_gtmDatalayer.send("click", "navigation", "voir_le_detail_de_l_offre", "body", {
23743    produit: productName,
23744    choix_numero: jquery_default()(".phone_block .portabilite").hasClass("active") ? "conserver" : "ne_pas_conserver",
23745    achat_telephone: jquery_default()(".phone_block .phone").hasClass("active") ? "acheter" : "ne_pas_acheter"
23746  });
23747});
23748/* harmony default export */ const tracking_ForfaitMobileEvents = (ForfaitMobileEvents);
23749;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/HomeEvents.js
23750
23751const HomeEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23752
23753const HomeEvents_elements = [{
23754  selector: "#home .short_link a",
23755  textSelector: "p"
23756}, {
23757  selector: ".slide-v2 a",
23758  textSelector: "element"
23759}, {
23760  selector: ".slide a",
23761  textSelector: "element"
23762}, {
23763  selector: "#home .wysiwyg_content a",
23764  textSelector: "element"
23765}];
23766const HomeEvents = () => {
23767  const {
23768    handleClicks
23769  } = HomeEvents_gtmDatalayer;
23770  handleClicks(HomeEvents_elements);
23771};
23772const HomeEvents_getProductName = $element => {
23773  const $card = $element.closest(".forfait, li");
23774  return $card.find(".title-price .title").first().text().trim() || $card.find("h2 span").first().text().trim();
23775};
23776jquery_default()(document).on("click", ".forfaits_container .actions .dynamic-formula-btn, .forfaits_container .actions .btn.primary.red", function () {
23777  if (jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) {
23778    return;
23779  }
23780  const productName = HomeEvents_getProductName(jquery_default()(this));
23781  HomeEvents_gtmDatalayer.send("click", "navigation", "choisir_ce_forfait", "body", {
23782    produit: productName
23783  });
23784});
23785jquery_default()(document).on("click", ".forfaits_container .actions .accordion .title", function () {
23786  if (jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) {
23787    return;
23788  }
23789  const productName = HomeEvents_getProductName(jquery_default()(this));
23790  HomeEvents_gtmDatalayer.send("click", "navigation", "voir_le_detail_de_l_offre", "body", {
23791    produit: productName
23792  });
23793});
23794jquery_default()(document).on("click", ".forfaits_container .switchboxtv", function () {
23795  const productName = HomeEvents_getProductName(jquery_default()(this));
23796  const clickLabel = jquery_default()(this).find(".text").first().text().trim() || jquery_default()(this).text().trim();
23797  HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", {
23798    produit: productName
23799  });
23800});
23801jquery_default()(document).on("click", ".modal-client .client-modal-buttons .client-modal-yes, .modal
23801-client .client-modal-buttons .client-modal-no", function () {
23802  const clickLabel = jquery_default()(this).text().trim();
23803  const modalTitle = jquery_default()(this).closest(".client-modal-step").find("h5").first().text().trim();
23804  HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", {
23805    produit: modalTitle
23806  });
23807});
23808jquery_default()(document).on("click", ".forfaits_container .phone_toggle_buttons .phone_btn", function () {
23809  const clickLabel = jquery_default()(this).text().trim();
23810  const blockTitle = jquery_default()(this).closest(".with-phone").find("h1, h2, h3, h4, h5").first().text().trim();
23811  HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", {
23812    produit: blockTitle
23813  });
23814});
23815jquery_default()(document).on("click", ".forfaits_container .forfait_type_buttons .forfait_type_btn", function () {
23816  const clickLabel = jquery_default()(this).text().trim();
23817  const blockTitle = jquery_default()(this).closest(".forfait-type-filter").find(".forfait-type-title.active h5").first().text().trim() || jquery_default()(this).closest(".forfait-type-filter").find(".forfait-type-title h5").first().text().trim();
23818  HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", {
23819    produit: blockTitle
23820  });
23821});
23822jquery_default()(document).on("click", ".test-eligibility .searchform .btn.primary.button", function () {
23823  const clickLabel = jquery_default()(this).text().trim();
23824  const blockTitle = jquery_default()(this).closest(".test-eligibility").find(".eligibility-step .content h1, .eligibility-step .content .h4").first().text().trim();
23825  HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", {
23826    produit: blockTitle
23827  });
23828});
23829/* harmony default export */ const tracking_HomeEvents = (HomeEvents);
23830;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/MenuEvents.js
23831
23832const MenuEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23833const MenuEvents_elements = [{
23834  selector: "#header li a",
23835  textSelector: "element",
23836  placement: "header"
23837}];
23838const MenuEvents = () => {
23839  const {
23840    handleClicks
23841  } = MenuEvents_gtmDatalayer;
23842  handleClicks(MenuEvents_elements);
23843};
23844/* harmony default export */ const tracking_MenuEvents = (MenuEvents);
23845;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/OffreBoxEvents.js
23846
23847const OffreBoxEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23848
23849const OffreBoxEvents_elements = [{
23850  selector: ".post-type-archive-sfr_forfaits_box .breadcrumbs .right a",
23851  textSelector: "element"
23852}, {
23853  selector: ".post-type-archive-sfr_forfaits_box #forfait_box_type ul li label",
23854  textSelector: "element"
23855}];
23856const OffreBoxEvents = () => {
23857  const {
23858    handleClicks
23859  } = OffreBoxEvents_gtmDatalayer;
23860  handleClicks(OffreBoxEvents_elements);
23861};
23862jquery_default()('.post-type-archive-sfr_forfaits_box .forfaits_container .advantages > li').each(function () {
23863  const title = jquery_default()(this).find("h2 span").text();
23864  jquery_default()(this).on('click', ".prices li .btn", function () {
23865    OffreBoxEvents_gtmDatalayer.send('click', 'navigation', title, 'body', {
23866      'choix_techno': jquery_default()('.forfait_list .filters form ul li input:checked + label').text(),
23867      'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver'
23868    });
23869  });
23870});
23871jquery_default()(document).on('click', "#complement aside .btn_modif", function () {
23872  OffreBoxEvents_gtmDatalayer.send('click', 'navigation', 'modifier_mon_choix_adresse', 'body');
23873});
23874jquery_default()(document).on('click', "#complement section .btn_modif", function () {
23875  OffreBoxEvents_gtmDatalayer.send('click', 'navigation', 'modifier_mon_choix_forfait', 'body');
23876});
23877/* harmony default export */ const tracking_OffreBoxEvents = (OffreBoxEvents);
23878;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/TelephoneEvents.js
23879
23880const TelephoneEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23881
23882const TelephoneEvents_elements = [{
23883  selector: ".single-sfr_phone .bottom .informations .btn",
23884  textSelector: "element"
23885}, {
23886  selector: ".page-template-recapitulatif .price .foot .btn",
23887  textSelector: "element"
23888}];
23889const TelephoneEvents = () => {
23890  const {
23891    handleClicks
23892  } = TelephoneEvents_gtmDatalayer;
23893  handleClicks(TelephoneEvents_elements);
23894};
23895jquery_default()(document).on('click', "#archive_phones .phones .cards li.phone a.btn.primary", function () {
23896  const $card = jquery_default()(this).closest("li.phone");
23897  const productName = $card.find(".phone-title-container .title").first().text().trim();
23898  TelephoneEvents_gtmDatalayer.send('click', 'navigation', jquery_default()(this).text().trim(), 'body', {
23899    'produit': productName
23900  });
23901});
23902jquery_default()(document).on('click', ".page-template-recapitulatif .cards-choices .card-choice:not(.box-tv) .buttons.yes-no .btn", function () {
23903  const $choiceCard = jquery_default()(this).closest(".card-choice");
23904  const choiceTitle = $choiceCard.find("h2").first().text().trim();
23905  TelephoneEvents_gtmDatalayer.send('click', 'navigation', jquery_default()(this).text().trim(), 'body', {
23906    'produit': choiceTitle
23907  });
23908});
23909/* harmony default export */ const tracking_TelephoneEvents = (TelephoneEvents);
23910;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/AdvantageEvents.js
23911
23912const AdvantageEvents_gtmDatalayer = new datalayer_GtmDatalayer();
23913
23914const AdvantageEvents = () => {};
23915jquery_default()('.container .advantages > li').each(function () {
23916  const title = jquery_default()(this).find("h2 span").text();
23917  jquery_default()(this).on('click', ".accordion .title", function () {
23918    if (jquery_default()(this).closest("#home").length || jquery_default()("body").hasClass("home") || jquery_default()(this).closest("#archive_ff[data-posttype='sfr_forfaits_phone']").length || jquery_default()(this).closest("#archive_ff[data-posttype='sfr_forfaits_tab']").length || jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) {
23919      return;
23920    }
23921    if (jquery_default()(this).hasClass('open')) {
23922      AdvantageEvents_gtmDatalayer.send('click', 'action', jquery_default()(this).text(), 'body', {
23923        'produit': title
23924      });
23925    }
23926  });
23927});
23928/* harmony default export */ const tracking_AdvantageEvents = (AdvantageEvents);
23929;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/AddOnTracking.js
23930
23931const AddOnTracking = () => {};
23932jquery_default()(".page-template-recapitulatif .price .foot .btn.print").click(function () {
23933  if (sfrJSVars.themeName == 'sfrtheme') {
23934    dataLayer.push({
23935      event: "print",
23936      conversionId: sfrJSVars.datalayerConversionId,
23937      conversionLabel: "PuXrCKHf-L8ZEIzegpsD"
23938    });
23939  }
23940});
23941jquery_default()(".post-type-archive-sfr_forfaits_phone .forfaits_blocs .prices .btn.primary.red.eligibility_btn").click(function () {
23942  if (sfrJSVars.themeName == 'sfrtheme') {
23943    dataLayer.push({
23944      event: "eligibility_test",
23945      conversionId: sfrJSVars.datalayerConversionId,
23946      conversionLabel: "VcgOCN6rkKUCEIzegpsD"
23947    });
23948  }
23949});
23950jquery_default()(".page-template-client .block_link.not_client .btn").click(function () {
23951  if (sfrJSVars.themeName == 'sfrtheme') {
23952    dataLayer.push({
23953      event: "subscribe_plan_new_customer",
23954      conversionId: sfrJSVars.datalayerConversionId,
23955      conversionLabel: "hEH3CJPztqUCEIzegpsD"
23956    });
23957  }
23958});
23959jquery_default()(".single-sfr_phone .validate .btn.primary.phone_alone").click(function () {
23960  dataLayer.push({
23961    event: "add_to_cart_only_phone",
23962    conversionId: sfrJSVars.datalayerConversionId,
23963    conversionLabel: sfrJSVars.themeName == 'sfrtheme' ? "8utlCICf_L8ZEIzegpsD" : "VcgOCN6rkKUCEIzegpsD"
23964  });
23965});
23966jquery_default()("#sur-footer .wrapper > ul > li:nth-of-type(2) a").click(function () {
23967  if (sfrJSVars.themeName == 'sfrtheme') {
23968    dataLayer.push({
23969      event: "meet_in_store",
23970      conversionId: sfrJSVars.datalayerConversionId,
23971      conversionLabel: "EJqtCNeft6UCEIzegpsD"
23972    });
23973  }
23974});
23975jquery_default()('main#edito a[data-datalayer="meet_in_store"]').click(function () {
23976  if (sfrJSVars.themeName == 'sfrtheme') {
23977    dataLayer.push({
23978      event: "meet_in_store",
23979      conversionId: sfrJSVars.datalayerConversionId,
23980      conversionLabel: "EJqtCNeft6UCEIzegpsD"
23981    });
23982  }
23983});
23984/* harmony default export */ const tracking_AddOnTracking = (AddOnTracking);
23985;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/PlanAdsEvents.js
23986
23987
23988const FORFAIT_SELECTOR = '#archive_ff[data-posttype="sfr_forfaits_phone"], #archive_ff[data-posttype="sfr_forfaits_tab"]';
23989const getRecapPlan = () => {
23990  const $recap = jquery_default()('#recapitulatif');
23991  if ($recap.length) {
23992    const planName = $recap.attr('data-plan-name') || '';
23993    const planPrice = parseFloat($recap.attr('data-plan-price'));
23994    if (planName) {
23995      return {
23996        planName: String(planName).trim(),
23997        planPrice: Number.isNaN(planPrice) ? 0 : planPrice
23998      };
23999    }
24000  }
24001  const stored = planTracking.loadPlan();
24002  if (stored?.planName) {
24003    return stored;
24004  }
24005  return null;
24006};
24007const initRecapPlanTracking = () => {
24008  const plan = getRecapPlan();
24009  if (!plan?.planName) {
24010    return;
24011  }
24012  planTracking.persistPlan(plan.planName, plan.planPrice);
24013};
24014const pushSelectPlan = $button => {
24015  if (window.planTrackingSkipSelectPlan) {
24016    window.planTrackingSkipSelectPlan = false;
24017    return;
24018  }
24019  const {
24020    planName,
24021    planPrice
24022  } = planTracking.getPlanFromElement($button);
24023  if (!planName) {
24024    return;
24025  }
24026  planTracking.pushPlanEvent('select_plan', planName, planPrice);
24027};
24028const pushModalPlanEvent = eventName => {
24029  const pendingBtn = window.planAddPhonePendingBtn ? jquery_default()(window.planAddPhonePendingBtn) : null;
24030  const storedPlan = planTracking.loadPlan();
24031  const plan = storedPlan?.planName ? storedPlan : pendingBtn ? planTracking.getPlanFromElement(pendingBtn) : null;
24032  if (!plan?.planName) {
24033    return;
24034  }
24035  planTracking.pushPlanEvent(eventName, plan.planName, plan.planPrice);
24036};
24037const PlanAdsEvents = () => {
24038  initRecapPlanTracking();
24039  jquery_default()(document).on('click', `${FORFAIT_SELECTOR} .actions .dynamic-formula-btn:not(.popin_action)`, function () {
24040    if (!jquery_default()(this).is('button, a')) {
24041      return;
24042    }
24043    pushSelectPlan(jquery_default()(this));
24044  });
24045  jquery_default()(document).on('click', `${FORFAIT_SELECTOR} .prices li .btn`, function () {
24046    pushSelectPlan(jquery_default()(this));
24047  });
24048  jquery_default()(document).on('click', '#recapitulatif .payment_flow_btn, #documents-modal .payment_flow_btn', function () {
24049    const plan = getRecapPlan();
24050    if (!plan?.planName) {
24051      return;
24052    }
24053    planTracking.pushPlanEvent('plan_summary_validation', plan.planName, plan.planPrice);
24054  });
24055  jquery_default()(document).on('click', '[data-plan-tracking="modal_continue_without_phone"]', function () {
24056    pushModalPlanEvent('modal_continue_without_phone');
24057  });
24058  jquery_default()(document).on('click', '[data-plan-tracking="modal_continue_with_phone"]', function () {
24059    pushModalPlanEvent('modal_continue_with_phone');
24060  });
24061};
24062/* harmony default export */ const tracking_PlanAdsEvents = (PlanAdsEvents);
24063;// ./wp-content/themes/sfrtheme/assets/js/datalayer/Tracking.js
24064
24065
24066
24067
24068
24069
24070
24071
24072
24073
24074
24075const Tracking = () => {
24076  tracking_ContactEvents();
24077  tracking_EligibiliteEvents();
24078  tracking_FooterEvents();
24079  tracking_ForfaitMobileEvents();
24080  tracking_HomeEvents();
24081  tracking_MenuEvents();
24082  tracking_OffreBoxEvents();
24083  tracking_TelephoneEvents();
24084  tracking_AdvantageEvents();
24085  tracking_PlanAdsEvents();
24086  tracking_AddOnTracking();
24087};
24088/* harmony default export */ const datalayer_Tracking = (Tracking);
24089;// ./wp-content/themes/sfrtheme/assets/js/carrousel.js
24090if (navigator.userAgent.indexOf("Chrome") != -1 || navigator.userAgent.indexOf("Safari") != -1 || navigator.userAgent.indexOf("AppleWebKit") != -1) {
24091  var transitEndEv = "webkitTransitionEnd";
24092} else {
24093  var transitEndEv = "transitionend";
24094}
24095
24096//Gère les carrousels
24097const carrouselInit = Cookie => {
24098  if ($('html').hasClass('ie11')) {
24099    $('html').find('.carrousel_container').addClass('noloop');
24100    $('.carrousel_container .carrousel .container .el_carr').each(function () {
24101      $(this).css({
24102        'min-width': $(this).find('.slide').innerWidth() + 'px'
24103      });
24104    });
24105  }
24106  checkCarrouselSize();
24107  $('html').find('.carrousel_container.is_sliding').each(function () {
24108    if (!$(this).hasClass('noloop')) {
24109      var carrousel = this,
24110        width = $(carrousel).find('.container .el_carr').innerWidth() * -1,
24111        limit = $(carrousel).find('.container .el_carr').length - 1,
24112        positions = [0, limit + 1],
24113        by = $(carrousel).data('by'),
24114        xStart = 0;
24115      $(carrousel).find('.container').addClass('container_0');
24116      $(carrousel).find('.carrousel').append('<div class="container container_1" style="position:absolute; opacity:1; visibility:visible; z-index:-1; transform:translateX(' + positions[1] * width + 'px)">' + $(carrousel).find('.container').html() + '</div>');
24117      $(carrousel).off('mousedown touchstart');
24118      $(carrousel).on({
24119        'mousedown touchstart': function (ev) {
24120          xStart = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX;
24121        }
24122      });
24123      $(carrousel).off('mouseup touchend');
24124      $(carrousel).on({
24125        'mouseup touchend': function (ev) {
24126          var pageX = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX,
24127            // On check si on est en mobile ou en desktop
24128            deltaX = parseInt(pageX) - parseInt(xStart),
24129            // On regarde la différence de position entre le début du click et la fin du click
24130            opa = Math.abs(Math.abs(deltaX) / 100 + 0.2); // On fait un calcul permettant de savoir si on va à gauche ou à droite
24131          if (opa >= 1 && deltaX > 0.1) {
24132            carrouselGoPrev(carrousel, limit, positions, by);
24133          } else if (opa >= 1 && deltaX < 0.1) {
24134            carrouselGoNext(carrousel, limit, positions, by);
24135          }
24136        }
24137      });
24138      $(this).parent().find('.prev').off('click');
24139      $(this).parent().find('.prev').on('click', function () {
24140        carrouselGoPrev(carrousel, limit, positions, by);
24141      });
24142      $(this).parent().find('.next').off('click');
24143      $(this).parent().find('.next').on('click', function () {
24144        carrouselGoNext(carrousel, limit, positions, by);
24145      });
24146    } else {
24147      var carrousel = this,
24148        position = [0],
24149        xStart = 0;
24150      $(carrousel).find('.prev').addClass('hide');
24151      $(carrousel).off('mousedown touchstart');
24152      $(carrousel).on({
24153        'mousedown touchstart': function (ev) {
24154          xStart = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX;
24155        }
24156      });
24157      $(carrousel).off('mouseup touchend');
24158      $(carrousel).on({
24159        'mouseup touchend': function (ev) {
24160          var pageX = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX,
24161            // On check si on est en mobile ou en desktop
24162            deltaX = parseInt(pageX) - parseInt(xStart),
24163            // On regarde la différence de position entre le début du click et la fin du click
24164            opa = Math.abs(Math.abs(deltaX) / 100 + 0.2); // On fait un calcul permettant de savoir si on va à gauche ou à droite
24165          if (opa >= 1 && deltaX > 0.1) {
24166            carrouselNoLoopGoPrev(carrousel, position);
24167          } else if (opa >= 1 && deltaX < 0.1) {
24168            carrouselNoLoopGoNext(carrousel, position);
24169          }
24170        }
24171      });
24172      $(this).parent().find('.prev').off('click');
24173      $(this).parent().find('.prev').on('click', function () {
24174        carrouselNoLoopGoPrev(carrousel, position);
24175      });
24176      $(this).parent().find('.next').off('click');
24177      $(this).parent().find('.next').on('click', function () {
24178        carrouselNoLoopGoNext(carrousel, position);
24179      });
24180    }
24181    window.addEventListener('resize', () => {
24182      carrousel_onResize(carrousel, positions);
24183    });
24184  });
24185};
24186/* harmony default export */ const carrousel = (carrouselInit);
24187function checkCarrouselSize() {
24188  $('html').find('.carrousel_container').each(function () {
24189    if (!$(this).hasClass('phone-images')) {
24190      if (!$(this).hasClass('is_sliding') && $(this).find('.carrousel .container').innerWidth() > $(this).innerWidth()) {
24191        $(this).addClass('is_sliding');
24192      } else if ($(this).hasClass('is_sliding') && $(this).find('.carrousel .container').innerWidth() <= $(this).innerWidth()) {
24193        $(this).removeClass('is_sliding');
24194      }
24195    }
24196  });
24197}
24198function carrouselNoLoopGoNext(carrousel, position) {
24199  if (!$(carrousel).hasClass('busy')) {
24200    $(carrousel).addClass('busy');
24201    let totalWidth = $(carrousel).find('.container').innerWidth();
24202    let visible = $(carrousel).innerWidth();
24203    let gap = 0;
24204    let moveBy = 0;
24205    for (let i = 0; i <= position[0]; i++) {
24206      if (i != position[0]) {
24207        gap += $(carrousel).find('.container .el_carr:nth-child(' + (i + 1) + ')').innerWidth();
24208      }
24209      moveBy += $(carrousel).find('.container .el_carr:nth-child(' + (i + 1) + ')').innerWidth();
24210    }
24211    if (totalWidth - gap > visible) {
24212      $(carrousel).find('.container').css({
24213        'transform': 'translateX(' + moveBy * -1 + 'px)'
24214      });
24215      position[0]++;
24216      $(carrousel).find('.container').one(transitEndEv, function () {
24217        if ($('html').hasClass('ie11')) {
24218          totalWidth = totalWidth - moveBy / visible * 15;
24219        }
24220        if (totalWidth - moveBy < visible) {
24221          $(carrousel).find('.next').addClass('hide');
24222        }
24223        if (position[0] > 0) {
24224          $(carrousel).find('.prev').removeClass('hide');
24225        }
24226        $(carrousel).removeClass('busy');
24227      });
24228    } else {
24229      $(carrousel).removeClass('busy');
24230    }
24231  }
24232}
24233function carrouselNoLoopGoPrev(carrousel, position) {
24234  if (!$(carrousel).hasClass('busy')) {
24235    $(carrousel).addClass('busy');
24236    var width = $(carrousel).find('.container .el_carr').innerWidth() * -1,
24237      limit = ($(carrousel).find('.container').innerWidth() - $(carrousel).innerWidth()) * -1;
24238    if (position[0] > 0) {
24239      position[0]--;
24240      $(carrousel).find('.container').css({
24241        'transform': 'translateX(' + position[0] * width + 'px)'
24242      });
24243      $(carrousel).find('.container').one(transitEndEv, function () {
24244        if (position[0] * width > limit) {
24245          $(carrousel).find('.next').removeClass('hide');
24246        }
24247        if (position[0] <= 0) {
24248          $(carrousel).find('.prev').addClass('hide');
24249        }
24250        $(carrousel).find('.container').css({
24251          'z-index': '1',
24252          'opacity': '1'
24253        });
24254        $(carrousel).removeClass('busy');
24255      });
24256    } else {
24257      $(carrousel).removeClass('busy');
24258    }
24259  }
24260}
24261function carrouselGoPrev(carrousel, limit, positions, by) {
24262  if (!$(carrousel).hasClass('busy')) {
24263    $(carrousel).addClass('busy');
24264    var width = $(carrousel).find('.container .el_carr').innerWidth() * -1;
24265    positions[0]--;
24266    positions[1]--;
24267    if (positions[0] < -by) {
24268      $(carrousel).find('.container_0').css({
24269        'z-index': '-1',
24270        'opacity': '0'
24271      });
24272      positions[0] = limit + positions[1] + 1;
24273    }
24274    if (positions[1] < -by) {
24275      $(carrousel).find('.container_1').css({
24276        'z-index': '-1',
24277        'opacity': '0'
24278      });
24279      positions[1] = limit + positions[0] + 1;
24280    }
24281    $(carrousel).find('.container_0').css({
24282      'transform': 'translateX(' + positions[0] * width + 'px)'
24283    });
24284    $(carrousel).find('.container_1').css({
24285      'transform': 'translateX(' + positions[1] * width + 'px)'
24286    });
24287    $(carrousel).find('.container_0').one(transitEndEv, function () {
24288      $(carrousel).find('.container_0').css({
24289        'z-index': '1',
24290        'opacity': '1'
24291      });
24292      $(carrousel).removeClass('busy');
24293    });
24294    $(carrousel).find('.container_1').one(transitEndEv, function () {
24295      $(carrousel).find('.container_1').css({
24296        'z-index': '1',
24297        'opacity': '1'
24298      });
24299      $(carrousel).removeClass('busy');
24300    });
24301  }
24302}
24303function carrouselGoNext(carrousel, limit, positions) {
24304  if (!$(carrousel).hasClass('busy')) {
24305    $(carrousel).addClass('busy');
24306    var width = $(carrousel).find('.container .el_carr').innerWidth() * -1;
24307    positions[0]++;
24308    positions[1]++;
24309    if (positions[0] > limit + 1) {
24310      $(carrousel).find('.container_0').css({
24311        'z-index': '-1',
24312        'opacity': '0'
24313      });
24314      positions[0] = -(limit - positions[1] + 1);
24315    }
24316    if (positions[1] > limit + 1) {
24317      $(carrousel).find('.container_1').css({
24318        'z-index': '-1',
24319        'opacity': '0'
24320      });
24321      positions[1] = -(limit - positions[0] + 1);
24322    }
24323    $(carrousel).find('.container_0').css({
24324      'transform': 'translateX(' + positions[0] * width + 'px)'
24325    });
24326    $(carrousel).find('.container_1').css({
24327      'transform': 'translateX(' + positions[1] * width + 'px)'
24328    });
24329    $(carrousel).find('.container_0').one(transitEndEv, function () {
24330      $(carrousel).find('.container_0').css({
24331        'z-index': '1',
24332        'opacity': '1'
24333      });
24334      $(carrousel).removeClass('busy');
24335    });
24336    $(carrousel).find('.container_1').one(transitEndEv, function () {
24337      $(carrousel).find('.container_1').css({
24338        'z-index': '1',
24339        'opacity': '1'
24340      });
24341      $(carrousel).removeClass('busy');
24342    });
24343  }
24344}
24345function carrousel_onResize(carrousel, positions) {
24346  carrousel.classList.add('no-transition');
24347  var width = $(carrousel).find('.container .el_carr').innerWidth() * -1;
24348  $(carrousel).find('.container_0').css({
24349    'transform': 'translateX(' + positions[0] * width + 'px)'
24350  });
24351  $(carrousel).find('.container_1').css({
24352    'transform': 'translateX(' + positions[1] * width + 'px)'
24353  });
24354  carrousel.classList.remove('no-transition');
24355}
24356;// ./wp-content/themes/sfrtheme/assets/js/cookies.js
24357const Cookie = {
24358  read: function (name) {
24359    var data,
24360      result = "null";
24361    var cookie = document.cookie.split("; ");
24362    for (const i in cookie) {
24363      data = cookie[i].split("=");
24364      if (name == data[0]) {
24365        result = data[1];
24366        break;
24367      }
24368    }
24369    return result;
24370  },
24371  write: function (name, value, days) {
24372    var cookie;
24373    if (days == null) {
24374      cookie = name + "=" + value + "; domain=" + location.hostname.split('.').reverse()[1] + "." + location.hostname.split('.').reverse()[0] + ";" + sfrJSVars.cookiesConfig;
24375    } else {
24376      var date = new Date().getTime() + 1000 * 3600 * 24 * days;
24377      var expires = new Date(date).toUTCString();
24378      cookie = name + "=" + value + "; expires=" + expires + "; domain=" + location.hostname.split('.').reverse()[1] + "." + location.hostname.split('.').reverse()[0] + ";" + sfrJSVars.cookiesConfig;
24379    }
24380    document.cookie = cookie;
24381  }
24382};
24383/* harmony default export */ const cookies = (Cookie);
24384;// ./wp-content/themes/sfrtheme/assets/js/webCallback.js
24385function webCallback() {
24386  let scrollY = 0;
24387  $('.webcallback').click(function () {
24388    //document.body.style.position = 'fixed';
24389    openPopin();
24390  });
24391  function openPopin() {
24392    $('.webcallback').after(`<div class="popwebcallback"><div><iframe class="" src="${webCallbackVars.popinUrl}"></iframe><div class="close"></div></<div></div>`);
24393    disableScroll();
24394    addCloseEvents();
24395  }
24396  function disableScroll() {
24397    $("body").addClass('stop_listening');
24398    scrollY = window.scrollY;
24399    document.body.style.top = `-${scrollY}px`;
24400    document.body.style.position = 'fixed';
24401  }
24402  function enableScroll() {
24403    console.log(scrollY);
24404    document.body.style.position = '';
24405    document.body.style.top = '';
24406    window.scrollTo(0, scrollY);
24407    $("body").removeClass('stop_listening');
24408  }
24409  function addCloseEvents() {
24410    document.addEventListener('keydown', e => {
24411      if (e.key === "Escape") {
24412        closePopin();
24413      }
24414    });
24415    $('.popwebcallback').click(function () {
24416      closePopin();
24417    });
24418  }
24419  function closePopin() {
24420    $('.popwebcallback').remove();
24421    enableScroll();
24422  }
24423}
24424;// ./wp-content/themes/sfrtheme/assets/js/localePopin.js
24425/**
24426 * Locale Popin JavaScript
24427 * Loads the locale selection popup via AJAX and displays it after page load
24428 */
24429
24430/**
24431 * Load the popin content via AJAX
24432 * @returns {Promise} jQuery AJAX promise
24433 */
24434function loadLocalePopinContent() {
24435  return $.ajax({
24436    url: window.sfrJSVars.ajaxurl,
24437    type: "POST",
24438    dataType: "json",
24439    data: {
24440      action: "get_locale_popin",
24441      nonce: window.sfrJSVars.localePopin.nonce
24442    }
24443  }).always(function () {
24444    // Enlever la classe page-loading pour afficher la page
24445    $("html").removeClass("page-loading");
24446  });
24447}
24448
24449/**
24450 * Create the popin container if it doesn't exist
24451 * @returns {jQuery} The popin container jQuery element
24452 */
24453function createPopinContainer() {
24454  if ($("#locale-popin-container").length === 0) {
24455    $("body").append('<div id="locale-popin-container" style="display:none;"></div>');
24456  }
24457  return $("#locale-popin-container");
24458}
24459
24460/**
24461 * Display the popin with animation
24462 * @param {jQuery} $container - The container element
24463 * @param {string} html - The HTML content to display
24464 */
24465function displayPopin($container, html) {
24466  // Add the HTML to the container
24467  $container.html(html);
24468
24469  // Apply styles for fullscreen overlay
24470  $container.css({
24471    position: "fixed",
24472    top: "0",
24473    left: "0",
24474    width: "100%",
24475    height: "100%",
24476    "background-color": "rgba(0, 0, 0, 0.8)",
24477    "z-index": "9999",
24478    display: "flex",
24479    "justify-content": "center",
24480    "align-items": "center",
24481    opacity: "0",
24482    transition: "opacity 0.3s ease-in-out"
24483  });
24484
24485  // Show the container with fade-in effect
24486  $container.show().css("opacity", "1");
24487
24488  // Make sure the body doesn't scroll while popin is open
24489  $("body").css("overflow", "hidden");
24490
24491  // Ajouter les gestionnaires d'événements pour les boutons de sélection de locale
24492  $container.find(".locale-select-btn").on("click", function () {
24493    var locale = $(this).data("locale");
24494    setLocaleAndReload(locale);
24495  });
24496}
24497
24498/**
24499 * Initialize the locale popin functionality
24500 */
24501/**
24502 * Set the locale cookie and reload the page
24503 * @param {string} locale - The locale to set (mtq, gpe, guy)
24504 */
24505function setLocaleAndReload(locale) {
24506  // Définir le cookie avec une durée de vie d'un an
24507  var expiryDate = new Date();
24508  expiryDate.setTime(expiryDate.getTime() + 365 * 24 * 60 * 60 * 1000);
24509  document.cookie = "locale=" + locale + "; expires=" + expiryDate.toUTCString() + "; path=/";
24510
24511  // Recharger la page courante
24512  window.location.reload();
24513}
24514function initLocalePopin() {
24515  // Only proceed if the localePopin data is available in sfrJSVars
24516  if (typeof window.sfrJSVars === "undefined") {
24517    return;
24518  }
24519  if (typeof window.sfrJSVars.localePopin === "undefined") {
24520    return;
24521  }
24522  if (!window.sfrJSVars.localePopin.enabled) {
24523    return;
24524  }
24525  var $container = createPopinContainer();
24526  console.log("hello");
24527  loadLocalePopinContent().done(function (response) {
24528    if (response.success && response.data.html) {
24529      displayPopin($container, response.data.html);
24530    }
24531  }).fail(function (xhr) {
24532    console.error("Failed to load locale popin:", xhr);
24533  });
24534}
24535;// ./wp-content/themes/sfrtheme/assets/js/functions.js
24536__webpack_require__(127);
24537
24538
24539
24540
24541
24542
24543/* OLD ELIGIBILITY */
24544
24545
24546
24547
24548
24549
24550
24551
24552
24553
24554
24555
24556
24557window.jQuery = (jquery_default());
24558window.$ = (jquery_default());
24559const appVersion =  true ? "1.0.0" : 0;
24560const buildTime =  true ? "2026-09-02T09:33:42.948Z" : 0;
24561console.log(`%cSFR Caraïbe — build v${appVersion} (${buildTime})`, "color:#e30a0a;font-weight:bold;");
24562
24563/* END OLD ELIGIBILITY */
24564
24565var loadAnalytics = false;
24566if (cookies.read("cookieconsent_status") == "null") {
24567  loadAnalytics = true;
24568}
24569/* Au chargement de la page */
24570$(document).ready(function () {
24571  $("html").removeClass("page-loading");
24572  selectCountryLocation();
24573  footerSubMenuSlide();
24574  allDropdownSlide();
24575  filterPhonesList();
24576  menuHamburger();
24577  changePhoneVariant();
24578  initLocalePopin(); // Initialize the locale popin
24579  pageChannel();
24580  ajaxPortabilite();
24581  pageComplement();
24582  channelGoTop();
24583  functions_cookies();
24584  carrousel();
24585  datalayer_Tracking();
24586  webCallback();
24587  initEnergyClassModal();
24588  initForfaitTypePopin();
24589  if (typeof sfrJSVars.headbandSpeed !== "undefined" && typeof sfrJSVars.headbandSpeed.time !== "undefined" && sfrJSVars.headbandSpeed.time) {
24590    headBand();
24591  }
24592  new LazyLoad("lazy", 0);
24593  functions_initTooltips();
24594
24595  /*$( ".carrousel_container.is_sliding" ).each(function() {
24596        new Carrousel($( this ), {
24597            auto: false,
24598            puces: false
24599        }).init()
24600    });*/
24601});
24602
24603/* A la fin du chargement de la page */
24604$(window).on("load", function () {
24605  headerSticky();
24606  //carrouselInit();
24607  //new LazyLoad('lazy', 0);
24608});
24609
24610/* Au resize du navigateur */
24611$(window).resize(function () {
24612  if (typeof sfrJSVars.headbandSpeed !== "undefined" && typeof sfrJSVars.headbandSpeed.time !== "undefined" && sfrJSVars.headbandSpeed.time) {
24613    headBand();
24614  }
24615});
24616
24617/* Au scroll */
24618$(window).scroll(function () {
24619  headerSticky();
24620  channelGoTop();
24621});
24622
24623/* Gère la redirection en fonction du pays choisis. */
24624function selectCountryLocation() {
24625  $("#zone-geographique").on("change", function () {
24626    document.location.href = $(this).val();
24627  });
24628}
24629
24630/* Gère le dropdown dans le footer. */
24631function footerSubMenuSlide() {
24632  if ($(window).width() <= 540) {
24633    $(".footer").find(".sub-menu").css("display", "none");
24634    $("#column-footer > li").click(function () {
24635      $(this).find(".sub-menu").slideToggle("fast");
24636    });
24637  } else {
24638    $(".footer").find(".sub-menu").css("display", "block");
24639  }
24640}
24641
24642/* Gère les dropdowns du site */
24643function allDropdownSlide() {
24644  $(".toggle-dropdown .active_toggle_event").unbind().on("click", function () {
24645    if ($(this).closest(".toggle-dropdown").hasClass("opened")) {
24646      $(this).closest(".toggle-dropdown").removeClass("opened").find(".accordeon").slide
24646Up();
24647    } else {
24648      $(this).closest(".toggle-dropdown").addClass("opened").find(".accordeon").slideDown();
24649    }
24650  });
24651}
24652
24653/* Helper function to initialize tooltips */
24654function functions_initTooltips() {
24655  const tooltips = document.querySelectorAll(".tooltip");
24656  tooltips.forEach(el => {
24657    // Éviter de réinitialiser un tooltip déjà initialisé
24658    if (!el.classList.contains("tooltip-initialized")) {
24659      new Tooltip(el);
24660      el.classList.add("tooltip-initialized");
24661    }
24662  });
24663}
24664
24665// Rendre la fonction accessible globalement pour les autres modules
24666window.initTooltips = functions_initTooltips;
24667function filterPhonesList() {
24668  $(".phones-list .filters select, .phones-list .filters input, .phones-list .filters select").on("change", function () {
24669    ajaxListPhones($(this));
24670  });
24671  $("#archive_phones .phones-list .filters .reset").click(function () {
24672    var $filters = $(this).parents(".filters");
24673    $filters.find(".form-group select").each(function () {
24674      $(this).find("option:eq(0)").prop("selected", true);
24675    });
24676    $filters.find(".form-group-checkbox input").each(function () {
24677      $(this).prop("checked", false);
24678    });
24679    ajaxListPhones($(this));
24680  });
24681}
24682function ajaxListPhones(current) {
24683  const $phones = current.parents(".phones-list").find(".phones");
24684  $phones.addClass("loading");
24685  var params = {};
24686
24687  // Only collect filter selects (brands and techno), exclude sort
24688  $.each(current.parents(".filters").find("select:not(#sort)"), function (index, element) {
24689    params[index] = {
24690      term: $(element).attr("id"),
24691      val: $(element).val()
24692    };
24693    if ($(element).val() == "all") {
24694      $(element).find("option").removeAttr("selected");
24695      $(element).find("option:first-of-type").attr("selected", "selected");
24696    }
24697  });
24698
24699  // Check if promos checkbox exists before trying to read it
24700  var promosChecked = $("#promos").length > 0 ? $("#promos").is(":checked") : false;
24701  $.ajax({
24702    url: sfrJSVars.ajaxurl,
24703    // Wordpress ajax
24704    method: "POST",
24705    data: {
24706      action: "displayFilterPhones",
24707      params: params,
24708      pageID: $("#archive_phones").data("id"),
24709      type: $("#archive_phones").data("type"),
24710      sort: $("#sort").val() || "news",
24711      promos: promosChecked
24712    },
24713    success: function (data) {
24714      //console.log(data);
24715      $phones.find(".wrapper .cards").html($(data).filter("li"));
24716      var $breadCrumbs = $(".breadcrumbs");
24717      var $countResult = $breadCrumbs.find(".wrapper .count-result");
24718      var phrase = $(data).filter("li:not(.no_result)").length === 0 || $(data).filter("li:not(.no_result)").length === 1 ? $(data).filter("li:not(.no_result)").length + " " + $countResult.data("singular") : $(data).filter("li:not(.no_result)").length + " " + $countResult.data("plural");
24719      $breadCrumbs.find(".wrapper .count-result").text(phrase);
24720      $phones.removeClass("loading");
24721      new LazyLoad("lazy", 0);
24722      functions_initTooltips(); // Réinitialiser les tooltips après le rechargement AJAX
24723    },
24724    error: function (request, error) {
24725      console.log(error);
24726    }
24727  });
24728}
24729
24730/* JS pour la page liste chaînes */
24731function pageChannel() {
24732  //Init Filters
24733  if ($("#archive_channel").get(0)) {
24734    let dataFF = $("#archive_channel .filters ul.filters-cat li button.selected").data("ff") ?? "";
24735    let searchForForfaits = dataFF.split(",").slice(0, dataFF.split(",").length - 1);
24736    $("#archive_channel .filters").find(".filters-techno li button").each(function () {
24737      let availableForfaits = $(this).data("ff").split(",").slice(0, $(this).data("ff").split(",").length - 1);
24738    });
24739  }
24740
24741  //Filters
24742  $("#archive_channel .channel-filters ul li button").click(function () {
24743    if (!$(this).hasClass("unavailable")) {
24744      if (!$(this).parents("ul").hasClass("type")) {
24745        $(this).parents("ul").find("li button").removeClass("selected");
24746        $(this).addClass("selected");
24747        let ffVisible = [];
24748        let ffAvailable = [];
24749        let ffData = [];
24750        $(this).parents("ul").parent().find(".filters-techno li button").each(function () {
24751          if ($(this).hasClass("selected")) {
24752            // S'assurer que data('ff') existe et est une chaîne avant d'appeler split()
24753            let dataFF = $(this).data("ff") || "";
24754            ffVisible = typeof dataFF === "string" ? dataFF.split(",").slice(0, dataFF.split(",").length - 1) : [];
24755          }
24756        });
24757
24758        // S'assurer que ffVisible est un tableau
24759        ffVisible = Array.isArray(ffVisible) ? ffVisible : [];
24760        $(this).parents("ul").parent().find(".filters-cat li button").each(function () {
24761          // S'assurer que data('ff') existe et est une chaîne avant d'appeler split()
24762          let buttonDataFF = $(this).data("ff") || "";
24763          let buttonFFArray = typeof buttonDataFF === "string" ? buttonDataFF.split(",").slice(0, buttonDataFF.split(",").length - 1) : [];
24764          let isAvailable = buttonFFArray.filter(function (n) {
24765            return ffVisible.indexOf(n) !== -1;
24766          });
24767          if (isAvailable.length < 1) {
24768            $(this).addClass("unavailable").removeClass("selected");
24769          } else {
24770            $(this).removeClass("unavailable");
24771            if (!$(this).parents("ul").parent().find(".filters-cat li button.selected").get(0)) {
24772              $(this).addClass("selected");
24773            }
24774          }
24775          if ($(this).hasClass("selected")) {
24776            ffAvailable = Array.isArray(isAvailable) ? isAvailable : [];
24777          }
24778          let data = {
24779            text: $(this).data("availabletext"),
24780            color: $(this).data("color")
24781          };
24782
24783          // Utiliser les variables déjà déclarées
24784          $.each(buttonFFArray, function (index, value) {
24785            ffData[value] = data;
24786          });
24787        });
24788        $("#archive_channel .channel_list ul li").each(function () {
24789          // S'assurer que data('ff') existe et est une chaîne avant d'appeler split()
24790          let liDataFF = $(this).data("ff") || "";
24791          let liFFArray = typeof liDataFF === "string" ? liDataFF.split(",").slice(0, liDataFF.split(",").length - 1) : [];
24792          let isVisible = liFFArray.filter(function (n) {
24793            return ffVisible.indexOf(n) !== -1;
24794          });
24795          if (isVisible.length < 1) {
24796            $(this).removeClass("visible");
24797          } else {
24798            $(this).addClass("visible");
24799            $(this).css({
24800              "border-color": ffData[isVisible[0]].color
24801            });
24802            $(this).find("figcaption").css({
24803              color: ffData[isVisible[0]].color
24804            }).text(ffData[isVisible[0]].text);
24805          }
24806
24807          // Réutiliser les variables déjà déclarées pour éviter de refaire le même traitement
24808          let isAvailable = liFFArray.filter(function (n) {
24809            return ffAvailable.indexOf(n) !== -1;
24810          });
24811          if (isAvailable.length < 1) {
24812            $(this).removeClass("available");
24813          } else {
24814            $(this).addClass("available");
24815          }
24816        });
24817        $("#archive_channel .options_list ul li").each(function () {
24818          // S'assurer que data('ff') existe et est une chaîne avant d'appeler split()
24819          let optionDataFF = $(this).data("ff") || "";
24820          let optionFFArray = typeof optionDataFF === "string" ? optionDataFF.split(",").slice(0, optionDataFF.split(",").length - 1) : [];
24821          let isVisible = optionFFArray.filter(function (n) {
24822            return ffAvailable.indexOf(n) !== -1;
24823          });
24824          if (isVisible.length < 1) {
24825            $(this).removeClass("visible");
24826          } else {
24827            $(this).addClass("visible");
24828          }
24829        });
24830      } else {
24831        let adminBarHeight = $("body").hasClass("admin-bar") ? 32 : 0,
24832          elementOffsetTop = $(this).hasClass("all") ? $(".channel_list").offset().top : $("#archive_channel").find('.channel_list article[data-radio="true"]').offset().top - 30,
24833          theScrollTop = elementOffsetTop - $("#heading").height() - adminBarHeight;
24834        $("html, body").animate({
24835          scrollTop: theScrollTop
24836        }, 500);
24837      }
24838    }
24839  });
24840  //Scroll
24841  if ($("#archive_channel").length !== 0) {
24842    $("#archive_channel").find(".channel_list .go-top").unbind("click").click(function () {
24843      $("html, body").animate({
24844        scrollTop: $(".filters").offset().top - $("#heading").height() - ($("body").hasClass("admin-bar") ? 32 : 0)
24845      }, 500);
24846    });
24847    if ($(".filters").offset().top - $("#heading").height() - ($("body").hasClass("admin-bar") ? 32 : 0) + parseFloat($(window).height()) < $("html, body").scrollTop()) {
24848      $("#archive_channel").find(".channel_list .go-top").addClass("active");
24849    } else {
24850      $("#archive_channel").find(".channel_list .go-top").removeClass("active");
24851    }
24852    if (parseFloat($("#archive_channel").find(".channel_list").outerHeight(true)) + parseFloat($("#archive_channel").find(".options_list").outerHeight(true)) + parseFloat($("#archive_channel").find(".channel_list").offset().top) < $(window).scrollTop() + $(window).height() + ($("body").hasClass("admin-bar") ? 32 : 0)) {
24853      $("#archive_channel").find(".channel_list .go-top").css({
24854        top: parseFloat($("#archive_channel").find(".channel_list").height()) + parseFloat($("#archive_channel").find(".options_list").height()) - 30 + "px",
24855        position: "absolute"
24856      });
24857    } else {
24858      $("#archive_channel").find(".channel_list .go-top").css({
24859        top: "",
24860        position: ""
24861      });
24862    }
24863  }
24864  //Popin
24865  $("#archive_channel .options_list .popin_action").on("click", function () {
24866    ajaxGetPopinContent($(this).data("id"));
24867  });
24868}
24869
24870/* JS pour le menu burger */
24871function menuHamburger() {
24872  $("#heading .hamburger").on("click", function () {
24873    $(this).find(".icons").toggleClass("open");
24874    $("body").toggleClass("stop_scrolling");
24875    $("#menu_page").toggleClass("visible");
24876    $("html, body").animate({
24877      scrollTop: 0
24878    }, 100);
24879  });
24880}
24881function changePhoneVariant() {
24882  var $singlePhone = $("#single-phone");
24883  $singlePhone.find(".colors ul li").unbind().on("click", function () {
24884    if (!$(this).hasClass("active")) {
24885      $("#single-phone").find(".colors ul li").removeClass("active");
24886      $(this).addClass("active");
24887      ajaxSinglePhone($singlePhone, "sfr_device_color");
24888    }
24889  });
24890  $singlePhone.find("#phone .phone-description .capacity select").unbind().on("change", function () {
24891    ajaxSinglePhone($singlePhone, "sfr_device_capacity");
24892  });
24893}
24894
24895/* Permet de gérer l'ajax des fiche téléphone, en fonction de si on change de couleur ou de capacité de stockage */
24896function ajaxSinglePhone($singlePhone, principal) {
24897  var params = {};
24898  params["sfr_device_color"] = $singlePhone.find("#phone .phone-description .colors .active").data("c
24898olor"); /* Couleur */
24899  params["sfr_device_capacity"] = $singlePhone.find("#phone .phone-description .capacity select option:selected").val(); /* Capacité */
24900  params["phoneID"] = $singlePhone.find("#phone").data("id"); /* Id du téléphone */
24901  params["posttype"] = $singlePhone.find("#phone").data("posttype"); /* posttype du material */
24902  params["principal"] = principal; /* Savoir ou la personne à cliqué */
24903
24904  $singlePhone.find("#phone").addClass("loading");
24905  $.ajax({
24906    url: sfrJSVars.ajaxurl,
24907    method: "POST",
24908    data: {
24909      action: "displaySinglePhone",
24910      params: params
24911    },
24912    success: function (data) {
24913      $singlePhone.find("#phone").remove(); /* On vide le dom */
24914      $(data).insertAfter($singlePhone.find(".breadcrumbs")); /* On le réinsère */
24915
24916      $singlePhone.find("#phone").removeClass("loading");
24917
24918      /* On rappel nos functions */
24919      $(".carrousel_container.is_sliding").each(function () {
24920        new Carrousel($(this), {
24921          auto: false,
24922          puces: false
24923        }).init();
24924      });
24925      changePhoneVariant();
24926      allDropdownSlide();
24927    },
24928    error: function (request, error) {
24929      console.log(error);
24930    }
24931  });
24932}
24933
24934/* Passe le header en sticky avant qu'il ne disparaisse de l'écran */
24935function headerSticky() {
24936  if (!$("body").hasClass("stop_listening")) {
24937    if (!$("body").hasClass("fixed_head") && $(document).scrollTop() > $("#heading").innerHeight() / 1.5) {
24938      $("main").css({
24939        "padding-top": $("#heading").innerHeight() + "px"
24940      });
24941      $("body").addClass("fixed_head");
24942    } else if ($("body").hasClass("fixed_head") && $(document).scrollTop() <= parseInt($("main").css("padding-top")) - $("#heading").innerHeight()) {
24943      $("main").css({
24944        "padding-top": "0px"
24945      });
24946      $("body").removeClass("fixed_head");
24947    }
24948  }
24949}
24950
24951// ********* //
24952//FORFAITS
24953// ********* //
24954
24955function ajaxPortabilite() {
24956  $("#portabilite-form input").change(function () {
24957    $("#portabilite-form").removeClass("error_numbers, error_fields");
24958  });
24959  $("#portabilite-form").on("submit", function (e) {
24960    e.preventDefault();
24961    if ($("#portabilite-numero").val() != "" && $("#portabilite-rio").val() != "") {
24962      $("#portabilite-form .button").addClass("loading");
24963      $.ajax({
24964        url: sfrJSVars.ajaxurl,
24965        method: "POST",
24966        data: {
24967          action: "ajaxPortabilite",
24968          params: {
24969            numero: $("#portabilite-numero").val(),
24970            rio: $("#portabilite-rio").val(),
24971            type: $("#post-type").val()
24972          }
24973        },
24974        success: function (data) {
24975          if (JSON.parse(data).message && JSON.parse(data).message.toLowerCase() == "ok") {
24976            if ($("#redirect-to").val() != "" && $("#post-type").val() != "") {
24977              window.location.href = $("#redirect-to").val() + "#ff";
24978            } else {
24979              $("#portabilite-form").addClass("error_redirect");
24980              $("#portabilite-form").append('<div class="error error_redirect"><p>DEV : Portability page need ?parent=[pageID]&type=[typeName] parameters to work</p></div>');
24981              $("#portabilite-form .button").removeClass("loading");
24982            }
24983          } else {
24984            $("#portabilite-form").addClass("error_numbers");
24985            $("#portabilite-form .button").removeClass("loading");
24986          }
24987        },
24988        error: function (request, error) {
24989          $("#portabilite-form").addClass("error_numbers");
24990        }
24991      });
24992    } else {
24993      $("#portabilite-form").addClass("error_fields");
24994    }
24995  });
24996}
24997
24998// ********* //
24999// ********* //
25000// ********* //
25001
25002function pageComplement() {
25003  $("#complement form article .popin_action").click(function () {
25004    ajaxGetPopinContent($(this).data("id"));
25005  });
25006
25007  // Handle add button clicks
25008  $("#complement form article.options .el_carr .add-button").click(function () {
25009    const $button = $(this);
25010    const $checkbox = $button.siblings('input[type="checkbox"]');
25011    const optionId = $button.data("option-id");
25012
25013    // Toggle the checkbox
25014    const isChecked = $checkbox.prop("checked");
25015    $checkbox.prop("checked", !isChecked);
25016
25017    // Toggle button active state
25018    $button.toggleClass("active");
25019
25020    // Handle exclusive selection by type
25021    if ($button.data("type") && !isChecked) {
25022      const type = $button.data("type");
25023      const code = $button.data("code");
25024      $("#complement form article.options .el_carr .add-button").each(function () {
25025        if ($(this).data("type") == type && $(this).data("code") != code) {
25026          $(this).parent().find('input[type="checkbox"]').prop("checked", false);
25027        }
25028      });
25029    }
25030  });
25031}
25032function channelGoTop() {}
25033function functions_cookies() {
25034  var $cookieConsent = $("#cookieconsent"),
25035    $cookieSettings = $("#cookiesettings"),
25036    classVisible = "visible",
25037    classHidden = "masked";
25038  $("#cookieconsent .settings").click(function () {
25039    $cookieConsent.addClass(classHidden);
25040    $cookieSettings.addClass(classVisible);
25041  });
25042  $("#cookieconsent .allow").click(function () {
25043    cookies.write("cookieconsent_status", JSON.stringify({
25044      analytics: true,
25045      marketing: true,
25046      personnalisation: true
25047    }), 365);
25048    $cookieConsent.addClass(classHidden);
25049    document.location.reload(true);
25050  });
25051  $("#cookieconsent .disallow").click(function () {
25052    cookies.write("cookieconsent_status", JSON.stringify({
25053      analytics: false,
25054      marketing: false,
25055      personnalisation: false
25056    }), 365);
25057    $cookieConsent.addClass(classHidden);
25058    document.location.reload(true);
25059  });
25060  $("#cookiesettings .close").click(function () {
25061    $cookieSettings.removeClass(classVisible);
25062  });
25063  $("#cookiesettings button").click(function () {
25064    var cookie = {
25065      analytics: true,
25066      marketing: true,
25067      personnalisation: true
25068    };
25069    $("#cookiesettings .toggle").each(function () {
25070      if ($(this).hasClass("active")) {
25071        cookie[$(this).data("cookie")] = true;
25072      } else {
25073        cookie[$(this).data("cookie")] = false;
25074      }
25075    });
25076    cookies.write("cookieconsent_status", JSON.stringify(cookie), 365);
25077    $cookieSettings.removeClass(classVisible);
25078    document.location.reload(true);
25079  });
25080  $("#cookiesettings .toggle").click(function () {
25081    $(this).toggleClass("active");
25082  });
25083  $(".cookie_config").click(function () {
25084    $cookieConsent.addClass(classHidden);
25085    $cookieSettings.addClass(classVisible);
25086  });
25087  $("#cookie_policy .settings").click(function () {
25088    $cookieConsent.addClass(classHidden);
25089    $cookieSettings.addClass(classVisible);
25090  });
25091}
25092function headBand() {
25093  $("#alert_headband .animation").css({
25094    "animation-duration": $("#alert_headband .animation .content").innerWidth() / 60 / sfrJSVars.headbandSpeed.time + "s"
25095  });
25096}
25097})();
25098
25099SpinFunctions = __webpack_exports__;
25100/******/ })()
25101;

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.