111
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

6721 line
210 KiB

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