shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

swiper.jquery.umd.js (213120B)


      1 /**
      2  * Swiper 3.4.2
      3  * Most modern mobile touch slider and framework with hardware accelerated transitions
      4  * 
      5  * http://www.idangero.us/swiper/
      6  * 
      7  * Copyright 2017, Vladimir Kharlampidi
      8  * The iDangero.us
      9  * http://www.idangero.us/
     10  * 
     11  * Licensed under MIT
     12  * 
     13  * Released on: March 10, 2017
     14  */
     15 (function (root, factory) {
     16 	'use strict';
     17 
     18 	if (typeof define === 'function' && define.amd) {
     19 		// AMD. Register as an anonymous module.
     20 		define(['jquery'], factory);
     21 	} else if (typeof exports === 'object') {
     22 		// Node. Does not work with strict CommonJS, but
     23 		// only CommonJS-like environments that support module.exports,
     24 		// like Node.
     25 		module.exports = factory(require('jquery'));
     26 	} else {
     27 		// Browser globals (root is window)
     28 		root.Swiper = factory(root.jQuery);
     29 	}
     30 }(this, function ($) {
     31 	'use strict';
     32 
     33     /*===========================
     34     Swiper
     35     ===========================*/
     36     var Swiper = function (container, params) {
     37         if (!(this instanceof Swiper)) return new Swiper(container, params);
     38     
     39 
     40         var defaults = {
     41             direction: 'horizontal',
     42             touchEventsTarget: 'container',
     43             initialSlide: 0,
     44             speed: 300,
     45             // autoplay
     46             autoplay: false,
     47             autoplayDisableOnInteraction: true,
     48             autoplayStopOnLast: false,
     49             // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
     50             iOSEdgeSwipeDetection: false,
     51             iOSEdgeSwipeThreshold: 20,
     52             // Free mode
     53             freeMode: false,
     54             freeModeMomentum: true,
     55             freeModeMomentumRatio: 1,
     56             freeModeMomentumBounce: true,
     57             freeModeMomentumBounceRatio: 1,
     58             freeModeMomentumVelocityRatio: 1,
     59             freeModeSticky: false,
     60             freeModeMinimumVelocity: 0.02,
     61             // Autoheight
     62             autoHeight: false,
     63             // Set wrapper width
     64             setWrapperSize: false,
     65             // Virtual Translate
     66             virtualTranslate: false,
     67             // Effects
     68             effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
     69             coverflow: {
     70                 rotate: 50,
     71                 stretch: 0,
     72                 depth: 100,
     73                 modifier: 1,
     74                 slideShadows : true
     75             },
     76             flip: {
     77                 slideShadows : true,
     78                 limitRotation: true
     79             },
     80             cube: {
     81                 slideShadows: true,
     82                 shadow: true,
     83                 shadowOffset: 20,
     84                 shadowScale: 0.94
     85             },
     86             fade: {
     87                 crossFade: false
     88             },
     89             // Parallax
     90             parallax: false,
     91             // Zoom
     92             zoom: false,
     93             zoomMax: 3,
     94             zoomMin: 1,
     95             zoomToggle: true,
     96             // Scrollbar
     97             scrollbar: null,
     98             scrollbarHide: true,
     99             scrollbarDraggable: false,
    100             scrollbarSnapOnRelease: false,
    101             // Keyboard Mousewheel
    102             keyboardControl: false,
    103             mousewheelControl: false,
    104             mousewheelReleaseOnEdges: false,
    105             mousewheelInvert: false,
    106             mousewheelForceToAxis: false,
    107             mousewheelSensitivity: 1,
    108             mousewheelEventsTarged: 'container',
    109             // Hash Navigation
    110             hashnav: false,
    111             hashnavWatchState: false,
    112             // History
    113             history: false,
    114             // Commong Nav State
    115             replaceState: false,
    116             // Breakpoints
    117             breakpoints: undefined,
    118             // Slides grid
    119             spaceBetween: 0,
    120             slidesPerView: 1,
    121             slidesPerColumn: 1,
    122             slidesPerColumnFill: 'column',
    123             slidesPerGroup: 1,
    124             centeredSlides: false,
    125             slidesOffsetBefore: 0, // in px
    126             slidesOffsetAfter: 0, // in px
    127             // Round length
    128             roundLengths: false,
    129             // Touches
    130             touchRatio: 1,
    131             touchAngle: 45,
    132             simulateTouch: true,
    133             shortSwipes: true,
    134             longSwipes: true,
    135             longSwipesRatio: 0.5,
    136             longSwipesMs: 300,
    137             followFinger: true,
    138             onlyExternal: false,
    139             threshold: 0,
    140             touchMoveStopPropagation: true,
    141             touchReleaseOnEdges: false,
    142             // Unique Navigation Elements
    143             uniqueNavElements: true,
    144             // Pagination
    145             pagination: null,
    146             paginationElement: 'span',
    147             paginationClickable: false,
    148             paginationHide: false,
    149             paginationBulletRender: null,
    150             paginationProgressRender: null,
    151             paginationFractionRender: null,
    152             paginationCustomRender: null,
    153             paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'
    154             // Resistance
    155             resistance: true,
    156             resistanceRatio: 0.85,
    157             // Next/prev buttons
    158             nextButton: null,
    159             prevButton: null,
    160             // Progress
    161             watchSlidesProgress: false,
    162             watchSlidesVisibility: false,
    163             // Cursor
    164             grabCursor: false,
    165             // Clicks
    166             preventClicks: true,
    167             preventClicksPropagation: true,
    168             slideToClickedSlide: false,
    169             // Lazy Loading
    170             lazyLoading: false,
    171             lazyLoadingInPrevNext: false,
    172             lazyLoadingInPrevNextAmount: 1,
    173             lazyLoadingOnTransitionStart: false,
    174             // Images
    175             preloadImages: true,
    176             updateOnImagesReady: true,
    177             // loop
    178             loop: false,
    179             loopAdditionalSlides: 0,
    180             loopedSlides: null,
    181             // Control
    182             control: undefined,
    183             controlInverse: false,
    184             controlBy: 'slide', //or 'container'
    185             normalizeSlideIndex: true,
    186             // Swiping/no swiping
    187             allowSwipeToPrev: true,
    188             allowSwipeToNext: true,
    189             swipeHandler: null, //'.swipe-handler',
    190             noSwiping: true,
    191             noSwipingClass: 'swiper-no-swiping',
    192             // Passive Listeners
    193             passiveListeners: true,
    194             // NS
    195             containerModifierClass: 'swiper-container-', // NEW
    196             slideClass: 'swiper-slide',
    197             slideActiveClass: 'swiper-slide-active',
    198             slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
    199             slideVisibleClass: 'swiper-slide-visible',
    200             slideDuplicateClass: 'swiper-slide-duplicate',
    201             slideNextClass: 'swiper-slide-next',
    202             slideDuplicateNextClass: 'swiper-slide-duplicate-next',
    203             slidePrevClass: 'swiper-slide-prev',
    204             slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
    205             wrapperClass: 'swiper-wrapper',
    206             bulletClass: 'swiper-pagination-bullet',
    207             bulletActiveClass: 'swiper-pagination-bullet-active',
    208             buttonDisabledClass: 'swiper-button-disabled',
    209             paginationCurrentClass: 'swiper-pagination-current',
    210             paginationTotalClass: 'swiper-pagination-total',
    211             paginationHiddenClass: 'swiper-pagination-hidden',
    212             paginationProgressbarClass: 'swiper-pagination-progressbar',
    213             paginationClickableClass: 'swiper-pagination-clickable', // NEW
    214             paginationModifierClass: 'swiper-pagination-', // NEW
    215             lazyLoadingClass: 'swiper-lazy',
    216             lazyStatusLoadingClass: 'swiper-lazy-loading',
    217             lazyStatusLoadedClass: 'swiper-lazy-loaded',
    218             lazyPreloaderClass: 'swiper-lazy-preloader',
    219             notificationClass: 'swiper-notification',
    220             preloaderClass: 'preloader',
    221             zoomContainerClass: 'swiper-zoom-container',
    222         
    223             // Observer
    224             observer: false,
    225             observeParents: false,
    226             // Accessibility
    227             a11y: false,
    228             prevSlideMessage: 'Previous slide',
    229             nextSlideMessage: 'Next slide',
    230             firstSlideMessage: 'This is the first slide',
    231             lastSlideMessage: 'This is the last slide',
    232             paginationBulletMessage: 'Go to slide {{index}}',
    233             // Callbacks
    234             runCallbacksOnInit: true
    235             /*
    236             Callbacks:
    237             onInit: function (swiper)
    238             onDestroy: function (swiper)
    239             onBeforeResize: function (swiper)
    240             onAfterResize: function (swiper)
    241             onClick: function (swiper, e)
    242             onTap: function (swiper, e)
    243             onDoubleTap: function (swiper, e)
    244             onSliderMove: function (swiper, e)
    245             onSlideChangeStart: function (swiper)
    246             onSlideChangeEnd: function (swiper)
    247             onTransitionStart: function (swiper)
    248             onTransitionEnd: function (swiper)
    249             onImagesReady: function (swiper)
    250             onProgress: function (swiper, progress)
    251             onTouchStart: function (swiper, e)
    252             onTouchMove: function (swiper, e)
    253             onTouchMoveOpposite: function (swiper, e)
    254             onTouchEnd: function (swiper, e)
    255             onReachBeginning: function (swiper)
    256             onReachEnd: function (swiper)
    257             onSetTransition: function (swiper, duration)
    258             onSetTranslate: function (swiper, translate)
    259             onAutoplayStart: function (swiper)
    260             onAutoplayStop: function (swiper),
    261             onLazyImageLoad: function (swiper, slide, image)
    262             onLazyImageReady: function (swiper, slide, image)
    263             onKeyPress: function (swiper, keyCode)
    264             */
    265         
    266         };
    267         var initialVirtualTranslate = params && params.virtualTranslate;
    268         
    269         params = params || {};
    270         var originalParams = {};
    271         for (var param in params) {
    272             if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {
    273                 originalParams[param] = {};
    274                 for (var deepParam in params[param]) {
    275                     originalParams[param][deepParam] = params[param][deepParam];
    276                 }
    277             }
    278             else {
    279                 originalParams[param] = params[param];
    280             }
    281         }
    282         for (var def in defaults) {
    283             if (typeof params[def] === 'undefined') {
    284                 params[def] = defaults[def];
    285             }
    286             else if (typeof params[def] === 'object') {
    287                 for (var deepDef in defaults[def]) {
    288                     if (typeof params[def][deepDef] === 'undefined') {
    289                         params[def][deepDef] = defaults[def][deepDef];
    290                     }
    291                 }
    292             }
    293         }
    294         
    295         // Swiper
    296         var s = this;
    297         
    298         // Params
    299         s.params = params;
    300         s.originalParams = originalParams;
    301         
    302         // Classname
    303         s.classNames = [];
    304         /*=========================
    305           Dom Library and plugins
    306           ===========================*/
    307         if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){
    308             $ = Dom7;
    309         }
    310         if (typeof $ === 'undefined') {
    311             if (typeof Dom7 === 'undefined') {
    312                 $ = window.Dom7 || window.Zepto || window.jQuery;
    313             }
    314             else {
    315                 $ = Dom7;
    316             }
    317             if (!$) return;
    318         }
    319         // Export it to Swiper instance
    320         s.$ = $;
    321         
    322         /*=========================
    323           Breakpoints
    324           ===========================*/
    325         s.currentBreakpoint = undefined;
    326         s.getActiveBreakpoint = function () {
    327             //Get breakpoint for window width
    328             if (!s.params.breakpoints) return false;
    329             var breakpoint = false;
    330             var points = [], point;
    331             for ( point in s.params.breakpoints ) {
    332                 if (s.params.breakpoints.hasOwnProperty(point)) {
    333                     points.push(point);
    334                 }
    335             }
    336             points.sort(function (a, b) {
    337                 return parseInt(a, 10) > parseInt(b, 10);
    338             });
    339             for (var i = 0; i < points.length; i++) {
    340                 point = points[i];
    341                 if (point >= window.innerWidth && !breakpoint) {
    342                     breakpoint = point;
    343                 }
    344             }
    345             return breakpoint || 'max';
    346         };
    347         s.setBreakpoint = function () {
    348             //Set breakpoint for window width and update parameters
    349             var breakpoint = s.getActiveBreakpoint();
    350             if (breakpoint && s.currentBreakpoint !== breakpoint) {
    351                 var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;
    352                 var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);
    353                 for ( var param in breakPointsParams ) {
    354                     s.params[param] = breakPointsParams[param];
    355                 }
    356                 s.currentBreakpoint = breakpoint;
    357                 if(needsReLoop && s.destroyLoop) {
    358                     s.reLoop(true);
    359                 }
    360             }
    361         };
    362         // Set breakpoint on load
    363         if (s.params.breakpoints) {
    364             s.setBreakpoint();
    365         }
    366         
    367         /*=========================
    368           Preparation - Define Container, Wrapper and Pagination
    369           ===========================*/
    370         s.container = $(container);
    371         if (s.container.length === 0) return;
    372         if (s.container.length > 1) {
    373             var swipers = [];
    374             s.container.each(function () {
    375                 var container = this;
    376                 swipers.push(new Swiper(this, params));
    377             });
    378             return swipers;
    379         }
    380         
    381         // Save instance in container HTML Element and in data
    382         s.container[0].swiper = s;
    383         s.container.data('swiper', s);
    384         
    385         s.classNames.push(s.params.containerModifierClass + s.params.direction);
    386         
    387         if (s.params.freeMode) {
    388             s.classNames.push(s.params.containerModifierClass + 'free-mode');
    389         }
    390         if (!s.support.flexbox) {
    391             s.classNames.push(s.params.containerModifierClass + 'no-flexbox');
    392             s.params.slidesPerColumn = 1;
    393         }
    394         if (s.params.autoHeight) {
    395             s.classNames.push(s.params.containerModifierClass + 'autoheight');
    396         }
    397         // Enable slides progress when required
    398         if (s.params.parallax || s.params.watchSlidesVisibility) {
    399             s.params.watchSlidesProgress = true;
    400         }
    401         // Max resistance when touchReleaseOnEdges
    402         if (s.params.touchReleaseOnEdges) {
    403             s.params.resistanceRatio = 0;
    404         }
    405         // Coverflow / 3D
    406         if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {
    407             if (s.support.transforms3d) {
    408                 s.params.watchSlidesProgress = true;
    409                 s.classNames.push(s.params.containerModifierClass + '3d');
    410             }
    411             else {
    412                 s.params.effect = 'slide';
    413             }
    414         }
    415         if (s.params.effect !== 'slide') {
    416             s.classNames.push(s.params.containerModifierClass + s.params.effect);
    417         }
    418         if (s.params.effect === 'cube') {
    419             s.params.resistanceRatio = 0;
    420             s.params.slidesPerView = 1;
    421             s.params.slidesPerColumn = 1;
    422             s.params.slidesPerGroup = 1;
    423             s.params.centeredSlides = false;
    424             s.params.spaceBetween = 0;
    425             s.params.virtualTranslate = true;
    426         }
    427         if (s.params.effect === 'fade' || s.params.effect === 'flip') {
    428             s.params.slidesPerView = 1;
    429             s.params.slidesPerColumn = 1;
    430             s.params.slidesPerGroup = 1;
    431             s.params.watchSlidesProgress = true;
    432             s.params.spaceBetween = 0;
    433             if (typeof initialVirtualTranslate === 'undefined') {
    434                 s.params.virtualTranslate = true;
    435             }
    436         }
    437         
    438         // Grab Cursor
    439         if (s.params.grabCursor && s.support.touch) {
    440             s.params.grabCursor = false;
    441         }
    442         
    443         // Wrapper
    444         s.wrapper = s.container.children('.' + s.params.wrapperClass);
    445         
    446         // Pagination
    447         if (s.params.pagination) {
    448             s.paginationContainer = $(s.params.pagination);
    449             if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {
    450                 s.paginationContainer = s.container.find(s.params.pagination);
    451             }
    452         
    453             if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {
    454                 s.paginationContainer.addClass(s.params.paginationModifierClass + 'clickable');
    455             }
    456             else {
    457                 s.params.paginationClickable = false;
    458             }
    459             s.paginationContainer.addClass(s.params.paginationModifierClass + s.params.paginationType);
    460         }
    461         // Next/Prev Buttons
    462         if (s.params.nextButton || s.params.prevButton) {
    463             if (s.params.nextButton) {
    464                 s.nextButton = $(s.params.nextButton);
    465                 if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {
    466                     s.nextButton = s.container.find(s.params.nextButton);
    467                 }
    468             }
    469             if (s.params.prevButton) {
    470                 s.prevButton = $(s.params.prevButton);
    471                 if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {
    472                     s.prevButton = s.container.find(s.params.prevButton);
    473                 }
    474             }
    475         }
    476         
    477         // Is Horizontal
    478         s.isHorizontal = function () {
    479             return s.params.direction === 'horizontal';
    480         };
    481         // s.isH = isH;
    482         
    483         // RTL
    484         s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
    485         if (s.rtl) {
    486             s.classNames.push(s.params.containerModifierClass + 'rtl');
    487         }
    488         
    489         // Wrong RTL support
    490         if (s.rtl) {
    491             s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
    492         }
    493         
    494         // Columns
    495         if (s.params.slidesPerColumn > 1) {
    496             s.classNames.push(s.params.containerModifierClass + 'multirow');
    497         }
    498         
    499         // Check for Android
    500         if (s.device.android) {
    501             s.classNames.push(s.params.containerModifierClass + 'android');
    502         }
    503         
    504         // Add classes
    505         s.container.addClass(s.classNames.join(' '));
    506         
    507         // Translate
    508         s.translate = 0;
    509         
    510         // Progress
    511         s.progress = 0;
    512         
    513         // Velocity
    514         s.velocity = 0;
    515         
    516         /*=========================
    517           Locks, unlocks
    518           ===========================*/
    519         s.lockSwipeToNext = function () {
    520             s.params.allowSwipeToNext = false;
    521             if (s.params.allowSwipeToPrev === false && s.params.grabCursor) {
    522                 s.unsetGrabCursor();
    523             }
    524         };
    525         s.lockSwipeToPrev = function () {
    526             s.params.allowSwipeToPrev = false;
    527             if (s.params.allowSwipeToNext === false && s.params.grabCursor) {
    528                 s.unsetGrabCursor();
    529             }
    530         };
    531         s.lockSwipes = function () {
    532             s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
    533             if (s.params.grabCursor) s.unsetGrabCursor();
    534         };
    535         s.unlockSwipeToNext = function () {
    536             s.params.allowSwipeToNext = true;
    537             if (s.params.allowSwipeToPrev === true && s.params.grabCursor) {
    538                 s.setGrabCursor();
    539             }
    540         };
    541         s.unlockSwipeToPrev = function () {
    542             s.params.allowSwipeToPrev = true;
    543             if (s.params.allowSwipeToNext === true && s.params.grabCursor) {
    544                 s.setGrabCursor();
    545             }
    546         };
    547         s.unlockSwipes = function () {
    548             s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
    549             if (s.params.grabCursor) s.setGrabCursor();
    550         };
    551         
    552         /*=========================
    553           Round helper
    554           ===========================*/
    555         function round(a) {
    556             return Math.floor(a);
    557         }
    558         /*=========================
    559           Set grab cursor
    560           ===========================*/
    561         s.setGrabCursor = function(moving) {
    562             s.container[0].style.cursor = 'move';
    563             s.container[0].style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';
    564             s.container[0].style.cursor = moving ? '-moz-grabbin' : '-moz-grab';
    565             s.container[0].style.cursor = moving ? 'grabbing': 'grab';
    566         };
    567         s.unsetGrabCursor = function () {
    568             s.container[0].style.cursor = '';
    569         };
    570         if (s.params.grabCursor) {
    571             s.setGrabCursor();
    572         }
    573         /*=========================
    574           Update on Images Ready
    575           ===========================*/
    576         s.imagesToLoad = [];
    577         s.imagesLoaded = 0;
    578         
    579         s.loadImage = function (imgElement, src, srcset, sizes, checkForComplete, callback) {
    580             var image;
    581             function onReady () {
    582                 if (callback) callback();
    583             }
    584             if (!imgElement.complete || !checkForComplete) {
    585                 if (src) {
    586                     image = new window.Image();
    587                     image.onload = onReady;
    588                     image.onerror = onReady;
    589                     if (sizes) {
    590                         image.sizes = sizes;
    591                     }
    592                     if (srcset) {
    593                         image.srcset = srcset;
    594                     }
    595                     if (src) {
    596                         image.src = src;
    597                     }
    598                 } else {
    599                     onReady();
    600                 }
    601         
    602             } else {//image already loaded...
    603                 onReady();
    604             }
    605         };
    606         s.preloadImages = function () {
    607             s.imagesToLoad = s.container.find('img');
    608             function _onReady() {
    609                 if (typeof s === 'undefined' || s === null || !s) return;
    610                 if (s.imagesLoaded !== undefined) s.imagesLoaded++;
    611                 if (s.imagesLoaded === s.imagesToLoad.length) {
    612                     if (s.params.updateOnImagesReady) s.update();
    613                     s.emit('onImagesReady', s);
    614                 }
    615             }
    616             for (var i = 0; i < s.imagesToLoad.length; i++) {
    617                 s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), s.imagesToLoad[i].sizes || s.imagesToLoad[i].getAttribute('sizes'), true, _onReady);
    618             }
    619         };
    620         
    621         /*=========================
    622           Autoplay
    623           ===========================*/
    624         s.autoplayTimeoutId = undefined;
    625         s.autoplaying = false;
    626         s.autoplayPaused = false;
    627         function autoplay() {
    628             var autoplayDelay = s.params.autoplay;
    629             var activeSlide = s.slides.eq(s.activeIndex);
    630             if (activeSlide.attr('data-swiper-autoplay')) {
    631                 autoplayDelay = activeSlide.attr('data-swiper-autoplay') || s.params.autoplay;
    632             }
    633             s.autoplayTimeoutId = setTimeout(function () {
    634                 if (s.params.loop) {
    635                     s.fixLoop();
    636                     s._slideNext();
    637                     s.emit('onAutoplay', s);
    638                 }
    639                 else {
    640                     if (!s.isEnd) {
    641                         s._slideNext();
    642                         s.emit('onAutoplay', s);
    643                     }
    644                     else {
    645                         if (!params.autoplayStopOnLast) {
    646                             s._slideTo(0);
    647                             s.emit('onAutoplay', s);
    648                         }
    649                         else {
    650                             s.stopAutoplay();
    651                         }
    652                     }
    653                 }
    654             }, autoplayDelay);
    655         }
    656         s.startAutoplay = function () {
    657             if (typeof s.autoplayTimeoutId !== 'undefined') return false;
    658             if (!s.params.autoplay) return false;
    659             if (s.autoplaying) return false;
    660             s.autoplaying = true;
    661             s.emit('onAutoplayStart', s);
    662             autoplay();
    663         };
    664         s.stopAutoplay = function (internal) {
    665             if (!s.autoplayTimeoutId) return;
    666             if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
    667             s.autoplaying = false;
    668             s.autoplayTimeoutId = undefined;
    669             s.emit('onAutoplayStop', s);
    670         };
    671         s.pauseAutoplay = function (speed) {
    672             if (s.autoplayPaused) return;
    673             if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
    674             s.autoplayPaused = true;
    675             if (speed === 0) {
    676                 s.autoplayPaused = false;
    677                 autoplay();
    678             }
    679             else {
    680                 s.wrapper.transitionEnd(function () {
    681                     if (!s) return;
    682                     s.autoplayPaused = false;
    683                     if (!s.autoplaying) {
    684                         s.stopAutoplay();
    685                     }
    686                     else {
    687                         autoplay();
    688                     }
    689                 });
    690             }
    691         };
    692         /*=========================
    693           Min/Max Translate
    694           ===========================*/
    695         s.minTranslate = function () {
    696             return (-s.snapGrid[0]);
    697         };
    698         s.maxTranslate = function () {
    699             return (-s.snapGrid[s.snapGrid.length - 1]);
    700         };
    701         /*=========================
    702           Slider/slides sizes
    703           ===========================*/
    704         s.updateAutoHeight = function () {
    705             var activeSlides = [];
    706             var newHeight = 0;
    707             var i;
    708         
    709             // Find slides currently in view
    710             if(s.params.slidesPerView !== 'auto' && s.params.slidesPerView > 1) {
    711                 for (i = 0; i < Math.ceil(s.params.slidesPerView); i++) {
    712                     var index = s.activeIndex + i;
    713                     if(index > s.slides.length) break;
    714                     activeSlides.push(s.slides.eq(index)[0]);
    715                 }
    716             } else {
    717                 activeSlides.push(s.slides.eq(s.activeIndex)[0]);
    718             }
    719         
    720             // Find new height from heighest slide in view
    721             for (i = 0; i < activeSlides.length; i++) {
    722                 if (typeof activeSlides[i] !== 'undefined') {
    723                     var height = activeSlides[i].offsetHeight;
    724                     newHeight = height > newHeight ? height : newHeight;
    725                 }
    726             }
    727         
    728             // Update Height
    729             if (newHeight) s.wrapper.css('height', newHeight + 'px');
    730         };
    731         s.updateContainerSize = function () {
    732             var width, height;
    733             if (typeof s.params.width !== 'undefined') {
    734                 width = s.params.width;
    735             }
    736             else {
    737                 width = s.container[0].clientWidth;
    738             }
    739             if (typeof s.params.height !== 'undefined') {
    740                 height = s.params.height;
    741             }
    742             else {
    743                 height = s.container[0].clientHeight;
    744             }
    745             if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {
    746                 return;
    747             }
    748         
    749             //Subtract paddings
    750             width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);
    751             height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);
    752         
    753             // Store values
    754             s.width = width;
    755             s.height = height;
    756             s.size = s.isHorizontal() ? s.width : s.height;
    757         };
    758         
    759         s.updateSlidesSize = function () {
    760             s.slides = s.wrapper.children('.' + s.params.slideClass);
    761             s.snapGrid = [];
    762             s.slidesGrid = [];
    763             s.slidesSizesGrid = [];
    764         
    765             var spaceBetween = s.params.spaceBetween,
    766                 slidePosition = -s.params.slidesOffsetBefore,
    767                 i,
    768                 prevSlideSize = 0,
    769                 index = 0;
    770             if (typeof s.size === 'undefined') return;
    771             if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
    772                 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
    773             }
    774         
    775             s.virtualSize = -spaceBetween;
    776             // reset margins
    777             if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
    778             else s.slides.css({marginRight: '', marginBottom: ''});
    779         
    780             var slidesNumberEvenToRows;
    781             if (s.params.slidesPerColumn > 1) {
    782                 if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
    783                     slidesNumberEvenToRows = s.slides.length;
    784                 }
    785                 else {
    786                     slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
    787                 }
    788                 if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {
    789                     slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);
    790                 }
    791             }
    792         
    793             // Calc slides
    794             var slideSize;
    795             var slidesPerColumn = s.params.slidesPerColumn;
    796             var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
    797             var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);
    798             for (i = 0; i < s.slides.length; i++) {
    799                 slideSize = 0;
    800                 var slide = s.slides.eq(i);
    801                 if (s.params.slidesPerColumn > 1) {
    802                     // Set slides order
    803                     var newSlideOrderIndex;
    804                     var column, row;
    805                     if (s.params.slidesPerColumnFill === 'column') {
    806                         column = Math.floor(i / slidesPerColumn);
    807                         row = i - column * slidesPerColumn;
    808                         if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {
    809                             if (++row >= slidesPerColumn) {
    810                                 row = 0;
    811                                 column++;
    812                             }
    813                         }
    814                         newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
    815                         slide
    816                             .css({
    817                                 '-webkit-box-ordinal-group': newSlideOrderIndex,
    818                                 '-moz-box-ordinal-group': newSlideOrderIndex,
    819                                 '-ms-flex-order': newSlideOrderIndex,
    820                                 '-webkit-order': newSlideOrderIndex,
    821                                 'order': newSlideOrderIndex
    822                             });
    823                     }
    824                     else {
    825                         row = Math.floor(i / slidesPerRow);
    826                         column = i - row * slidesPerRow;
    827                     }
    828                     slide
    829                         .css(
    830                             'margin-' + (s.isHorizontal() ? 'top' : 'left'),
    831                             (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
    832                         )
    833                         .attr('data-swiper-column', column)
    834                         .attr('data-swiper-row', row);
    835         
    836                 }
    837                 if (slide.css('display') === 'none') continue;
    838                 if (s.params.slidesPerView === 'auto') {
    839                     slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
    840                     if (s.params.roundLengths) slideSize = round(slideSize);
    841                 }
    842                 else {
    843                     slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
    844                     if (s.params.roundLengths) slideSize = round(slideSize);
    845         
    846                     if (s.isHorizontal()) {
    847                         s.slides[i].style.width = slideSize + 'px';
    848                     }
    849                     else {
    850                         s.slides[i].style.height = slideSize + 'px';
    851                     }
    852                 }
    853                 s.slides[i].swiperSlideSize = slideSize;
    854                 s.slidesSizesGrid.push(slideSize);
    855         
    856         
    857                 if (s.params.centeredSlides) {
    858                     slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
    859                     if(prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
    860                     if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
    861                     if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
    862                     if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
    863                     s.slidesGrid.push(slidePosition);
    864                 }
    865                 else {
    866                     if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
    867                     s.slidesGrid.push(slidePosition);
    868                     slidePosition = slidePosition + slideSize + spaceBetween;
    869                 }
    870         
    871                 s.virtualSize += slideSize + spaceBetween;
    872         
    873                 prevSlideSize = slideSize;
    874         
    875                 index ++;
    876             }
    877             s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;
    878             var newSlidesGrid;
    879         
    880             if (
    881                 s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
    882                 s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
    883             }
    884             if (!s.support.flexbox || s.params.setWrapperSize) {
    885                 if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
    886                 else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
    887             }
    888         
    889             if (s.params.slidesPerColumn > 1) {
    890                 s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
    891                 s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
    892                 if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
    893                 else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
    894                 if (s.params.centeredSlides) {
    895                     newSlidesGrid = [];
    896                     for (i = 0; i < s.snapGrid.length; i++) {
    897                         if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
    898                     }
    899                     s.snapGrid = newSlidesGrid;
    900                 }
    901             }
    902         
    903             // Remove last grid elements depending on width
    904             if (!s.params.centeredSlides) {
    905                 newSlidesGrid = [];
    906                 for (i = 0; i < s.snapGrid.length; i++) {
    907                     if (s.snapGrid[i] <= s.virtualSize - s.size) {
    908                         newSlidesGrid.push(s.snapGrid[i]);
    909                     }
    910                 }
    911                 s.snapGrid = newSlidesGrid;
    912                 if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {
    913                     s.snapGrid.push(s.virtualSize - s.size);
    914                 }
    915             }
    916             if (s.snapGrid.length === 0) s.snapGrid = [0];
    917         
    918             if (s.params.spaceBetween !== 0) {
    919                 if (s.isHorizontal()) {
    920                     if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
    921                     else s.slides.css({marginRight: spaceBetween + 'px'});
    922                 }
    923                 else s.slides.css({marginBottom: spaceBetween + 'px'});
    924             }
    925             if (s.params.watchSlidesProgress) {
    926                 s.updateSlidesOffset();
    927             }
    928         };
    929         s.updateSlidesOffset = function () {
    930             for (var i = 0; i < s.slides.length; i++) {
    931                 s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
    932             }
    933         };
    934         
    935         /*=========================
    936           Dynamic Slides Per View
    937           ===========================*/
    938         s.currentSlidesPerView = function () {
    939             var spv = 1, i, j;
    940             if (s.params.centeredSlides) {
    941                 var size = s.slides[s.activeIndex].swiperSlideSize;
    942                 var breakLoop;
    943                 for (i = s.activeIndex + 1; i < s.slides.length; i++) {
    944                     if (s.slides[i] && !breakLoop) {
    945                         size += s.slides[i].swiperSlideSize;
    946                         spv ++;
    947                         if (size > s.size) breakLoop = true;
    948                     }
    949                 }
    950                 for (j = s.activeIndex - 1; j >= 0; j--) {
    951                     if (s.slides[j] && !breakLoop) {
    952                         size += s.slides[j].swiperSlideSize;
    953                         spv ++;
    954                         if (size > s.size) breakLoop = true;
    955                     }
    956                 }
    957             }
    958             else {
    959                 for (i = s.activeIndex + 1; i < s.slides.length; i++) {
    960                     if (s.slidesGrid[i] - s.slidesGrid[s.activeIndex] < s.size) {
    961                         spv++;
    962                     }
    963                 }
    964             }
    965             return spv;
    966         };
    967         /*=========================
    968           Slider/slides progress
    969           ===========================*/
    970         s.updateSlidesProgress = function (translate) {
    971             if (typeof translate === 'undefined') {
    972                 translate = s.translate || 0;
    973             }
    974             if (s.slides.length === 0) return;
    975             if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
    976         
    977             var offsetCenter = -translate;
    978             if (s.rtl) offsetCenter = translate;
    979         
    980             // Visible Slides
    981             s.slides.removeClass(s.params.slideVisibleClass);
    982             for (var i = 0; i < s.slides.length; i++) {
    983                 var slide = s.slides[i];
    984                 var slideProgress = (offsetCenter + (s.params.centeredSlides ? s.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
    985                 if (s.params.watchSlidesVisibility) {
    986                     var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
    987                     var slideAfter = slideBefore + s.slidesSizesGrid[i];
    988                     var isVisible =
    989                         (slideBefore >= 0 && slideBefore < s.size) ||
    990                         (slideAfter > 0 && slideAfter <= s.size) ||
    991                         (slideBefore <= 0 && slideAfter >= s.size);
    992                     if (isVisible) {
    993                         s.slides.eq(i).addClass(s.params.slideVisibleClass);
    994                     }
    995                 }
    996                 slide.progress = s.rtl ? -slideProgress : slideProgress;
    997             }
    998         };
    999         s.updateProgress = function (translate) {
   1000             if (typeof translate === 'undefined') {
   1001                 translate = s.translate || 0;
   1002             }
   1003             var translatesDiff = s.maxTranslate() - s.minTranslate();
   1004             var wasBeginning = s.isBeginning;
   1005             var wasEnd = s.isEnd;
   1006             if (translatesDiff === 0) {
   1007                 s.progress = 0;
   1008                 s.isBeginning = s.isEnd = true;
   1009             }
   1010             else {
   1011                 s.progress = (translate - s.minTranslate()) / (translatesDiff);
   1012                 s.isBeginning = s.progress <= 0;
   1013                 s.isEnd = s.progress >= 1;
   1014             }
   1015             if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);
   1016             if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);
   1017         
   1018             if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
   1019             s.emit('onProgress', s, s.progress);
   1020         };
   1021         s.updateActiveIndex = function () {
   1022             var translate = s.rtl ? s.translate : -s.translate;
   1023             var newActiveIndex, i, snapIndex;
   1024             for (i = 0; i < s.slidesGrid.length; i ++) {
   1025                 if (typeof s.slidesGrid[i + 1] !== 'undefined') {
   1026                     if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
   1027                         newActiveIndex = i;
   1028                     }
   1029                     else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
   1030                         newActiveIndex = i + 1;
   1031                     }
   1032                 }
   1033                 else {
   1034                     if (translate >= s.slidesGrid[i]) {
   1035                         newActiveIndex = i;
   1036                     }
   1037                 }
   1038             }
   1039             // Normalize slideIndex
   1040             if(s.params.normalizeSlideIndex){
   1041                 if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
   1042             }
   1043             // for (i = 0; i < s.slidesGrid.length; i++) {
   1044                 // if (- translate >= s.slidesGrid[i]) {
   1045                     // newActiveIndex = i;
   1046                 // }
   1047             // }
   1048             snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
   1049             if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
   1050         
   1051             if (newActiveIndex === s.activeIndex) {
   1052                 return;
   1053             }
   1054             s.snapIndex = snapIndex;
   1055             s.previousIndex = s.activeIndex;
   1056             s.activeIndex = newActiveIndex;
   1057             s.updateClasses();
   1058             s.updateRealIndex();
   1059         };
   1060         s.updateRealIndex = function(){
   1061             s.realIndex = parseInt(s.slides.eq(s.activeIndex).attr('data-swiper-slide-index') || s.activeIndex, 10);
   1062         };
   1063         
   1064         /*=========================
   1065           Classes
   1066           ===========================*/
   1067         s.updateClasses = function () {
   1068             s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass + ' ' + s.params.slideDuplicateActiveClass + ' ' + s.params.slideDuplicateNextClass + ' ' + s.params.slideDuplicatePrevClass);
   1069             var activeSlide = s.slides.eq(s.activeIndex);
   1070             // Active classes
   1071             activeSlide.addClass(s.params.slideActiveClass);
   1072             if (params.loop) {
   1073                 // Duplicate to all looped slides
   1074                 if (activeSlide.hasClass(s.params.slideDuplicateClass)) {
   1075                     s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
   1076                 }
   1077                 else {
   1078                     s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
   1079                 }
   1080             }
   1081             // Next Slide
   1082             var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
   1083             if (s.params.loop && nextSlide.length === 0) {
   1084                 nextSlide = s.slides.eq(0);
   1085                 nextSlide.addClass(s.params.slideNextClass);
   1086             }
   1087             // Prev Slide
   1088             var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
   1089             if (s.params.loop && prevSlide.length === 0) {
   1090                 prevSlide = s.slides.eq(-1);
   1091                 prevSlide.addClass(s.params.slidePrevClass);
   1092             }
   1093             if (params.loop) {
   1094                 // Duplicate to all looped slides
   1095                 if (nextSlide.hasClass(s.params.slideDuplicateClass)) {
   1096                     s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
   1097                 }
   1098                 else {
   1099                     s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
   1100                 }
   1101                 if (prevSlide.hasClass(s.params.slideDuplicateClass)) {
   1102                     s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
   1103                 }
   1104                 else {
   1105                     s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
   1106                 }
   1107             }
   1108         
   1109             // Pagination
   1110             if (s.paginationContainer && s.paginationContainer.length > 0) {
   1111                 // Current/Total
   1112                 var current,
   1113                     total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
   1114                 if (s.params.loop) {
   1115                     current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);
   1116                     if (current > s.slides.length - 1 - s.loopedSlides * 2) {
   1117                         current = current - (s.slides.length - s.loopedSlides * 2);
   1118                     }
   1119                     if (current > total - 1) current = current - total;
   1120                     if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;
   1121                 }
   1122                 else {
   1123                     if (typeof s.snapIndex !== 'undefined') {
   1124                         current = s.snapIndex;
   1125                     }
   1126                     else {
   1127                         current = s.activeIndex || 0;
   1128                     }
   1129                 }
   1130                 // Types
   1131                 if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {
   1132                     s.bullets.removeClass(s.params.bulletActiveClass);
   1133                     if (s.paginationContainer.length > 1) {
   1134                         s.bullets.each(function () {
   1135                             if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);
   1136                         });
   1137                     }
   1138                     else {
   1139                         s.bullets.eq(current).addClass(s.params.bulletActiveClass);
   1140                     }
   1141                 }
   1142                 if (s.params.paginationType === 'fraction') {
   1143                     s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);
   1144                     s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);
   1145                 }
   1146                 if (s.params.paginationType === 'progress') {
   1147                     var scale = (current + 1) / total,
   1148                         scaleX = scale,
   1149                         scaleY = 1;
   1150                     if (!s.isHorizontal()) {
   1151                         scaleY = scale;
   1152                         scaleX = 1;
   1153                     }
   1154                     s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);
   1155                 }
   1156                 if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {
   1157                     s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));
   1158                     s.emit('onPaginationRendered', s, s.paginationContainer[0]);
   1159                 }
   1160             }
   1161         
   1162             // Next/active buttons
   1163             if (!s.params.loop) {
   1164                 if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
   1165                     if (s.isBeginning) {
   1166                         s.prevButton.addClass(s.params.buttonDisabledClass);
   1167                         if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);
   1168                     }
   1169                     else {
   1170                         s.prevButton.removeClass(s.params.buttonDisabledClass);
   1171                         if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);
   1172                     }
   1173                 }
   1174                 if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
   1175                     if (s.isEnd) {
   1176                         s.nextButton.addClass(s.params.buttonDisabledClass);
   1177                         if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);
   1178                     }
   1179                     else {
   1180                         s.nextButton.removeClass(s.params.buttonDisabledClass);
   1181                         if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);
   1182                     }
   1183                 }
   1184             }
   1185         };
   1186         
   1187         /*=========================
   1188           Pagination
   1189           ===========================*/
   1190         s.updatePagination = function () {
   1191             if (!s.params.pagination) return;
   1192             if (s.paginationContainer && s.paginationContainer.length > 0) {
   1193                 var paginationHTML = '';
   1194                 if (s.params.paginationType === 'bullets') {
   1195                     var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
   1196                     for (var i = 0; i < numberOfBullets; i++) {
   1197                         if (s.params.paginationBulletRender) {
   1198                             paginationHTML += s.params.paginationBulletRender(s, i, s.params.bulletClass);
   1199                         }
   1200                         else {
   1201                             paginationHTML += '<' + s.params.paginationElement+' class="' + s.params.bulletClass + '"></' + s.params.paginationElement + '>';
   1202                         }
   1203                     }
   1204                     s.paginationContainer.html(paginationHTML);
   1205                     s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
   1206                     if (s.params.paginationClickable && s.params.a11y && s.a11y) {
   1207                         s.a11y.initPagination();
   1208                     }
   1209                 }
   1210                 if (s.params.paginationType === 'fraction') {
   1211                     if (s.params.paginationFractionRender) {
   1212                         paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);
   1213                     }
   1214                     else {
   1215                         paginationHTML =
   1216                             '<span class="' + s.params.paginationCurrentClass + '"></span>' +
   1217                             ' / ' +
   1218                             '<span class="' + s.params.paginationTotalClass+'"></span>';
   1219                     }
   1220                     s.paginationContainer.html(paginationHTML);
   1221                 }
   1222                 if (s.params.paginationType === 'progress') {
   1223                     if (s.params.paginationProgressRender) {
   1224                         paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);
   1225                     }
   1226                     else {
   1227                         paginationHTML = '<span class="' + s.params.paginationProgressbarClass + '"></span>';
   1228                     }
   1229                     s.paginationContainer.html(paginationHTML);
   1230                 }
   1231                 if (s.params.paginationType !== 'custom') {
   1232                     s.emit('onPaginationRendered', s, s.paginationContainer[0]);
   1233                 }
   1234             }
   1235         };
   1236         /*=========================
   1237           Common update method
   1238           ===========================*/
   1239         s.update = function (updateTranslate) {
   1240             if (!s) return;
   1241             s.updateContainerSize();
   1242             s.updateSlidesSize();
   1243             s.updateProgress();
   1244             s.updatePagination();
   1245             s.updateClasses();
   1246             if (s.params.scrollbar && s.scrollbar) {
   1247                 s.scrollbar.set();
   1248             }
   1249             var newTranslate;
   1250             function forceSetTranslate() {
   1251                 var translate = s.rtl ? -s.translate : s.translate;
   1252                 newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
   1253                 s.setWrapperTranslate(newTranslate);
   1254                 s.updateActiveIndex();
   1255                 s.updateClasses();
   1256             }
   1257             if (updateTranslate) {
   1258                 var translated;
   1259                 if (s.controller && s.controller.spline) {
   1260                     s.controller.spline = undefined;
   1261                 }
   1262                 if (s.params.freeMode) {
   1263                     forceSetTranslate();
   1264                     if (s.params.autoHeight) {
   1265                         s.updateAutoHeight();
   1266                     }
   1267                 }
   1268                 else {
   1269                     if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
   1270                         translated = s.slideTo(s.slides.length - 1, 0, false, true);
   1271                     }
   1272                     else {
   1273                         translated = s.slideTo(s.activeIndex, 0, false, true);
   1274                     }
   1275                     if (!translated) {
   1276                         forceSetTranslate();
   1277                     }
   1278                 }
   1279             }
   1280             else if (s.params.autoHeight) {
   1281                 s.updateAutoHeight();
   1282             }
   1283         };
   1284         
   1285         /*=========================
   1286           Resize Handler
   1287           ===========================*/
   1288         s.onResize = function (forceUpdatePagination) {
   1289             if (s.params.onBeforeResize) s.params.onBeforeResize(s);
   1290             //Breakpoints
   1291             if (s.params.breakpoints) {
   1292                 s.setBreakpoint();
   1293             }
   1294         
   1295             // Disable locks on resize
   1296             var allowSwipeToPrev = s.params.allowSwipeToPrev;
   1297             var allowSwipeToNext = s.params.allowSwipeToNext;
   1298             s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;
   1299         
   1300             s.updateContainerSize();
   1301             s.updateSlidesSize();
   1302             if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();
   1303             if (s.params.scrollbar && s.scrollbar) {
   1304                 s.scrollbar.set();
   1305             }
   1306             if (s.controller && s.controller.spline) {
   1307                 s.controller.spline = undefined;
   1308             }
   1309             var slideChangedBySlideTo = false;
   1310             if (s.params.freeMode) {
   1311                 var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
   1312                 s.setWrapperTranslate(newTranslate);
   1313                 s.updateActiveIndex();
   1314                 s.updateClasses();
   1315         
   1316                 if (s.params.autoHeight) {
   1317                     s.updateAutoHeight();
   1318                 }
   1319             }
   1320             else {
   1321                 s.updateClasses();
   1322                 if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
   1323                     slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);
   1324                 }
   1325                 else {
   1326                     slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);
   1327                 }
   1328             }
   1329             if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {
   1330                 s.lazy.load();
   1331             }
   1332             // Return locks after resize
   1333             s.params.allowSwipeToPrev = allowSwipeToPrev;
   1334             s.params.allowSwipeToNext = allowSwipeToNext;
   1335             if (s.params.onAfterResize) s.params.onAfterResize(s);
   1336         };
   1337         
   1338         /*=========================
   1339           Events
   1340           ===========================*/
   1341         
   1342         //Define Touch Events
   1343         s.touchEventsDesktop = {start: 'mousedown', move: 'mousemove', end: 'mouseup'};
   1344         if (window.navigator.pointerEnabled) s.touchEventsDesktop = {start: 'pointerdown', move: 'pointermove', end: 'pointerup'};
   1345         else if (window.navigator.msPointerEnabled) s.touchEventsDesktop = {start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp'};
   1346         s.touchEvents = {
   1347             start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : s.touchEventsDesktop.start,
   1348             move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : s.touchEventsDesktop.move,
   1349             end : s.support.touch || !s.params.simulateTouch ? 'touchend' : s.touchEventsDesktop.end
   1350         };
   1351         
   1352         
   1353         // WP8 Touch Events Fix
   1354         if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
   1355             (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
   1356         }
   1357         
   1358         // Attach/detach events
   1359         s.initEvents = function (detach) {
   1360             var actionDom = detach ? 'off' : 'on';
   1361             var action = detach ? 'removeEventListener' : 'addEventListener';
   1362             var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
   1363             var target = s.support.touch ? touchEventsTarget : document;
   1364         
   1365             var moveCapture = s.params.nested ? true : false;
   1366         
   1367             //Touch Events
   1368             if (s.browser.ie) {
   1369                 touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
   1370                 target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
   1371                 target[action](s.touchEvents.end, s.onTouchEnd, false);
   1372             }
   1373             else {
   1374                 if (s.support.touch) {
   1375                     var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
   1376                     touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, passiveListener);
   1377                     touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
   1378                     touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, passiveListener);
   1379                 }
   1380                 if ((params.simulateTouch && !s.device.ios && !s.device.android) || (params.simulateTouch && !s.support.touch && s.device.ios)) {
   1381                     touchEventsTarget[action]('mousedown', s.onTouchStart, false);
   1382                     document[action]('mousemove', s.onTouchMove, moveCapture);
   1383                     document[action]('mouseup', s.onTouchEnd, false);
   1384                 }
   1385             }
   1386             window[action]('resize', s.onResize);
   1387         
   1388             // Next, Prev, Index
   1389             if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
   1390                 s.nextButton[actionDom]('click', s.onClickNext);
   1391                 if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);
   1392             }
   1393             if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
   1394                 s.prevButton[actionDom]('click', s.onClickPrev);
   1395                 if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);
   1396             }
   1397             if (s.params.pagination && s.params.paginationClickable) {
   1398                 s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
   1399                 if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);
   1400             }
   1401         
   1402             // Prevent Links Clicks
   1403             if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
   1404         };
   1405         s.attachEvents = function () {
   1406             s.initEvents();
   1407         };
   1408         s.detachEvents = function () {
   1409             s.initEvents(true);
   1410         };
   1411         
   1412         /*=========================
   1413           Handle Clicks
   1414           ===========================*/
   1415         // Prevent Clicks
   1416         s.allowClick = true;
   1417         s.preventClicks = function (e) {
   1418             if (!s.allowClick) {
   1419                 if (s.params.preventClicks) e.preventDefault();
   1420                 if (s.params.preventClicksPropagation && s.animating) {
   1421                     e.stopPropagation();
   1422                     e.stopImmediatePropagation();
   1423                 }
   1424             }
   1425         };
   1426         // Clicks
   1427         s.onClickNext = function (e) {
   1428             e.preventDefault();
   1429             if (s.isEnd && !s.params.loop) return;
   1430             s.slideNext();
   1431         };
   1432         s.onClickPrev = function (e) {
   1433             e.preventDefault();
   1434             if (s.isBeginning && !s.params.loop) return;
   1435             s.slidePrev();
   1436         };
   1437         s.onClickIndex = function (e) {
   1438             e.preventDefault();
   1439             var index = $(this).index() * s.params.slidesPerGroup;
   1440             if (s.params.loop) index = index + s.loopedSlides;
   1441             s.slideTo(index);
   1442         };
   1443         
   1444         /*=========================
   1445           Handle Touches
   1446           ===========================*/
   1447         function findElementInEvent(e, selector) {
   1448             var el = $(e.target);
   1449             if (!el.is(selector)) {
   1450                 if (typeof selector === 'string') {
   1451                     el = el.parents(selector);
   1452                 }
   1453                 else if (selector.nodeType) {
   1454                     var found;
   1455                     el.parents().each(function (index, _el) {
   1456                         if (_el === selector) found = selector;
   1457                     });
   1458                     if (!found) return undefined;
   1459                     else return selector;
   1460                 }
   1461             }
   1462             if (el.length === 0) {
   1463                 return undefined;
   1464             }
   1465             return el[0];
   1466         }
   1467         s.updateClickedSlide = function (e) {
   1468             var slide = findElementInEvent(e, '.' + s.params.slideClass);
   1469             var slideFound = false;
   1470             if (slide) {
   1471                 for (var i = 0; i < s.slides.length; i++) {
   1472                     if (s.slides[i] === slide) slideFound = true;
   1473                 }
   1474             }
   1475         
   1476             if (slide && slideFound) {
   1477                 s.clickedSlide = slide;
   1478                 s.clickedIndex = $(slide).index();
   1479             }
   1480             else {
   1481                 s.clickedSlide = undefined;
   1482                 s.clickedIndex = undefined;
   1483                 return;
   1484             }
   1485             if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
   1486                 var slideToIndex = s.clickedIndex,
   1487                     realIndex,
   1488                     duplicatedSlides,
   1489                     slidesPerView = s.params.slidesPerView === 'auto' ? s.currentSlidesPerView() : s.params.slidesPerView;
   1490                 if (s.params.loop) {
   1491                     if (s.animating) return;
   1492                     realIndex = parseInt($(s.clickedSlide).attr('data-swiper-slide-index'), 10);
   1493                     if (s.params.centeredSlides) {
   1494                         if ((slideToIndex < s.loopedSlides - slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + slidesPerView/2)) {
   1495                             s.fixLoop();
   1496                             slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
   1497                             setTimeout(function () {
   1498                                 s.slideTo(slideToIndex);
   1499                             }, 0);
   1500                         }
   1501                         else {
   1502                             s.slideTo(slideToIndex);
   1503                         }
   1504                     }
   1505                     else {
   1506                         if (slideToIndex > s.slides.length - slidesPerView) {
   1507                             s.fixLoop();
   1508                             slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
   1509                             setTimeout(function () {
   1510                                 s.slideTo(slideToIndex);
   1511                             }, 0);
   1512                         }
   1513                         else {
   1514                             s.slideTo(slideToIndex);
   1515                         }
   1516                     }
   1517                 }
   1518                 else {
   1519                     s.slideTo(slideToIndex);
   1520                 }
   1521             }
   1522         };
   1523         
   1524         var isTouched,
   1525             isMoved,
   1526             allowTouchCallbacks,
   1527             touchStartTime,
   1528             isScrolling,
   1529             currentTranslate,
   1530             startTranslate,
   1531             allowThresholdMove,
   1532             // Form elements to match
   1533             formElements = 'input, select, textarea, button, video',
   1534             // Last click time
   1535             lastClickTime = Date.now(), clickTimeout,
   1536             //Velocities
   1537             velocities = [],
   1538             allowMomentumBounce;
   1539         
   1540         // Animating Flag
   1541         s.animating = false;
   1542         
   1543         // Touches information
   1544         s.touches = {
   1545             startX: 0,
   1546             startY: 0,
   1547             currentX: 0,
   1548             currentY: 0,
   1549             diff: 0
   1550         };
   1551         
   1552         // Touch handlers
   1553         var isTouchEvent, startMoving;
   1554         s.onTouchStart = function (e) {
   1555             if (e.originalEvent) e = e.originalEvent;
   1556             isTouchEvent = e.type === 'touchstart';
   1557             if (!isTouchEvent && 'which' in e && e.which === 3) return;
   1558             if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
   1559                 s.allowClick = true;
   1560                 return;
   1561             }
   1562             if (s.params.swipeHandler) {
   1563                 if (!findElementInEvent(e, s.params.swipeHandler)) return;
   1564             }
   1565         
   1566             var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
   1567             var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
   1568         
   1569             // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
   1570             if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {
   1571                 return;
   1572             }
   1573         
   1574             isTouched = true;
   1575             isMoved = false;
   1576             allowTouchCallbacks = true;
   1577             isScrolling = undefined;
   1578             startMoving = undefined;
   1579             s.touches.startX = startX;
   1580             s.touches.startY = startY;
   1581             touchStartTime = Date.now();
   1582             s.allowClick = true;
   1583             s.updateContainerSize();
   1584             s.swipeDirection = undefined;
   1585             if (s.params.threshold > 0) allowThresholdMove = false;
   1586             if (e.type !== 'touchstart') {
   1587                 var preventDefault = true;
   1588                 if ($(e.target).is(formElements)) preventDefault = false;
   1589                 if (document.activeElement && $(document.activeElement).is(formElements)) {
   1590                     document.activeElement.blur();
   1591                 }
   1592                 if (preventDefault) {
   1593                     e.preventDefault();
   1594                 }
   1595             }
   1596             s.emit('onTouchStart', s, e);
   1597         };
   1598         
   1599         s.onTouchMove = function (e) {
   1600             if (e.originalEvent) e = e.originalEvent;
   1601             if (isTouchEvent && e.type === 'mousemove') return;
   1602             if (e.preventedByNestedSwiper) {
   1603                 s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
   1604                 s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
   1605                 return;
   1606             }
   1607             if (s.params.onlyExternal) {
   1608                 // isMoved = true;
   1609                 s.allowClick = false;
   1610                 if (isTouched) {
   1611                     s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
   1612                     s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
   1613                     touchStartTime = Date.now();
   1614                 }
   1615                 return;
   1616             }
   1617             if (isTouchEvent && s.params.touchReleaseOnEdges && !s.params.loop) {
   1618                 if (!s.isHorizontal()) {
   1619                     // Vertical
   1620                     if (
   1621                         (s.touches.currentY < s.touches.startY && s.translate <= s.maxTranslate()) ||
   1622                         (s.touches.currentY > s.touches.startY && s.translate >= s.minTranslate())
   1623                         ) {
   1624                         return;
   1625                     }
   1626                 }
   1627                 else {
   1628                     if (
   1629                         (s.touches.currentX < s.touches.startX && s.translate <= s.maxTranslate()) ||
   1630                         (s.touches.currentX > s.touches.startX && s.translate >= s.minTranslate())
   1631                         ) {
   1632                         return;
   1633                     }
   1634                 }
   1635             }
   1636             if (isTouchEvent && document.activeElement) {
   1637                 if (e.target === document.activeElement && $(e.target).is(formElements)) {
   1638                     isMoved = true;
   1639                     s.allowClick = false;
   1640                     return;
   1641                 }
   1642             }
   1643             if (allowTouchCallbacks) {
   1644                 s.emit('onTouchMove', s, e);
   1645             }
   1646             if (e.targetTouches && e.targetTouches.length > 1) return;
   1647         
   1648             s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
   1649             s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
   1650         
   1651             if (typeof isScrolling === 'undefined') {
   1652                 var touchAngle;
   1653                 if (s.isHorizontal() && s.touches.currentY === s.touches.startY || !s.isHorizontal() && s.touches.currentX === s.touches.startX) {
   1654                     isScrolling = false;
   1655                 }
   1656                 else {
   1657                     touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
   1658                     isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
   1659                 }
   1660             }
   1661             if (isScrolling) {
   1662                 s.emit('onTouchMoveOpposite', s, e);
   1663             }
   1664             if (typeof startMoving === 'undefined') {
   1665                 if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
   1666                     startMoving = true;
   1667                 }
   1668             }
   1669             if (!isTouched) return;
   1670             if (isScrolling)  {
   1671                 isTouched = false;
   1672                 return;
   1673             }
   1674             if (!startMoving) {
   1675                 return;
   1676             }
   1677             s.allowClick = false;
   1678             s.emit('onSliderMove', s, e);
   1679             e.preventDefault();
   1680             if (s.params.touchMoveStopPropagation && !s.params.nested) {
   1681                 e.stopPropagation();
   1682             }
   1683         
   1684             if (!isMoved) {
   1685                 if (params.loop) {
   1686                     s.fixLoop();
   1687                 }
   1688                 startTranslate = s.getWrapperTranslate();
   1689                 s.setWrapperTransition(0);
   1690                 if (s.animating) {
   1691                     s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
   1692                 }
   1693                 if (s.params.autoplay && s.autoplaying) {
   1694                     if (s.params.autoplayDisableOnInteraction) {
   1695                         s.stopAutoplay();
   1696                     }
   1697                     else {
   1698                         s.pauseAutoplay();
   1699                     }
   1700                 }
   1701                 allowMomentumBounce = false;
   1702                 //Grab Cursor
   1703                 if (s.params.grabCursor && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
   1704                     s.setGrabCursor(true);
   1705                 }
   1706             }
   1707             isMoved = true;
   1708         
   1709             var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
   1710         
   1711             diff = diff * s.params.touchRatio;
   1712             if (s.rtl) diff = -diff;
   1713         
   1714             s.swipeDirection = diff > 0 ? 'prev' : 'next';
   1715             currentTranslate = diff + startTranslate;
   1716         
   1717             var disableParentSwiper = true;
   1718             if ((diff > 0 && currentTranslate > s.minTranslate())) {
   1719                 disableParentSwiper = false;
   1720                 if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
   1721             }
   1722             else if (diff < 0 && currentTranslate < s.maxTranslate()) {
   1723                 disableParentSwiper = false;
   1724                 if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
   1725             }
   1726         
   1727             if (disableParentSwiper) {
   1728                 e.preventedByNestedSwiper = true;
   1729             }
   1730         
   1731             // Directions locks
   1732             if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
   1733                 currentTranslate = startTranslate;
   1734             }
   1735             if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
   1736                 currentTranslate = startTranslate;
   1737             }
   1738         
   1739         
   1740             // Threshold
   1741             if (s.params.threshold > 0) {
   1742                 if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
   1743                     if (!allowThresholdMove) {
   1744                         allowThresholdMove = true;
   1745                         s.touches.startX = s.touches.currentX;
   1746                         s.touches.startY = s.touches.currentY;
   1747                         currentTranslate = startTranslate;
   1748                         s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
   1749                         return;
   1750                     }
   1751                 }
   1752                 else {
   1753                     currentTranslate = startTranslate;
   1754                     return;
   1755                 }
   1756             }
   1757         
   1758             if (!s.params.followFinger) return;
   1759         
   1760             // Update active index in free mode
   1761             if (s.params.freeMode || s.params.watchSlidesProgress) {
   1762                 s.updateActiveIndex();
   1763             }
   1764             if (s.params.freeMode) {
   1765                 //Velocity
   1766                 if (velocities.length === 0) {
   1767                     velocities.push({
   1768                         position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],
   1769                         time: touchStartTime
   1770                     });
   1771                 }
   1772                 velocities.push({
   1773                     position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],
   1774                     time: (new window.Date()).getTime()
   1775                 });
   1776             }
   1777             // Update progress
   1778             s.updateProgress(currentTranslate);
   1779             // Update translate
   1780             s.setWrapperTranslate(currentTranslate);
   1781         };
   1782         s.onTouchEnd = function (e) {
   1783             if (e.originalEvent) e = e.originalEvent;
   1784             if (allowTouchCallbacks) {
   1785                 s.emit('onTouchEnd', s, e);
   1786             }
   1787             allowTouchCallbacks = false;
   1788             if (!isTouched) return;
   1789             //Return Grab Cursor
   1790             if (s.params.grabCursor && isMoved && isTouched  && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
   1791                 s.setGrabCursor(false);
   1792             }
   1793         
   1794             // Time diff
   1795             var touchEndTime = Date.now();
   1796             var timeDiff = touchEndTime - touchStartTime;
   1797         
   1798             // Tap, doubleTap, Click
   1799             if (s.allowClick) {
   1800                 s.updateClickedSlide(e);
   1801                 s.emit('onTap', s, e);
   1802                 if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
   1803                     if (clickTimeout) clearTimeout(clickTimeout);
   1804                     clickTimeout = setTimeout(function () {
   1805                         if (!s) return;
   1806                         if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
   1807                             s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
   1808                         }
   1809                         s.emit('onClick', s, e);
   1810                     }, 300);
   1811         
   1812                 }
   1813                 if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
   1814                     if (clickTimeout) clearTimeout(clickTimeout);
   1815                     s.emit('onDoubleTap', s, e);
   1816                 }
   1817             }
   1818         
   1819             lastClickTime = Date.now();
   1820             setTimeout(function () {
   1821                 if (s) s.allowClick = true;
   1822             }, 0);
   1823         
   1824             if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
   1825                 isTouched = isMoved = false;
   1826                 return;
   1827             }
   1828             isTouched = isMoved = false;
   1829         
   1830             var currentPos;
   1831             if (s.params.followFinger) {
   1832                 currentPos = s.rtl ? s.translate : -s.translate;
   1833             }
   1834             else {
   1835                 currentPos = -currentTranslate;
   1836             }
   1837             if (s.params.freeMode) {
   1838                 if (currentPos < -s.minTranslate()) {
   1839                     s.slideTo(s.activeIndex);
   1840                     return;
   1841                 }
   1842                 else if (currentPos > -s.maxTranslate()) {
   1843                     if (s.slides.length < s.snapGrid.length) {
   1844                         s.slideTo(s.snapGrid.length - 1);
   1845                     }
   1846                     else {
   1847                         s.slideTo(s.slides.length - 1);
   1848                     }
   1849                     return;
   1850                 }
   1851         
   1852                 if (s.params.freeModeMomentum) {
   1853                     if (velocities.length > 1) {
   1854                         var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
   1855         
   1856                         var distance = lastMoveEvent.position - velocityEvent.position;
   1857                         var time = lastMoveEvent.time - velocityEvent.time;
   1858                         s.velocity = distance / time;
   1859                         s.velocity = s.velocity / 2;
   1860                         if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {
   1861                             s.velocity = 0;
   1862                         }
   1863                         // this implies that the user stopped moving a finger then released.
   1864                         // There would be no events with distance zero, so the last event is stale.
   1865                         if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {
   1866                             s.velocity = 0;
   1867                         }
   1868                     } else {
   1869                         s.velocity = 0;
   1870                     }
   1871                     s.velocity = s.velocity * s.params.freeModeMomentumVelocityRatio;
   1872         
   1873                     velocities.length = 0;
   1874                     var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
   1875                     var momentumDistance = s.velocity * momentumDuration;
   1876         
   1877                     var newPosition = s.translate + momentumDistance;
   1878                     if (s.rtl) newPosition = - newPosition;
   1879                     var doBounce = false;
   1880                     var afterBouncePosition;
   1881                     var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
   1882                     if (newPosition < s.maxTranslate()) {
   1883                         if (s.params.freeModeMomentumBounce) {
   1884                             if (newPosition + s.maxTranslate() < -bounceAmount) {
   1885                                 newPosition = s.maxTranslate() - bounceAmount;
   1886                             }
   1887                             afterBouncePosition = s.maxTranslate();
   1888                             doBounce = true;
   1889                             allowMomentumBounce = true;
   1890                         }
   1891                         else {
   1892                             newPosition = s.maxTranslate();
   1893                         }
   1894                     }
   1895                     else if (newPosition > s.minTranslate()) {
   1896                         if (s.params.freeModeMomentumBounce) {
   1897                             if (newPosition - s.minTranslate() > bounceAmount) {
   1898                                 newPosition = s.minTranslate() + bounceAmount;
   1899                             }
   1900                             afterBouncePosition = s.minTranslate();
   1901                             doBounce = true;
   1902                             allowMomentumBounce = true;
   1903                         }
   1904                         else {
   1905                             newPosition = s.minTranslate();
   1906                         }
   1907                     }
   1908                     else if (s.params.freeModeSticky) {
   1909                         var j = 0,
   1910                             nextSlide;
   1911                         for (j = 0; j < s.snapGrid.length; j += 1) {
   1912                             if (s.snapGrid[j] > -newPosition) {
   1913                                 nextSlide = j;
   1914                                 break;
   1915                             }
   1916         
   1917                         }
   1918                         if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
   1919                             newPosition = s.snapGrid[nextSlide];
   1920                         } else {
   1921                             newPosition = s.snapGrid[nextSlide - 1];
   1922                         }
   1923                         if (!s.rtl) newPosition = - newPosition;
   1924                     }
   1925                     //Fix duration
   1926                     if (s.velocity !== 0) {
   1927                         if (s.rtl) {
   1928                             momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
   1929                         }
   1930                         else {
   1931                             momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
   1932                         }
   1933                     }
   1934                     else if (s.params.freeModeSticky) {
   1935                         s.slideReset();
   1936                         return;
   1937                     }
   1938         
   1939                     if (s.params.freeModeMomentumBounce && doBounce) {
   1940                         s.updateProgress(afterBouncePosition);
   1941                         s.setWrapperTransition(momentumDuration);
   1942                         s.setWrapperTranslate(newPosition);
   1943                         s.onTransitionStart();
   1944                         s.animating = true;
   1945                         s.wrapper.transitionEnd(function () {
   1946                             if (!s || !allowMomentumBounce) return;
   1947                             s.emit('onMomentumBounce', s);
   1948         
   1949                             s.setWrapperTransition(s.params.speed);
   1950                             s.setWrapperTranslate(afterBouncePosition);
   1951                             s.wrapper.transitionEnd(function () {
   1952                                 if (!s) return;
   1953                                 s.onTransitionEnd();
   1954                             });
   1955                         });
   1956                     } else if (s.velocity) {
   1957                         s.updateProgress(newPosition);
   1958                         s.setWrapperTransition(momentumDuration);
   1959                         s.setWrapperTranslate(newPosition);
   1960                         s.onTransitionStart();
   1961                         if (!s.animating) {
   1962                             s.animating = true;
   1963                             s.wrapper.transitionEnd(function () {
   1964                                 if (!s) return;
   1965                                 s.onTransitionEnd();
   1966                             });
   1967                         }
   1968         
   1969                     } else {
   1970                         s.updateProgress(newPosition);
   1971                     }
   1972         
   1973                     s.updateActiveIndex();
   1974                 }
   1975                 if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
   1976                     s.updateProgress();
   1977                     s.updateActiveIndex();
   1978                 }
   1979                 return;
   1980             }
   1981         
   1982             // Find current slide
   1983             var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
   1984             for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
   1985                 if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
   1986                     if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
   1987                         stopIndex = i;
   1988                         groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
   1989                     }
   1990                 }
   1991                 else {
   1992                     if (currentPos >= s.slidesGrid[i]) {
   1993                         stopIndex = i;
   1994                         groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
   1995                     }
   1996                 }
   1997             }
   1998         
   1999             // Find current slide size
   2000             var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
   2001         
   2002             if (timeDiff > s.params.longSwipesMs) {
   2003                 // Long touches
   2004                 if (!s.params.longSwipes) {
   2005                     s.slideTo(s.activeIndex);
   2006                     return;
   2007                 }
   2008                 if (s.swipeDirection === 'next') {
   2009                     if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
   2010                     else s.slideTo(stopIndex);
   2011         
   2012                 }
   2013                 if (s.swipeDirection === 'prev') {
   2014                     if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
   2015                     else s.slideTo(stopIndex);
   2016                 }
   2017             }
   2018             else {
   2019                 // Short swipes
   2020                 if (!s.params.shortSwipes) {
   2021                     s.slideTo(s.activeIndex);
   2022                     return;
   2023                 }
   2024                 if (s.swipeDirection === 'next') {
   2025                     s.slideTo(stopIndex + s.params.slidesPerGroup);
   2026         
   2027                 }
   2028                 if (s.swipeDirection === 'prev') {
   2029                     s.slideTo(stopIndex);
   2030                 }
   2031             }
   2032         };
   2033         /*=========================
   2034           Transitions
   2035           ===========================*/
   2036         s._slideTo = function (slideIndex, speed) {
   2037             return s.slideTo(slideIndex, speed, true, true);
   2038         };
   2039         s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
   2040             if (typeof runCallbacks === 'undefined') runCallbacks = true;
   2041             if (typeof slideIndex === 'undefined') slideIndex = 0;
   2042             if (slideIndex < 0) slideIndex = 0;
   2043             s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
   2044             if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
   2045         
   2046             var translate = - s.snapGrid[s.snapIndex];
   2047             // Stop autoplay
   2048             if (s.params.autoplay && s.autoplaying) {
   2049                 if (internal || !s.params.autoplayDisableOnInteraction) {
   2050                     s.pauseAutoplay(speed);
   2051                 }
   2052                 else {
   2053                     s.stopAutoplay();
   2054                 }
   2055             }
   2056             // Update progress
   2057             s.updateProgress(translate);
   2058         
   2059             // Normalize slideIndex
   2060             if(s.params.normalizeSlideIndex){
   2061                 for (var i = 0; i < s.slidesGrid.length; i++) {
   2062                     if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {
   2063                         slideIndex = i;
   2064                     }
   2065                 }
   2066             }
   2067         
   2068             // Directions locks
   2069             if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {
   2070                 return false;
   2071             }
   2072             if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {
   2073                 if ((s.activeIndex || 0) !== slideIndex ) return false;
   2074             }
   2075         
   2076             // Update Index
   2077             if (typeof speed === 'undefined') speed = s.params.speed;
   2078             s.previousIndex = s.activeIndex || 0;
   2079             s.activeIndex = slideIndex;
   2080             s.updateRealIndex();
   2081             if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {
   2082                 // Update Height
   2083                 if (s.params.autoHeight) {
   2084                     s.updateAutoHeight();
   2085                 }
   2086                 s.updateClasses();
   2087                 if (s.params.effect !== 'slide') {
   2088                     s.setWrapperTranslate(translate);
   2089                 }
   2090                 return false;
   2091             }
   2092             s.updateClasses();
   2093             s.onTransitionStart(runCallbacks);
   2094         
   2095             if (speed === 0 || s.browser.lteIE9) {
   2096                 s.setWrapperTranslate(translate);
   2097                 s.setWrapperTransition(0);
   2098                 s.onTransitionEnd(runCallbacks);
   2099             }
   2100             else {
   2101                 s.setWrapperTranslate(translate);
   2102                 s.setWrapperTransition(speed);
   2103                 if (!s.animating) {
   2104                     s.animating = true;
   2105                     s.wrapper.transitionEnd(function () {
   2106                         if (!s) return;
   2107                         s.onTransitionEnd(runCallbacks);
   2108                     });
   2109                 }
   2110         
   2111             }
   2112         
   2113             return true;
   2114         };
   2115         
   2116         s.onTransitionStart = function (runCallbacks) {
   2117             if (typeof runCallbacks === 'undefined') runCallbacks = true;
   2118             if (s.params.autoHeight) {
   2119                 s.updateAutoHeight();
   2120             }
   2121             if (s.lazy) s.lazy.onTransitionStart();
   2122             if (runCallbacks) {
   2123                 s.emit('onTransitionStart', s);
   2124                 if (s.activeIndex !== s.previousIndex) {
   2125                     s.emit('onSlideChangeStart', s);
   2126                     if (s.activeIndex > s.previousIndex) {
   2127                         s.emit('onSlideNextStart', s);
   2128                     }
   2129                     else {
   2130                         s.emit('onSlidePrevStart', s);
   2131                     }
   2132                 }
   2133         
   2134             }
   2135         };
   2136         s.onTransitionEnd = function (runCallbacks) {
   2137             s.animating = false;
   2138             s.setWrapperTransition(0);
   2139             if (typeof runCallbacks === 'undefined') runCallbacks = true;
   2140             if (s.lazy) s.lazy.onTransitionEnd();
   2141             if (runCallbacks) {
   2142                 s.emit('onTransitionEnd', s);
   2143                 if (s.activeIndex !== s.previousIndex) {
   2144                     s.emit('onSlideChangeEnd', s);
   2145                     if (s.activeIndex > s.previousIndex) {
   2146                         s.emit('onSlideNextEnd', s);
   2147                     }
   2148                     else {
   2149                         s.emit('onSlidePrevEnd', s);
   2150                     }
   2151                 }
   2152             }
   2153             if (s.params.history && s.history) {
   2154                 s.history.setHistory(s.params.history, s.activeIndex);
   2155             }
   2156             if (s.params.hashnav && s.hashnav) {
   2157                 s.hashnav.setHash();
   2158             }
   2159         
   2160         };
   2161         s.slideNext = function (runCallbacks, speed, internal) {
   2162             if (s.params.loop) {
   2163                 if (s.animating) return false;
   2164                 s.fixLoop();
   2165                 var clientLeft = s.container[0].clientLeft;
   2166                 return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
   2167             }
   2168             else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
   2169         };
   2170         s._slideNext = function (speed) {
   2171             return s.slideNext(true, speed, true);
   2172         };
   2173         s.slidePrev = function (runCallbacks, speed, internal) {
   2174             if (s.params.loop) {
   2175                 if (s.animating) return false;
   2176                 s.fixLoop();
   2177                 var clientLeft = s.container[0].clientLeft;
   2178                 return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
   2179             }
   2180             else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
   2181         };
   2182         s._slidePrev = function (speed) {
   2183             return s.slidePrev(true, speed, true);
   2184         };
   2185         s.slideReset = function (runCallbacks, speed, internal) {
   2186             return s.slideTo(s.activeIndex, speed, runCallbacks);
   2187         };
   2188         
   2189         s.disableTouchControl = function () {
   2190             s.params.onlyExternal = true;
   2191             return true;
   2192         };
   2193         s.enableTouchControl = function () {
   2194             s.params.onlyExternal = false;
   2195             return true;
   2196         };
   2197         
   2198         /*=========================
   2199           Translate/transition helpers
   2200           ===========================*/
   2201         s.setWrapperTransition = function (duration, byController) {
   2202             s.wrapper.transition(duration);
   2203             if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
   2204                 s.effects[s.params.effect].setTransition(duration);
   2205             }
   2206             if (s.params.parallax && s.parallax) {
   2207                 s.parallax.setTransition(duration);
   2208             }
   2209             if (s.params.scrollbar && s.scrollbar) {
   2210                 s.scrollbar.setTransition(duration);
   2211             }
   2212             if (s.params.control && s.controller) {
   2213                 s.controller.setTransition(duration, byController);
   2214             }
   2215             s.emit('onSetTransition', s, duration);
   2216         };
   2217         s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
   2218             var x = 0, y = 0, z = 0;
   2219             if (s.isHorizontal()) {
   2220                 x = s.rtl ? -translate : translate;
   2221             }
   2222             else {
   2223                 y = translate;
   2224             }
   2225         
   2226             if (s.params.roundLengths) {
   2227                 x = round(x);
   2228                 y = round(y);
   2229             }
   2230         
   2231             if (!s.params.virtualTranslate) {
   2232                 if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
   2233                 else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
   2234             }
   2235         
   2236             s.translate = s.isHorizontal() ? x : y;
   2237         
   2238             // Check if we need to update progress
   2239             var progress;
   2240             var translatesDiff = s.maxTranslate() - s.minTranslate();
   2241             if (translatesDiff === 0) {
   2242                 progress = 0;
   2243             }
   2244             else {
   2245                 progress = (translate - s.minTranslate()) / (translatesDiff);
   2246             }
   2247             if (progress !== s.progress) {
   2248                 s.updateProgress(translate);
   2249             }
   2250         
   2251             if (updateActiveIndex) s.updateActiveIndex();
   2252             if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
   2253                 s.effects[s.params.effect].setTranslate(s.translate);
   2254             }
   2255             if (s.params.parallax && s.parallax) {
   2256                 s.parallax.setTranslate(s.translate);
   2257             }
   2258             if (s.params.scrollbar && s.scrollbar) {
   2259                 s.scrollbar.setTranslate(s.translate);
   2260             }
   2261             if (s.params.control && s.controller) {
   2262                 s.controller.setTranslate(s.translate, byController);
   2263             }
   2264             s.emit('onSetTranslate', s, s.translate);
   2265         };
   2266         
   2267         s.getTranslate = function (el, axis) {
   2268             var matrix, curTransform, curStyle, transformMatrix;
   2269         
   2270             // automatic axis detection
   2271             if (typeof axis === 'undefined') {
   2272                 axis = 'x';
   2273             }
   2274         
   2275             if (s.params.virtualTranslate) {
   2276                 return s.rtl ? -s.translate : s.translate;
   2277             }
   2278         
   2279             curStyle = window.getComputedStyle(el, null);
   2280             if (window.WebKitCSSMatrix) {
   2281                 curTransform = curStyle.transform || curStyle.webkitTransform;
   2282                 if (curTransform.split(',').length > 6) {
   2283                     curTransform = curTransform.split(', ').map(function(a){
   2284                         return a.replace(',','.');
   2285                     }).join(', ');
   2286                 }
   2287                 // Some old versions of Webkit choke when 'none' is passed; pass
   2288                 // empty string instead in this case
   2289                 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
   2290             }
   2291             else {
   2292                 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
   2293                 matrix = transformMatrix.toString().split(',');
   2294             }
   2295         
   2296             if (axis === 'x') {
   2297                 //Latest Chrome and webkits Fix
   2298                 if (window.WebKitCSSMatrix)
   2299                     curTransform = transformMatrix.m41;
   2300                 //Crazy IE10 Matrix
   2301                 else if (matrix.length === 16)
   2302                     curTransform = parseFloat(matrix[12]);
   2303                 //Normal Browsers
   2304                 else
   2305                     curTransform = parseFloat(matrix[4]);
   2306             }
   2307             if (axis === 'y') {
   2308                 //Latest Chrome and webkits Fix
   2309                 if (window.WebKitCSSMatrix)
   2310                     curTransform = transformMatrix.m42;
   2311                 //Crazy IE10 Matrix
   2312                 else if (matrix.length === 16)
   2313                     curTransform = parseFloat(matrix[13]);
   2314                 //Normal Browsers
   2315                 else
   2316                     curTransform = parseFloat(matrix[5]);
   2317             }
   2318             if (s.rtl && curTransform) curTransform = -curTransform;
   2319             return curTransform || 0;
   2320         };
   2321         s.getWrapperTranslate = function (axis) {
   2322             if (typeof axis === 'undefined') {
   2323                 axis = s.isHorizontal() ? 'x' : 'y';
   2324             }
   2325             return s.getTranslate(s.wrapper[0], axis);
   2326         };
   2327         
   2328         /*=========================
   2329           Observer
   2330           ===========================*/
   2331         s.observers = [];
   2332         function initObserver(target, options) {
   2333             options = options || {};
   2334             // create an observer instance
   2335             var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
   2336             var observer = new ObserverFunc(function (mutations) {
   2337                 mutations.forEach(function (mutation) {
   2338                     s.onResize(true);
   2339                     s.emit('onObserverUpdate', s, mutation);
   2340                 });
   2341             });
   2342         
   2343             observer.observe(target, {
   2344                 attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
   2345                 childList: typeof options.childList === 'undefined' ? true : options.childList,
   2346                 characterData: typeof options.characterData === 'undefined' ? true : options.characterData
   2347             });
   2348         
   2349             s.observers.push(observer);
   2350         }
   2351         s.initObservers = function () {
   2352             if (s.params.observeParents) {
   2353                 var containerParents = s.container.parents();
   2354                 for (var i = 0; i < containerParents.length; i++) {
   2355                     initObserver(containerParents[i]);
   2356                 }
   2357             }
   2358         
   2359             // Observe container
   2360             initObserver(s.container[0], {childList: false});
   2361         
   2362             // Observe wrapper
   2363             initObserver(s.wrapper[0], {attributes: false});
   2364         };
   2365         s.disconnectObservers = function () {
   2366             for (var i = 0; i < s.observers.length; i++) {
   2367                 s.observers[i].disconnect();
   2368             }
   2369             s.observers = [];
   2370         };
   2371         /*=========================
   2372           Loop
   2373           ===========================*/
   2374         // Create looped slides
   2375         s.createLoop = function () {
   2376             // Remove duplicated slides
   2377             s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
   2378         
   2379             var slides = s.wrapper.children('.' + s.params.slideClass);
   2380         
   2381             if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;
   2382         
   2383             s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
   2384             s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
   2385             if (s.loopedSlides > slides.length) {
   2386                 s.loopedSlides = slides.length;
   2387             }
   2388         
   2389             var prependSlides = [], appendSlides = [], i;
   2390             slides.each(function (index, el) {
   2391                 var slide = $(this);
   2392                 if (index < s.loopedSlides) appendSlides.push(el);
   2393                 if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
   2394                 slide.attr('data-swiper-slide-index', index);
   2395             });
   2396             for (i = 0; i < appendSlides.length; i++) {
   2397                 s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
   2398             }
   2399             for (i = prependSlides.length - 1; i >= 0; i--) {
   2400                 s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
   2401             }
   2402         };
   2403         s.destroyLoop = function () {
   2404             s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
   2405             s.slides.removeAttr('data-swiper-slide-index');
   2406         };
   2407         s.reLoop = function (updatePosition) {
   2408             var oldIndex = s.activeIndex - s.loopedSlides;
   2409             s.destroyLoop();
   2410             s.createLoop();
   2411             s.updateSlidesSize();
   2412             if (updatePosition) {
   2413                 s.slideTo(oldIndex + s.loopedSlides, 0, false);
   2414             }
   2415         
   2416         };
   2417         s.fixLoop = function () {
   2418             var newIndex;
   2419             //Fix For Negative Oversliding
   2420             if (s.activeIndex < s.loopedSlides) {
   2421                 newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
   2422                 newIndex = newIndex + s.loopedSlides;
   2423                 s.slideTo(newIndex, 0, false, true);
   2424             }
   2425             //Fix For Positive Oversliding
   2426             else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
   2427                 newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
   2428                 newIndex = newIndex + s.loopedSlides;
   2429                 s.slideTo(newIndex, 0, false, true);
   2430             }
   2431         };
   2432         /*=========================
   2433           Append/Prepend/Remove Slides
   2434           ===========================*/
   2435         s.appendSlide = function (slides) {
   2436             if (s.params.loop) {
   2437                 s.destroyLoop();
   2438             }
   2439             if (typeof slides === 'object' && slides.length) {
   2440                 for (var i = 0; i < slides.length; i++) {
   2441                     if (slides[i]) s.wrapper.append(slides[i]);
   2442                 }
   2443             }
   2444             else {
   2445                 s.wrapper.append(slides);
   2446             }
   2447             if (s.params.loop) {
   2448                 s.createLoop();
   2449             }
   2450             if (!(s.params.observer && s.support.observer)) {
   2451                 s.update(true);
   2452             }
   2453         };
   2454         s.prependSlide = function (slides) {
   2455             if (s.params.loop) {
   2456                 s.destroyLoop();
   2457             }
   2458             var newActiveIndex = s.activeIndex + 1;
   2459             if (typeof slides === 'object' && slides.length) {
   2460                 for (var i = 0; i < slides.length; i++) {
   2461                     if (slides[i]) s.wrapper.prepend(slides[i]);
   2462                 }
   2463                 newActiveIndex = s.activeIndex + slides.length;
   2464             }
   2465             else {
   2466                 s.wrapper.prepend(slides);
   2467             }
   2468             if (s.params.loop) {
   2469                 s.createLoop();
   2470             }
   2471             if (!(s.params.observer && s.support.observer)) {
   2472                 s.update(true);
   2473             }
   2474             s.slideTo(newActiveIndex, 0, false);
   2475         };
   2476         s.removeSlide = function (slidesIndexes) {
   2477             if (s.params.loop) {
   2478                 s.destroyLoop();
   2479                 s.slides = s.wrapper.children('.' + s.params.slideClass);
   2480             }
   2481             var newActiveIndex = s.activeIndex,
   2482                 indexToRemove;
   2483             if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
   2484                 for (var i = 0; i < slidesIndexes.length; i++) {
   2485                     indexToRemove = slidesIndexes[i];
   2486                     if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
   2487                     if (indexToRemove < newActiveIndex) newActiveIndex--;
   2488                 }
   2489                 newActiveIndex = Math.max(newActiveIndex, 0);
   2490             }
   2491             else {
   2492                 indexToRemove = slidesIndexes;
   2493                 if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
   2494                 if (indexToRemove < newActiveIndex) newActiveIndex--;
   2495                 newActiveIndex = Math.max(newActiveIndex, 0);
   2496             }
   2497         
   2498             if (s.params.loop) {
   2499                 s.createLoop();
   2500             }
   2501         
   2502             if (!(s.params.observer && s.support.observer)) {
   2503                 s.update(true);
   2504             }
   2505             if (s.params.loop) {
   2506                 s.slideTo(newActiveIndex + s.loopedSlides, 0, false);
   2507             }
   2508             else {
   2509                 s.slideTo(newActiveIndex, 0, false);
   2510             }
   2511         
   2512         };
   2513         s.removeAllSlides = function () {
   2514             var slidesIndexes = [];
   2515             for (var i = 0; i < s.slides.length; i++) {
   2516                 slidesIndexes.push(i);
   2517             }
   2518             s.removeSlide(slidesIndexes);
   2519         };
   2520         
   2521 
   2522         /*=========================
   2523           Effects
   2524           ===========================*/
   2525         s.effects = {
   2526             fade: {
   2527                 setTranslate: function () {
   2528                     for (var i = 0; i < s.slides.length; i++) {
   2529                         var slide = s.slides.eq(i);
   2530                         var offset = slide[0].swiperSlideOffset;
   2531                         var tx = -offset;
   2532                         if (!s.params.virtualTranslate) tx = tx - s.translate;
   2533                         var ty = 0;
   2534                         if (!s.isHorizontal()) {
   2535                             ty = tx;
   2536                             tx = 0;
   2537                         }
   2538                         var slideOpacity = s.params.fade.crossFade ?
   2539                                 Math.max(1 - Math.abs(slide[0].progress), 0) :
   2540                                 1 + Math.min(Math.max(slide[0].progress, -1), 0);
   2541                         slide
   2542                             .css({
   2543                                 opacity: slideOpacity
   2544                             })
   2545                             .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
   2546         
   2547                     }
   2548         
   2549                 },
   2550                 setTransition: function (duration) {
   2551                     s.slides.transition(duration);
   2552                     if (s.params.virtualTranslate && duration !== 0) {
   2553                         var eventTriggered = false;
   2554                         s.slides.transitionEnd(function () {
   2555                             if (eventTriggered) return;
   2556                             if (!s) return;
   2557                             eventTriggered = true;
   2558                             s.animating = false;
   2559                             var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
   2560                             for (var i = 0; i < triggerEvents.length; i++) {
   2561                                 s.wrapper.trigger(triggerEvents[i]);
   2562                             }
   2563                         });
   2564                     }
   2565                 }
   2566             },
   2567             flip: {
   2568                 setTranslate: function () {
   2569                     for (var i = 0; i < s.slides.length; i++) {
   2570                         var slide = s.slides.eq(i);
   2571                         var progress = slide[0].progress;
   2572                         if (s.params.flip.limitRotation) {
   2573                             progress = Math.max(Math.min(slide[0].progress, 1), -1);
   2574                         }
   2575                         var offset = slide[0].swiperSlideOffset;
   2576                         var rotate = -180 * progress,
   2577                             rotateY = rotate,
   2578                             rotateX = 0,
   2579                             tx = -offset,
   2580                             ty = 0;
   2581                         if (!s.isHorizontal()) {
   2582                             ty = tx;
   2583                             tx = 0;
   2584                             rotateX = -rotateY;
   2585                             rotateY = 0;
   2586                         }
   2587                         else if (s.rtl) {
   2588                             rotateY = -rotateY;
   2589                         }
   2590         
   2591                         slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;
   2592         
   2593                         if (s.params.flip.slideShadows) {
   2594                             //Set shadows
   2595                             var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
   2596                             var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
   2597                             if (shadowBefore.length === 0) {
   2598                                 shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
   2599                                 slide.append(shadowBefore);
   2600                             }
   2601                             if (shadowAfter.length === 0) {
   2602                                 shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
   2603                                 slide.append(shadowAfter);
   2604                             }
   2605                             if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
   2606                             if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
   2607                         }
   2608         
   2609                         slide
   2610                             .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');
   2611                     }
   2612                 },
   2613                 setTransition: function (duration) {
   2614                     s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
   2615                     if (s.params.virtualTranslate && duration !== 0) {
   2616                         var eventTriggered = false;
   2617                         s.slides.eq(s.activeIndex).transitionEnd(function () {
   2618                             if (eventTriggered) return;
   2619                             if (!s) return;
   2620                             if (!$(this).hasClass(s.params.slideActiveClass)) return;
   2621                             eventTriggered = true;
   2622                             s.animating = false;
   2623                             var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
   2624                             for (var i = 0; i < triggerEvents.length; i++) {
   2625                                 s.wrapper.trigger(triggerEvents[i]);
   2626                             }
   2627                         });
   2628                     }
   2629                 }
   2630             },
   2631             cube: {
   2632                 setTranslate: function () {
   2633                     var wrapperRotate = 0, cubeShadow;
   2634                     if (s.params.cube.shadow) {
   2635                         if (s.isHorizontal()) {
   2636                             cubeShadow = s.wrapper.find('.swiper-cube-shadow');
   2637                             if (cubeShadow.length === 0) {
   2638                                 cubeShadow = $('<div class="swiper-cube-shadow"></div>');
   2639                                 s.wrapper.append(cubeShadow);
   2640                             }
   2641                             cubeShadow.css({height: s.width + 'px'});
   2642                         }
   2643                         else {
   2644                             cubeShadow = s.container.find('.swiper-cube-shadow');
   2645                             if (cubeShadow.length === 0) {
   2646                                 cubeShadow = $('<div class="swiper-cube-shadow"></div>');
   2647                                 s.container.append(cubeShadow);
   2648                             }
   2649                         }
   2650                     }
   2651                     for (var i = 0; i < s.slides.length; i++) {
   2652                         var slide = s.slides.eq(i);
   2653                         var slideAngle = i * 90;
   2654                         var round = Math.floor(slideAngle / 360);
   2655                         if (s.rtl) {
   2656                             slideAngle = -slideAngle;
   2657                             round = Math.floor(-slideAngle / 360);
   2658                         }
   2659                         var progress = Math.max(Math.min(slide[0].progress, 1), -1);
   2660                         var tx = 0, ty = 0, tz = 0;
   2661                         if (i % 4 === 0) {
   2662                             tx = - round * 4 * s.size;
   2663                             tz = 0;
   2664                         }
   2665                         else if ((i - 1) % 4 === 0) {
   2666                             tx = 0;
   2667                             tz = - round * 4 * s.size;
   2668                         }
   2669                         else if ((i - 2) % 4 === 0) {
   2670                             tx = s.size + round * 4 * s.size;
   2671                             tz = s.size;
   2672                         }
   2673                         else if ((i - 3) % 4 === 0) {
   2674                             tx = - s.size;
   2675                             tz = 3 * s.size + s.size * 4 * round;
   2676                         }
   2677                         if (s.rtl) {
   2678                             tx = -tx;
   2679                         }
   2680         
   2681                         if (!s.isHorizontal()) {
   2682                             ty = tx;
   2683                             tx = 0;
   2684                         }
   2685         
   2686                         var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
   2687                         if (progress <= 1 && progress > -1) {
   2688                             wrapperRotate = i * 90 + progress * 90;
   2689                             if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
   2690                         }
   2691                         slide.transform(transform);
   2692                         if (s.params.cube.slideShadows) {
   2693                             //Set shadows
   2694                             var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
   2695                             var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
   2696                             if (shadowBefore.length === 0) {
   2697                                 shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
   2698                                 slide.append(shadowBefore);
   2699                             }
   2700                             if (shadowAfter.length === 0) {
   2701                                 shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
   2702                                 slide.append(shadowAfter);
   2703                             }
   2704                             if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
   2705                             if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
   2706                         }
   2707                     }
   2708                     s.wrapper.css({
   2709                         '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
   2710                         '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
   2711                         '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
   2712                         'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
   2713                     });
   2714         
   2715                     if (s.params.cube.shadow) {
   2716                         if (s.isHorizontal()) {
   2717                             cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');
   2718                         }
   2719                         else {
   2720                             var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
   2721                             var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
   2722                             var scale1 = s.params.cube.shadowScale,
   2723                                 scale2 = s.params.cube.shadowScale / multiplier,
   2724                                 offset = s.params.cube.shadowOffset;
   2725                             cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
   2726                         }
   2727                     }
   2728                     var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
   2729                     s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');
   2730                 },
   2731                 setTransition: function (duration) {
   2732                     s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
   2733                     if (s.params.cube.shadow && !s.isHorizontal()) {
   2734                         s.container.find('.swiper-cube-shadow').transition(duration);
   2735                     }
   2736                 }
   2737             },
   2738             coverflow: {
   2739                 setTranslate: function () {
   2740                     var transform = s.translate;
   2741                     var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;
   2742                     var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
   2743                     var translate = s.params.coverflow.depth;
   2744                     //Each slide offset from center
   2745                     for (var i = 0, length = s.slides.length; i < length; i++) {
   2746                         var slide = s.slides.eq(i);
   2747                         var slideSize = s.slidesSizesGrid[i];
   2748                         var slideOffset = slide[0].swiperSlideOffset;
   2749                         var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
   2750         
   2751                         var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;
   2752                         var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;
   2753                         // var rotateZ = 0
   2754                         var translateZ = -translate * Math.abs(offsetMultiplier);
   2755         
   2756                         var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
   2757                         var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
   2758         
   2759                         //Fix for ultra small values
   2760                         if (Math.abs(translateX) < 0.001) translateX = 0;
   2761                         if (Math.abs(translateY) < 0.001) translateY = 0;
   2762                         if (Math.abs(translateZ) < 0.001) translateZ = 0;
   2763                         if (Math.abs(rotateY) < 0.001) rotateY = 0;
   2764                         if (Math.abs(rotateX) < 0.001) rotateX = 0;
   2765         
   2766                         var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
   2767         
   2768                         slide.transform(slideTransform);
   2769                         slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
   2770                         if (s.params.coverflow.slideShadows) {
   2771                             //Set shadows
   2772                             var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
   2773                             var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
   2774                             if (shadowBefore.length === 0) {
   2775                                 shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
   2776                                 slide.append(shadowBefore);
   2777                             }
   2778                             if (shadowAfter.length === 0) {
   2779                                 shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
   2780                                 slide.append(shadowAfter);
   2781                             }
   2782                             if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
   2783                             if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
   2784                         }
   2785                     }
   2786         
   2787                     //Set correct perspective for IE10
   2788                     if (s.browser.ie) {
   2789                         var ws = s.wrapper[0].style;
   2790                         ws.perspectiveOrigin = center + 'px 50%';
   2791                     }
   2792                 },
   2793                 setTransition: function (duration) {
   2794                     s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
   2795                 }
   2796             }
   2797         };
   2798         
   2799 
   2800         /*=========================
   2801           Images Lazy Loading
   2802           ===========================*/
   2803         s.lazy = {
   2804             initialImageLoaded: false,
   2805             loadImageInSlide: function (index, loadInDuplicate) {
   2806                 if (typeof index === 'undefined') return;
   2807                 if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;
   2808                 if (s.slides.length === 0) return;
   2809         
   2810                 var slide = s.slides.eq(index);
   2811                 var img = slide.find('.' + s.params.lazyLoadingClass + ':not(.' + s.params.lazyStatusLoadedClass + '):not(.' + s.params.lazyStatusLoadingClass + ')');
   2812                 if (slide.hasClass(s.params.lazyLoadingClass) && !slide.hasClass(s.params.lazyStatusLoadedClass) && !slide.hasClass(s.params.lazyStatusLoadingClass)) {
   2813                     img = img.add(slide[0]);
   2814                 }
   2815                 if (img.length === 0) return;
   2816         
   2817                 img.each(function () {
   2818                     var _img = $(this);
   2819                     _img.addClass(s.params.lazyStatusLoadingClass);
   2820                     var background = _img.attr('data-background');
   2821                     var src = _img.attr('data-src'),
   2822                         srcset = _img.attr('data-srcset'),
   2823                         sizes = _img.attr('data-sizes');
   2824                     s.loadImage(_img[0], (src || background), srcset, sizes, false, function () {
   2825                         if (typeof s === 'undefined' || s === null || !s) return;
   2826                         if (background) {
   2827                             _img.css('background-image', 'url("' + background + '")');
   2828                             _img.removeAttr('data-background');
   2829                         }
   2830                         else {
   2831                             if (srcset) {
   2832                                 _img.attr('srcset', srcset);
   2833                                 _img.removeAttr('data-srcset');
   2834                             }
   2835                             if (sizes) {
   2836                                 _img.attr('sizes', sizes);
   2837                                 _img.removeAttr('data-sizes');
   2838                             }
   2839                             if (src) {
   2840                                 _img.attr('src', src);
   2841                                 _img.removeAttr('data-src');
   2842                             }
   2843         
   2844                         }
   2845         
   2846                         _img.addClass(s.params.lazyStatusLoadedClass).removeClass(s.params.lazyStatusLoadingClass);
   2847                         slide.find('.' + s.params.lazyPreloaderClass + ', .' + s.params.preloaderClass).remove();
   2848                         if (s.params.loop && loadInDuplicate) {
   2849                             var slideOriginalIndex = slide.attr('data-swiper-slide-index');
   2850                             if (slide.hasClass(s.params.slideDuplicateClass)) {
   2851                                 var originalSlide = s.wrapper.children('[data-swiper-slide-index="' + slideOriginalIndex + '"]:not(.' + s.params.slideDuplicateClass + ')');
   2852                                 s.lazy.loadImageInSlide(originalSlide.index(), false);
   2853                             }
   2854                             else {
   2855                                 var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + slideOriginalIndex + '"]');
   2856                                 s.lazy.loadImageInSlide(duplicatedSlide.index(), false);
   2857                             }
   2858                         }
   2859                         s.emit('onLazyImageReady', s, slide[0], _img[0]);
   2860                     });
   2861         
   2862                     s.emit('onLazyImageLoad', s, slide[0], _img[0]);
   2863                 });
   2864         
   2865             },
   2866             load: function () {
   2867                 var i;
   2868                 var slidesPerView = s.params.slidesPerView;
   2869                 if (slidesPerView === 'auto') {
   2870                     slidesPerView = 0;
   2871                 }
   2872                 if (!s.lazy.initialImageLoaded) s.lazy.initialImageLoaded = true;
   2873                 if (s.params.watchSlidesVisibility) {
   2874                     s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
   2875                         s.lazy.loadImageInSlide($(this).index());
   2876                     });
   2877                 }
   2878                 else {
   2879                     if (slidesPerView > 1) {
   2880                         for (i = s.activeIndex; i < s.activeIndex + slidesPerView ; i++) {
   2881                             if (s.slides[i]) s.lazy.loadImageInSlide(i);
   2882                         }
   2883                     }
   2884                     else {
   2885                         s.lazy.loadImageInSlide(s.activeIndex);
   2886                     }
   2887                 }
   2888                 if (s.params.lazyLoadingInPrevNext) {
   2889                     if (slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {
   2890                         var amount = s.params.lazyLoadingInPrevNextAmount;
   2891                         var spv = slidesPerView;
   2892                         var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);
   2893                         var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);
   2894                         // Next Slides
   2895                         for (i = s.activeIndex + slidesPerView; i < maxIndex; i++) {
   2896                             if (s.slides[i]) s.lazy.loadImageInSlide(i);
   2897                         }
   2898                         // Prev Slides
   2899                         for (i = minIndex; i < s.activeIndex ; i++) {
   2900                             if (s.slides[i]) s.lazy.loadImageInSlide(i);
   2901                         }
   2902                     }
   2903                     else {
   2904                         var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
   2905                         if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
   2906         
   2907                         var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
   2908                         if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
   2909                     }
   2910                 }
   2911             },
   2912             onTransitionStart: function () {
   2913                 if (s.params.lazyLoading) {
   2914                     if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
   2915                         s.lazy.load();
   2916                     }
   2917                 }
   2918             },
   2919             onTransitionEnd: function () {
   2920                 if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
   2921                     s.lazy.load();
   2922                 }
   2923             }
   2924         };
   2925         
   2926 
   2927         /*=========================
   2928           Scrollbar
   2929           ===========================*/
   2930         s.scrollbar = {
   2931             isTouched: false,
   2932             setDragPosition: function (e) {
   2933                 var sb = s.scrollbar;
   2934                 var x = 0, y = 0;
   2935                 var translate;
   2936                 var pointerPosition = s.isHorizontal() ?
   2937                     ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :
   2938                     ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;
   2939                 var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;
   2940                 var positionMin = -s.minTranslate() * sb.moveDivider;
   2941                 var positionMax = -s.maxTranslate() * sb.moveDivider;
   2942                 if (position < positionMin) {
   2943                     position = positionMin;
   2944                 }
   2945                 else if (position > positionMax) {
   2946                     position = positionMax;
   2947                 }
   2948                 position = -position / sb.moveDivider;
   2949                 s.updateProgress(position);
   2950                 s.setWrapperTranslate(position, true);
   2951             },
   2952             dragStart: function (e) {
   2953                 var sb = s.scrollbar;
   2954                 sb.isTouched = true;
   2955                 e.preventDefault();
   2956                 e.stopPropagation();
   2957         
   2958                 sb.setDragPosition(e);
   2959                 clearTimeout(sb.dragTimeout);
   2960         
   2961                 sb.track.transition(0);
   2962                 if (s.params.scrollbarHide) {
   2963                     sb.track.css('opacity', 1);
   2964                 }
   2965                 s.wrapper.transition(100);
   2966                 sb.drag.transition(100);
   2967                 s.emit('onScrollbarDragStart', s);
   2968             },
   2969             dragMove: function (e) {
   2970                 var sb = s.scrollbar;
   2971                 if (!sb.isTouched) return;
   2972                 if (e.preventDefault) e.preventDefault();
   2973                 else e.returnValue = false;
   2974                 sb.setDragPosition(e);
   2975                 s.wrapper.transition(0);
   2976                 sb.track.transition(0);
   2977                 sb.drag.transition(0);
   2978                 s.emit('onScrollbarDragMove', s);
   2979             },
   2980             dragEnd: function (e) {
   2981                 var sb = s.scrollbar;
   2982                 if (!sb.isTouched) return;
   2983                 sb.isTouched = false;
   2984                 if (s.params.scrollbarHide) {
   2985                     clearTimeout(sb.dragTimeout);
   2986                     sb.dragTimeout = setTimeout(function () {
   2987                         sb.track.css('opacity', 0);
   2988                         sb.track.transition(400);
   2989                     }, 1000);
   2990         
   2991                 }
   2992                 s.emit('onScrollbarDragEnd', s);
   2993                 if (s.params.scrollbarSnapOnRelease) {
   2994                     s.slideReset();
   2995                 }
   2996             },
   2997             draggableEvents: (function () {
   2998                 if ((s.params.simulateTouch === false && !s.support.touch)) return s.touchEventsDesktop;
   2999                 else return s.touchEvents;
   3000             })(),
   3001             enableDraggable: function () {
   3002                 var sb = s.scrollbar;
   3003                 var target = s.support.touch ? sb.track : document;
   3004                 $(sb.track).on(sb.draggableEvents.start, sb.dragStart);
   3005                 $(target).on(sb.draggableEvents.move, sb.dragMove);
   3006                 $(target).on(sb.draggableEvents.end, sb.dragEnd);
   3007             },
   3008             disableDraggable: function () {
   3009                 var sb = s.scrollbar;
   3010                 var target = s.support.touch ? sb.track : document;
   3011                 $(sb.track).off(sb.draggableEvents.start, sb.dragStart);
   3012                 $(target).off(sb.draggableEvents.move, sb.dragMove);
   3013                 $(target).off(sb.draggableEvents.end, sb.dragEnd);
   3014             },
   3015             set: function () {
   3016                 if (!s.params.scrollbar) return;
   3017                 var sb = s.scrollbar;
   3018                 sb.track = $(s.params.scrollbar);
   3019                 if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {
   3020                     sb.track = s.container.find(s.params.scrollbar);
   3021                 }
   3022                 sb.drag = sb.track.find('.swiper-scrollbar-drag');
   3023                 if (sb.drag.length === 0) {
   3024                     sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
   3025                     sb.track.append(sb.drag);
   3026                 }
   3027                 sb.drag[0].style.width = '';
   3028                 sb.drag[0].style.height = '';
   3029                 sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
   3030         
   3031                 sb.divider = s.size / s.virtualSize;
   3032                 sb.moveDivider = sb.divider * (sb.trackSize / s.size);
   3033                 sb.dragSize = sb.trackSize * sb.divider;
   3034         
   3035                 if (s.isHorizontal()) {
   3036                     sb.drag[0].style.width = sb.dragSize + 'px';
   3037                 }
   3038                 else {
   3039                     sb.drag[0].style.height = sb.dragSize + 'px';
   3040                 }
   3041         
   3042                 if (sb.divider >= 1) {
   3043                     sb.track[0].style.display = 'none';
   3044                 }
   3045                 else {
   3046                     sb.track[0].style.display = '';
   3047                 }
   3048                 if (s.params.scrollbarHide) {
   3049                     sb.track[0].style.opacity = 0;
   3050                 }
   3051             },
   3052             setTranslate: function () {
   3053                 if (!s.params.scrollbar) return;
   3054                 var diff;
   3055                 var sb = s.scrollbar;
   3056                 var translate = s.translate || 0;
   3057                 var newPos;
   3058         
   3059                 var newSize = sb.dragSize;
   3060                 newPos = (sb.trackSize - sb.dragSize) * s.progress;
   3061                 if (s.rtl && s.isHorizontal()) {
   3062                     newPos = -newPos;
   3063                     if (newPos > 0) {
   3064                         newSize = sb.dragSize - newPos;
   3065                         newPos = 0;
   3066                     }
   3067                     else if (-newPos + sb.dragSize > sb.trackSize) {
   3068                         newSize = sb.trackSize + newPos;
   3069                     }
   3070                 }
   3071                 else {
   3072                     if (newPos < 0) {
   3073                         newSize = sb.dragSize + newPos;
   3074                         newPos = 0;
   3075                     }
   3076                     else if (newPos + sb.dragSize > sb.trackSize) {
   3077                         newSize = sb.trackSize - newPos;
   3078                     }
   3079                 }
   3080                 if (s.isHorizontal()) {
   3081                     if (s.support.transforms3d) {
   3082                         sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
   3083                     }
   3084                     else {
   3085                         sb.drag.transform('translateX(' + (newPos) + 'px)');
   3086                     }
   3087                     sb.drag[0].style.width = newSize + 'px';
   3088                 }
   3089                 else {
   3090                     if (s.support.transforms3d) {
   3091                         sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
   3092                     }
   3093                     else {
   3094                         sb.drag.transform('translateY(' + (newPos) + 'px)');
   3095                     }
   3096                     sb.drag[0].style.height = newSize + 'px';
   3097                 }
   3098                 if (s.params.scrollbarHide) {
   3099                     clearTimeout(sb.timeout);
   3100                     sb.track[0].style.opacity = 1;
   3101                     sb.timeout = setTimeout(function () {
   3102                         sb.track[0].style.opacity = 0;
   3103                         sb.track.transition(400);
   3104                     }, 1000);
   3105                 }
   3106             },
   3107             setTransition: function (duration) {
   3108                 if (!s.params.scrollbar) return;
   3109                 s.scrollbar.drag.transition(duration);
   3110             }
   3111         };
   3112         
   3113 
   3114         /*=========================
   3115           Controller
   3116           ===========================*/
   3117         s.controller = {
   3118             LinearSpline: function (x, y) {
   3119                 var binarySearch = (function() {
   3120                     var maxIndex, minIndex, guess;
   3121                     return function(array, val) {
   3122                         minIndex = -1;
   3123                         maxIndex = array.length;
   3124                         while (maxIndex - minIndex > 1)
   3125                             if (array[guess = maxIndex + minIndex >> 1] <= val) {
   3126                                 minIndex = guess;
   3127                             } else {
   3128                                 maxIndex = guess;
   3129                             }
   3130                         return maxIndex;
   3131                     };
   3132                 })();
   3133                 this.x = x;
   3134                 this.y = y;
   3135                 this.lastIndex = x.length - 1;
   3136                 // Given an x value (x2), return the expected y2 value:
   3137                 // (x1,y1) is the known point before given value,
   3138                 // (x3,y3) is the known point after given value.
   3139                 var i1, i3;
   3140                 var l = this.x.length;
   3141         
   3142                 this.interpolate = function (x2) {
   3143                     if (!x2) return 0;
   3144         
   3145                     // Get the indexes of x1 and x3 (the array indexes before and after given x2):
   3146                     i3 = binarySearch(this.x, x2);
   3147                     i1 = i3 - 1;
   3148         
   3149                     // We have our indexes i1 & i3, so we can calculate already:
   3150                     // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
   3151                     return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
   3152                 };
   3153             },
   3154             //xxx: for now i will just save one spline function to to
   3155             getInterpolateFunction: function(c){
   3156                 if(!s.controller.spline) s.controller.spline = s.params.loop ?
   3157                     new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :
   3158                     new s.controller.LinearSpline(s.snapGrid, c.snapGrid);
   3159             },
   3160             setTranslate: function (translate, byController) {
   3161                var controlled = s.params.control;
   3162                var multiplier, controlledTranslate;
   3163                function setControlledTranslate(c) {
   3164                     // this will create an Interpolate function based on the snapGrids
   3165                     // x is the Grid of the scrolled scroller and y will be the controlled scroller
   3166                     // it makes sense to create this only once and recall it for the interpolation
   3167                     // the function does a lot of value caching for performance
   3168                     translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;
   3169                     if (s.params.controlBy === 'slide') {
   3170                         s.controller.getInterpolateFunction(c);
   3171                         // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
   3172                         // but it did not work out
   3173                         controlledTranslate = -s.controller.spline.interpolate(-translate);
   3174                     }
   3175         
   3176                     if(!controlledTranslate || s.params.controlBy === 'container'){
   3177                         multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());
   3178                         controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();
   3179                     }
   3180         
   3181                     if (s.params.controlInverse) {
   3182                         controlledTranslate = c.maxTranslate() - controlledTranslate;
   3183                     }
   3184                     c.updateProgress(controlledTranslate);
   3185                     c.setWrapperTranslate(controlledTranslate, false, s);
   3186                     c.updateActiveIndex();
   3187                }
   3188                if (Array.isArray(controlled)) {
   3189                    for (var i = 0; i < controlled.length; i++) {
   3190                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
   3191                            setControlledTranslate(controlled[i]);
   3192                        }
   3193                    }
   3194                }
   3195                else if (controlled instanceof Swiper && byController !== controlled) {
   3196         
   3197                    setControlledTranslate(controlled);
   3198                }
   3199             },
   3200             setTransition: function (duration, byController) {
   3201                 var controlled = s.params.control;
   3202                 var i;
   3203                 function setControlledTransition(c) {
   3204                     c.setWrapperTransition(duration, s);
   3205                     if (duration !== 0) {
   3206                         c.onTransitionStart();
   3207                         c.wrapper.transitionEnd(function(){
   3208                             if (!controlled) return;
   3209                             if (c.params.loop && s.params.controlBy === 'slide') {
   3210                                 c.fixLoop();
   3211                             }
   3212                             c.onTransitionEnd();
   3213         
   3214                         });
   3215                     }
   3216                 }
   3217                 if (Array.isArray(controlled)) {
   3218                     for (i = 0; i < controlled.length; i++) {
   3219                         if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
   3220                             setControlledTransition(controlled[i]);
   3221                         }
   3222                     }
   3223                 }
   3224                 else if (controlled instanceof Swiper && byController !== controlled) {
   3225                     setControlledTransition(controlled);
   3226                 }
   3227             }
   3228         };
   3229         
   3230 
   3231         /*=========================
   3232           Hash Navigation
   3233           ===========================*/
   3234         s.hashnav = {
   3235             onHashCange: function (e, a) {
   3236                 var newHash = document.location.hash.replace('#', '');
   3237                 var activeSlideHash = s.slides.eq(s.activeIndex).attr('data-hash');
   3238                 if (newHash !== activeSlideHash) {
   3239                     s.slideTo(s.wrapper.children('.' + s.params.slideClass + '[data-hash="' + (newHash) + '"]').index());
   3240                 }
   3241             },
   3242             attachEvents: function (detach) {
   3243                 var action = detach ? 'off' : 'on';
   3244                 $(window)[action]('hashchange', s.hashnav.onHashCange);
   3245             },
   3246             setHash: function () {
   3247                 if (!s.hashnav.initialized || !s.params.hashnav) return;
   3248                 if (s.params.replaceState && window.history && window.history.replaceState) {
   3249                     window.history.replaceState(null, null, ('#' + s.slides.eq(s.activeIndex).attr('data-hash') || ''));
   3250                 } else {
   3251                     var slide = s.slides.eq(s.activeIndex);
   3252                     var hash = slide.attr('data-hash') || slide.attr('data-history');
   3253                     document.location.hash = hash || '';
   3254                 }
   3255             },
   3256             init: function () {
   3257                 if (!s.params.hashnav || s.params.history) return;
   3258                 s.hashnav.initialized = true;
   3259                 var hash = document.location.hash.replace('#', '');
   3260                 if (hash) {
   3261                     var speed = 0;
   3262                     for (var i = 0, length = s.slides.length; i < length; i++) {
   3263                         var slide = s.slides.eq(i);
   3264                         var slideHash = slide.attr('data-hash') || slide.attr('data-history');
   3265                         if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {
   3266                             var index = slide.index();
   3267                             s.slideTo(index, speed, s.params.runCallbacksOnInit, true);
   3268                         }
   3269                     }
   3270                 }
   3271                 if (s.params.hashnavWatchState) s.hashnav.attachEvents();
   3272             },
   3273             destroy: function () {
   3274                 if (s.params.hashnavWatchState) s.hashnav.attachEvents(true);
   3275             }
   3276         };
   3277         
   3278 
   3279         /*=========================
   3280           History Api with fallback to Hashnav
   3281           ===========================*/
   3282         s.history = {
   3283             init: function () {
   3284                 if (!s.params.history) return;
   3285                 if (!window.history || !window.history.pushState) {
   3286                     s.params.history = false;
   3287                     s.params.hashnav = true;
   3288                     return;
   3289                 }
   3290                 s.history.initialized = true;
   3291                 this.paths = this.getPathValues();
   3292                 if (!this.paths.key && !this.paths.value) return;
   3293                 this.scrollToSlide(0, this.paths.value, s.params.runCallbacksOnInit);
   3294                 if (!s.params.replaceState) {
   3295                     window.addEventListener('popstate', this.setHistoryPopState);
   3296                 }
   3297             },
   3298             setHistoryPopState: function() {
   3299                 s.history.paths = s.history.getPathValues();
   3300                 s.history.scrollToSlide(s.params.speed, s.history.paths.value, false);
   3301             },
   3302             getPathValues: function() {
   3303                 var pathArray = window.location.pathname.slice(1).split('/');
   3304                 var total = pathArray.length;
   3305                 var key = pathArray[total - 2];
   3306                 var value = pathArray[total - 1];
   3307                 return { key: key, value: value };
   3308             },
   3309             setHistory: function (key, index) {
   3310                 if (!s.history.initialized || !s.params.history) return;
   3311                 var slide = s.slides.eq(index);
   3312                 var value = this.slugify(slide.attr('data-history'));
   3313                 if (!window.location.pathname.includes(key)) {
   3314                     value = key + '/' + value;
   3315                 }
   3316                 if (s.params.replaceState) {
   3317                     window.history.replaceState(null, null, value);
   3318                 } else {
   3319                     window.history.pushState(null, null, value);
   3320                 }
   3321             },
   3322             slugify: function(text) {
   3323                 return text.toString().toLowerCase()
   3324                     .replace(/\s+/g, '-')
   3325                     .replace(/[^\w\-]+/g, '')
   3326                     .replace(/\-\-+/g, '-')
   3327                     .replace(/^-+/, '')
   3328                     .replace(/-+$/, '');
   3329             },
   3330             scrollToSlide: function(speed, value, runCallbacks) {
   3331                 if (value) {
   3332                     for (var i = 0, length = s.slides.length; i < length; i++) {
   3333                         var slide = s.slides.eq(i);
   3334                         var slideHistory = this.slugify(slide.attr('data-history'));
   3335                         if (slideHistory === value && !slide.hasClass(s.params.slideDuplicateClass)) {
   3336                             var index = slide.index();
   3337                             s.slideTo(index, speed, runCallbacks);
   3338                         }
   3339                     }
   3340                 } else {
   3341                     s.slideTo(0, speed, runCallbacks);
   3342                 }
   3343             }
   3344         };
   3345         
   3346 
   3347         /*=========================
   3348           Keyboard Control
   3349           ===========================*/
   3350         function handleKeyboard(e) {
   3351             if (e.originalEvent) e = e.originalEvent; //jquery fix
   3352             var kc = e.keyCode || e.charCode;
   3353             // Directions locks
   3354             if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {
   3355                 return false;
   3356             }
   3357             if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {
   3358                 return false;
   3359             }
   3360             if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
   3361                 return;
   3362             }
   3363             if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
   3364                 return;
   3365             }
   3366             if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
   3367                 var inView = false;
   3368                 //Check that swiper should be inside of visible area of window
   3369                 if (s.container.parents('.' + s.params.slideClass).length > 0 && s.container.parents('.' + s.params.slideActiveClass).length === 0) {
   3370                     return;
   3371                 }
   3372                 var windowScroll = {
   3373                     left: window.pageXOffset,
   3374                     top: window.pageYOffset
   3375                 };
   3376                 var windowWidth = window.innerWidth;
   3377                 var windowHeight = window.innerHeight;
   3378                 var swiperOffset = s.container.offset();
   3379                 if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;
   3380                 var swiperCoord = [
   3381                     [swiperOffset.left, swiperOffset.top],
   3382                     [swiperOffset.left + s.width, swiperOffset.top],
   3383                     [swiperOffset.left, swiperOffset.top + s.height],
   3384                     [swiperOffset.left + s.width, swiperOffset.top + s.height]
   3385                 ];
   3386                 for (var i = 0; i < swiperCoord.length; i++) {
   3387                     var point = swiperCoord[i];
   3388                     if (
   3389                         point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
   3390                         point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight
   3391                     ) {
   3392                         inView = true;
   3393                     }
   3394         
   3395                 }
   3396                 if (!inView) return;
   3397             }
   3398             if (s.isHorizontal()) {
   3399                 if (kc === 37 || kc === 39) {
   3400                     if (e.preventDefault) e.preventDefault();
   3401                     else e.returnValue = false;
   3402                 }
   3403                 if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();
   3404                 if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();
   3405             }
   3406             else {
   3407                 if (kc === 38 || kc === 40) {
   3408                     if (e.preventDefault) e.preventDefault();
   3409                     else e.returnValue = false;
   3410                 }
   3411                 if (kc === 40) s.slideNext();
   3412                 if (kc === 38) s.slidePrev();
   3413             }
   3414             s.emit('onKeyPress', s, kc);
   3415         }
   3416         s.disableKeyboardControl = function () {
   3417             s.params.keyboardControl = false;
   3418             $(document).off('keydown', handleKeyboard);
   3419         };
   3420         s.enableKeyboardControl = function () {
   3421             s.params.keyboardControl = true;
   3422             $(document).on('keydown', handleKeyboard);
   3423         };
   3424         
   3425 
   3426         /*=========================
   3427           Mousewheel Control
   3428           ===========================*/
   3429         s.mousewheel = {
   3430             event: false,
   3431             lastScrollTime: (new window.Date()).getTime()
   3432         };
   3433         function isEventSupported() {
   3434             var eventName = 'onwheel';
   3435             var isSupported = eventName in document;
   3436         
   3437             if (!isSupported) {
   3438                 var element = document.createElement('div');
   3439                 element.setAttribute(eventName, 'return;');
   3440                 isSupported = typeof element[eventName] === 'function';
   3441             }
   3442         
   3443             if (!isSupported &&
   3444                 document.implementation &&
   3445                 document.implementation.hasFeature &&
   3446                     // always returns true in newer browsers as per the standard.
   3447                     // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
   3448                 document.implementation.hasFeature('', '') !== true ) {
   3449                 // This is the only way to test support for the `wheel` event in IE9+.
   3450                 isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
   3451             }
   3452         
   3453             return isSupported;
   3454         }
   3455         /**
   3456          * Mouse wheel (and 2-finger trackpad) support on the web sucks.  It is
   3457          * complicated, thus this doc is long and (hopefully) detailed enough to answer
   3458          * your questions.
   3459          *
   3460          * If you need to react to the mouse wheel in a predictable way, this code is
   3461          * like your bestest friend. * hugs *
   3462          *
   3463          * As of today, there are 4 DOM event types you can listen to:
   3464          *
   3465          *   'wheel'                -- Chrome(31+), FF(17+), IE(9+)
   3466          *   'mousewheel'           -- Chrome, IE(6+), Opera, Safari
   3467          *   'MozMousePixelScroll'  -- FF(3.5 only!) (2010-2013) -- don't bother!
   3468          *   'DOMMouseScroll'       -- FF(0.9.7+) since 2003
   3469          *
   3470          * So what to do?  The is the best:
   3471          *
   3472          *   normalizeWheel.getEventType();
   3473          *
   3474          * In your event callback, use this code to get sane interpretation of the
   3475          * deltas.  This code will return an object with properties:
   3476          *
   3477          *   spinX   -- normalized spin speed (use for zoom) - x plane
   3478          *   spinY   -- " - y plane
   3479          *   pixelX  -- normalized distance (to pixels) - x plane
   3480          *   pixelY  -- " - y plane
   3481          *
   3482          * Wheel values are provided by the browser assuming you are using the wheel to
   3483          * scroll a web page by a number of lines or pixels (or pages).  Values can vary
   3484          * significantly on different platforms and browsers, forgetting that you can
   3485          * scroll at different speeds.  Some devices (like trackpads) emit more events
   3486          * at smaller increments with fine granularity, and some emit massive jumps with
   3487          * linear speed or acceleration.
   3488          *
   3489          * This code does its best to normalize the deltas for you:
   3490          *
   3491          *   - spin is trying to normalize how far the wheel was spun (or trackpad
   3492          *     dragged).  This is super useful for zoom support where you want to
   3493          *     throw away the chunky scroll steps on the PC and make those equal to
   3494          *     the slow and smooth tiny steps on the Mac. Key data: This code tries to
   3495          *     resolve a single slow step on a wheel to 1.
   3496          *
   3497          *   - pixel is normalizing the desired scroll delta in pixel units.  You'll
   3498          *     get the crazy differences between browsers, but at least it'll be in
   3499          *     pixels!
   3500          *
   3501          *   - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT.  This
   3502          *     should translate to positive value zooming IN, negative zooming OUT.
   3503          *     This matches the newer 'wheel' event.
   3504          *
   3505          * Why are there spinX, spinY (or pixels)?
   3506          *
   3507          *   - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn
   3508          *     with a mouse.  It results in side-scrolling in the browser by default.
   3509          *
   3510          *   - spinY is what you expect -- it's the classic axis of a mouse wheel.
   3511          *
   3512          *   - I dropped spinZ/pixelZ.  It is supported by the DOM 3 'wheel' event and
   3513          *     probably is by browsers in conjunction with fancy 3D controllers .. but
   3514          *     you know.
   3515          *
   3516          * Implementation info:
   3517          *
   3518          * Examples of 'wheel' event if you scroll slowly (down) by one step with an
   3519          * average mouse:
   3520          *
   3521          *   OS X + Chrome  (mouse)     -    4   pixel delta  (wheelDelta -120)
   3522          *   OS X + Safari  (mouse)     -  N/A   pixel delta  (wheelDelta  -12)
   3523          *   OS X + Firefox (mouse)     -    0.1 line  delta  (wheelDelta  N/A)
   3524          *   Win8 + Chrome  (mouse)     -  100   pixel delta  (wheelDelta -120)
   3525          *   Win8 + Firefox (mouse)     -    3   line  delta  (wheelDelta -120)
   3526          *
   3527          * On the trackpad:
   3528          *
   3529          *   OS X + Chrome  (trackpad)  -    2   pixel delta  (wheelDelta   -6)
   3530          *   OS X + Firefox (trackpad)  -    1   pixel delta  (wheelDelta  N/A)
   3531          *
   3532          * On other/older browsers.. it's more complicated as there can be multiple and
   3533          * also missing delta values.
   3534          *
   3535          * The 'wheel' event is more standard:
   3536          *
   3537          * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
   3538          *
   3539          * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and
   3540          * deltaX, deltaY and deltaZ.  Some browsers provide other values to maintain
   3541          * backward compatibility with older events.  Those other values help us
   3542          * better normalize spin speed.  Example of what the browsers provide:
   3543          *
   3544          *                          | event.wheelDelta | event.detail
   3545          *        ------------------+------------------+--------------
   3546          *          Safari v5/OS X  |       -120       |       0
   3547          *          Safari v5/Win7  |       -120       |       0
   3548          *         Chrome v17/OS X  |       -120       |       0
   3549          *         Chrome v17/Win7  |       -120       |       0
   3550          *                IE9/Win7  |       -120       |   undefined
   3551          *         Firefox v4/OS X  |     undefined    |       1
   3552          *         Firefox v4/Win7  |     undefined    |       3
   3553          *
   3554          */
   3555         function normalizeWheel( /*object*/ event ) /*object*/ {
   3556             // Reasonable defaults
   3557             var PIXEL_STEP = 10;
   3558             var LINE_HEIGHT = 40;
   3559             var PAGE_HEIGHT = 800;
   3560         
   3561             var sX = 0, sY = 0,       // spinX, spinY
   3562                 pX = 0, pY = 0;       // pixelX, pixelY
   3563         
   3564             // Legacy
   3565             if( 'detail' in event ) {
   3566                 sY = event.detail;
   3567             }
   3568             if( 'wheelDelta' in event ) {
   3569                 sY = -event.wheelDelta / 120;
   3570             }
   3571             if( 'wheelDeltaY' in event ) {
   3572                 sY = -event.wheelDeltaY / 120;
   3573             }
   3574             if( 'wheelDeltaX' in event ) {
   3575                 sX = -event.wheelDeltaX / 120;
   3576             }
   3577         
   3578             // side scrolling on FF with DOMMouseScroll
   3579             if( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {
   3580                 sX = sY;
   3581                 sY = 0;
   3582             }
   3583         
   3584             pX = sX * PIXEL_STEP;
   3585             pY = sY * PIXEL_STEP;
   3586         
   3587             if( 'deltaY' in event ) {
   3588                 pY = event.deltaY;
   3589             }
   3590             if( 'deltaX' in event ) {
   3591                 pX = event.deltaX;
   3592             }
   3593         
   3594             if( (pX || pY) && event.deltaMode ) {
   3595                 if( event.deltaMode === 1 ) {          // delta in LINE units
   3596                     pX *= LINE_HEIGHT;
   3597                     pY *= LINE_HEIGHT;
   3598                 } else {                             // delta in PAGE units
   3599                     pX *= PAGE_HEIGHT;
   3600                     pY *= PAGE_HEIGHT;
   3601                 }
   3602             }
   3603         
   3604             // Fall-back if spin cannot be determined
   3605             if( pX && !sX ) {
   3606                 sX = (pX < 1) ? -1 : 1;
   3607             }
   3608             if( pY && !sY ) {
   3609                 sY = (pY < 1) ? -1 : 1;
   3610             }
   3611         
   3612             return {
   3613                 spinX: sX,
   3614                 spinY: sY,
   3615                 pixelX: pX,
   3616                 pixelY: pY
   3617             };
   3618         }
   3619         if (s.params.mousewheelControl) {
   3620             /**
   3621              * The best combination if you prefer spinX + spinY normalization.  It favors
   3622              * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with
   3623              * 'wheel' event, making spin speed determination impossible.
   3624              */
   3625             s.mousewheel.event = (navigator.userAgent.indexOf('firefox') > -1) ?
   3626                 'DOMMouseScroll' :
   3627                 isEventSupported() ?
   3628                     'wheel' : 'mousewheel';
   3629         }
   3630         function handleMousewheel(e) {
   3631             if (e.originalEvent) e = e.originalEvent; //jquery fix
   3632             var delta = 0;
   3633             var rtlFactor = s.rtl ? -1 : 1;
   3634         
   3635             var data = normalizeWheel( e );
   3636         
   3637             if (s.params.mousewheelForceToAxis) {
   3638                 if (s.isHorizontal()) {
   3639                     if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;
   3640                     else return;
   3641                 }
   3642                 else {
   3643                     if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;
   3644                     else return;
   3645                 }
   3646             }
   3647             else {
   3648                 delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? - data.pixelX * rtlFactor : - data.pixelY;
   3649             }
   3650         
   3651             if (delta === 0) return;
   3652         
   3653             if (s.params.mousewheelInvert) delta = -delta;
   3654         
   3655             if (!s.params.freeMode) {
   3656                 if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {
   3657                     if (delta < 0) {
   3658                         if ((!s.isEnd || s.params.loop) && !s.animating) {
   3659                             s.slideNext();
   3660                             s.emit('onScroll', s, e);
   3661                         }
   3662                         else if (s.params.mousewheelReleaseOnEdges) return true;
   3663                     }
   3664                     else {
   3665                         if ((!s.isBeginning || s.params.loop) && !s.animating) {
   3666                             s.slidePrev();
   3667                             s.emit('onScroll', s, e);
   3668                         }
   3669                         else if (s.params.mousewheelReleaseOnEdges) return true;
   3670                     }
   3671                 }
   3672                 s.mousewheel.lastScrollTime = (new window.Date()).getTime();
   3673         
   3674             }
   3675             else {
   3676                 //Freemode or scrollContainer:
   3677                 var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;
   3678                 var wasBeginning = s.isBeginning,
   3679                     wasEnd = s.isEnd;
   3680         
   3681                 if (position >= s.minTranslate()) position = s.minTranslate();
   3682                 if (position <= s.maxTranslate()) position = s.maxTranslate();
   3683         
   3684                 s.setWrapperTransition(0);
   3685                 s.setWrapperTranslate(position);
   3686                 s.updateProgress();
   3687                 s.updateActiveIndex();
   3688         
   3689                 if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {
   3690                     s.updateClasses();
   3691                 }
   3692         
   3693                 if (s.params.freeModeSticky) {
   3694                     clearTimeout(s.mousewheel.timeout);
   3695                     s.mousewheel.timeout = setTimeout(function () {
   3696                         s.slideReset();
   3697                     }, 300);
   3698                 }
   3699                 else {
   3700                     if (s.params.lazyLoading && s.lazy) {
   3701                         s.lazy.load();
   3702                     }
   3703                 }
   3704                 // Emit event
   3705                 s.emit('onScroll', s, e);
   3706         
   3707                 // Stop autoplay
   3708                 if (s.params.autoplay && s.params.autoplayDisableOnInteraction) s.stopAutoplay();
   3709         
   3710                 // Return page scroll on edge positions
   3711                 if (position === 0 || position === s.maxTranslate()) return;
   3712             }
   3713         
   3714             if (e.preventDefault) e.preventDefault();
   3715             else e.returnValue = false;
   3716             return false;
   3717         }
   3718         s.disableMousewheelControl = function () {
   3719             if (!s.mousewheel.event) return false;
   3720             var target = s.container;
   3721             if (s.params.mousewheelEventsTarged !== 'container') {
   3722                 target = $(s.params.mousewheelEventsTarged);
   3723             }
   3724             target.off(s.mousewheel.event, handleMousewheel);
   3725             s.params.mousewheelControl = false;
   3726             return true;
   3727         };
   3728         
   3729         s.enableMousewheelControl = function () {
   3730             if (!s.mousewheel.event) return false;
   3731             var target = s.container;
   3732             if (s.params.mousewheelEventsTarged !== 'container') {
   3733                 target = $(s.params.mousewheelEventsTarged);
   3734             }
   3735             target.on(s.mousewheel.event, handleMousewheel);
   3736             s.params.mousewheelControl = true;
   3737             return true;
   3738         };
   3739         
   3740 
   3741         /*=========================
   3742           Parallax
   3743           ===========================*/
   3744         function setParallaxTransform(el, progress) {
   3745             el = $(el);
   3746             var p, pX, pY;
   3747             var rtlFactor = s.rtl ? -1 : 1;
   3748         
   3749             p = el.attr('data-swiper-parallax') || '0';
   3750             pX = el.attr('data-swiper-parallax-x');
   3751             pY = el.attr('data-swiper-parallax-y');
   3752             if (pX || pY) {
   3753                 pX = pX || '0';
   3754                 pY = pY || '0';
   3755             }
   3756             else {
   3757                 if (s.isHorizontal()) {
   3758                     pX = p;
   3759                     pY = '0';
   3760                 }
   3761                 else {
   3762                     pY = p;
   3763                     pX = '0';
   3764                 }
   3765             }
   3766         
   3767             if ((pX).indexOf('%') >= 0) {
   3768                 pX = parseInt(pX, 10) * progress * rtlFactor + '%';
   3769             }
   3770             else {
   3771                 pX = pX * progress * rtlFactor + 'px' ;
   3772             }
   3773             if ((pY).indexOf('%') >= 0) {
   3774                 pY = parseInt(pY, 10) * progress + '%';
   3775             }
   3776             else {
   3777                 pY = pY * progress + 'px' ;
   3778             }
   3779         
   3780             el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
   3781         }
   3782         s.parallax = {
   3783             setTranslate: function () {
   3784                 s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
   3785                     setParallaxTransform(this, s.progress);
   3786         
   3787                 });
   3788                 s.slides.each(function () {
   3789                     var slide = $(this);
   3790                     slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
   3791                         var progress = Math.min(Math.max(slide[0].progress, -1), 1);
   3792                         setParallaxTransform(this, progress);
   3793                     });
   3794                 });
   3795             },
   3796             setTransition: function (duration) {
   3797                 if (typeof duration === 'undefined') duration = s.params.speed;
   3798                 s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
   3799                     var el = $(this);
   3800                     var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
   3801                     if (duration === 0) parallaxDuration = 0;
   3802                     el.transition(parallaxDuration);
   3803                 });
   3804             }
   3805         };
   3806         
   3807 
   3808         /*=========================
   3809           Zoom
   3810           ===========================*/
   3811         s.zoom = {
   3812             // "Global" Props
   3813             scale: 1,
   3814             currentScale: 1,
   3815             isScaling: false,
   3816             gesture: {
   3817                 slide: undefined,
   3818                 slideWidth: undefined,
   3819                 slideHeight: undefined,
   3820                 image: undefined,
   3821                 imageWrap: undefined,
   3822                 zoomMax: s.params.zoomMax
   3823             },
   3824             image: {
   3825                 isTouched: undefined,
   3826                 isMoved: undefined,
   3827                 currentX: undefined,
   3828                 currentY: undefined,
   3829                 minX: undefined,
   3830                 minY: undefined,
   3831                 maxX: undefined,
   3832                 maxY: undefined,
   3833                 width: undefined,
   3834                 height: undefined,
   3835                 startX: undefined,
   3836                 startY: undefined,
   3837                 touchesStart: {},
   3838                 touchesCurrent: {}
   3839             },
   3840             velocity: {
   3841                 x: undefined,
   3842                 y: undefined,
   3843                 prevPositionX: undefined,
   3844                 prevPositionY: undefined,
   3845                 prevTime: undefined
   3846             },
   3847             // Calc Scale From Multi-touches
   3848             getDistanceBetweenTouches: function (e) {
   3849                 if (e.targetTouches.length < 2) return 1;
   3850                 var x1 = e.targetTouches[0].pageX,
   3851                     y1 = e.targetTouches[0].pageY,
   3852                     x2 = e.targetTouches[1].pageX,
   3853                     y2 = e.targetTouches[1].pageY;
   3854                 var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
   3855                 return distance;
   3856             },
   3857             // Events
   3858             onGestureStart: function (e) {
   3859                 var z = s.zoom;
   3860                 if (!s.support.gestures) {
   3861                     if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {
   3862                         return;
   3863                     }
   3864                     z.gesture.scaleStart = z.getDistanceBetweenTouches(e);
   3865                 }
   3866                 if (!z.gesture.slide || !z.gesture.slide.length) {
   3867                     z.gesture.slide = $(this);
   3868                     if (z.gesture.slide.length === 0) z.gesture.slide = s.slides.eq(s.activeIndex);
   3869                     z.gesture.image = z.gesture.slide.find('img, svg, canvas');
   3870                     z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
   3871                     z.gesture.zoomMax = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax ;
   3872                     if (z.gesture.imageWrap.length === 0) {
   3873                         z.gesture.image = undefined;
   3874                         return;
   3875                     }
   3876                 }
   3877                 z.gesture.image.transition(0);
   3878                 z.isScaling = true;
   3879             },
   3880             onGestureChange: function (e) {
   3881                 var z = s.zoom;
   3882                 if (!s.support.gestures) {
   3883                     if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {
   3884                         return;
   3885                     }
   3886                     z.gesture.scaleMove = z.getDistanceBetweenTouches(e);
   3887                 }
   3888                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   3889                 if (s.support.gestures) {
   3890                     z.scale = e.scale * z.currentScale;
   3891                 }
   3892                 else {
   3893                     z.scale = (z.gesture.scaleMove / z.gesture.scaleStart) * z.currentScale;
   3894                 }
   3895                 if (z.scale > z.gesture.zoomMax) {
   3896                     z.scale = z.gesture.zoomMax - 1 + Math.pow((z.scale - z.gesture.zoomMax + 1), 0.5);
   3897                 }
   3898                 if (z.scale < s.params.zoomMin) {
   3899                     z.scale =  s.params.zoomMin + 1 - Math.pow((s.params.zoomMin - z.scale + 1), 0.5);
   3900                 }
   3901                 z.gesture.image.transform('translate3d(0,0,0) scale(' + z.scale + ')');
   3902             },
   3903             onGestureEnd: function (e) {
   3904                 var z = s.zoom;
   3905                 if (!s.support.gestures) {
   3906                     if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2) {
   3907                         return;
   3908                     }
   3909                 }
   3910                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   3911                 z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.params.zoomMin);
   3912                 z.gesture.image.transition(s.params.speed).transform('translate3d(0,0,0) scale(' + z.scale + ')');
   3913                 z.currentScale = z.scale;
   3914                 z.isScaling = false;
   3915                 if (z.scale === 1) z.gesture.slide = undefined;
   3916             },
   3917             onTouchStart: function (s, e) {
   3918                 var z = s.zoom;
   3919                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   3920                 if (z.image.isTouched) return;
   3921                 if (s.device.os === 'android') e.preventDefault();
   3922                 z.image.isTouched = true;
   3923                 z.image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
   3924                 z.image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
   3925             },
   3926             onTouchMove: function (e) {
   3927                 var z = s.zoom;
   3928                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   3929                 s.allowClick = false;
   3930                 if (!z.image.isTouched || !z.gesture.slide) return;
   3931         
   3932                 if (!z.image.isMoved) {
   3933                     z.image.width = z.gesture.image[0].offsetWidth;
   3934                     z.image.height = z.gesture.image[0].offsetHeight;
   3935                     z.image.startX = s.getTranslate(z.gesture.imageWrap[0], 'x') || 0;
   3936                     z.image.startY = s.getTranslate(z.gesture.imageWrap[0], 'y') || 0;
   3937                     z.gesture.slideWidth = z.gesture.slide[0].offsetWidth;
   3938                     z.gesture.slideHeight = z.gesture.slide[0].offsetHeight;
   3939                     z.gesture.imageWrap.transition(0);
   3940                     if (s.rtl) z.image.startX = -z.image.startX;
   3941                     if (s.rtl) z.image.startY = -z.image.startY;
   3942                 }
   3943                 // Define if we need image drag
   3944                 var scaledWidth = z.image.width * z.scale;
   3945                 var scaledHeight = z.image.height * z.scale;
   3946         
   3947                 if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) return;
   3948         
   3949                 z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
   3950                 z.image.maxX = -z.image.minX;
   3951                 z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
   3952                 z.image.maxY = -z.image.minY;
   3953         
   3954                 z.image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
   3955                 z.image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
   3956         
   3957                 if (!z.image.isMoved && !z.isScaling) {
   3958                     if (s.isHorizontal() &&
   3959                         (Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x) ||
   3960                         (Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x)
   3961                         ) {
   3962                         z.image.isTouched = false;
   3963                         return;
   3964                     }
   3965                     else if (!s.isHorizontal() &&
   3966                         (Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y) ||
   3967                         (Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y)
   3968                         ) {
   3969                         z.image.isTouched = false;
   3970                         return;
   3971                     }
   3972                 }
   3973                 e.preventDefault();
   3974                 e.stopPropagation();
   3975         
   3976                 z.image.isMoved = true;
   3977                 z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;
   3978                 z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;
   3979         
   3980                 if (z.image.currentX < z.image.minX) {
   3981                     z.image.currentX =  z.image.minX + 1 - Math.pow((z.image.minX - z.image.currentX + 1), 0.8);
   3982                 }
   3983                 if (z.image.currentX > z.image.maxX) {
   3984                     z.image.currentX = z.image.maxX - 1 + Math.pow((z.image.currentX - z.image.maxX + 1), 0.8);
   3985                 }
   3986         
   3987                 if (z.image.currentY < z.image.minY) {
   3988                     z.image.currentY =  z.image.minY + 1 - Math.pow((z.image.minY - z.image.currentY + 1), 0.8);
   3989                 }
   3990                 if (z.image.currentY > z.image.maxY) {
   3991                     z.image.currentY = z.image.maxY - 1 + Math.pow((z.image.currentY - z.image.maxY + 1), 0.8);
   3992                 }
   3993         
   3994                 //Velocity
   3995                 if (!z.velocity.prevPositionX) z.velocity.prevPositionX = z.image.touchesCurrent.x;
   3996                 if (!z.velocity.prevPositionY) z.velocity.prevPositionY = z.image.touchesCurrent.y;
   3997                 if (!z.velocity.prevTime) z.velocity.prevTime = Date.now();
   3998                 z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;
   3999                 z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;
   4000                 if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2) z.velocity.x = 0;
   4001                 if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2) z.velocity.y = 0;
   4002                 z.velocity.prevPositionX = z.image.touchesCurrent.x;
   4003                 z.velocity.prevPositionY = z.image.touchesCurrent.y;
   4004                 z.velocity.prevTime = Date.now();
   4005         
   4006                 z.gesture.imageWrap.transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
   4007             },
   4008             onTouchEnd: function (s, e) {
   4009                 var z = s.zoom;
   4010                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   4011                 if (!z.image.isTouched || !z.image.isMoved) {
   4012                     z.image.isTouched = false;
   4013                     z.image.isMoved = false;
   4014                     return;
   4015                 }
   4016                 z.image.isTouched = false;
   4017                 z.image.isMoved = false;
   4018                 var momentumDurationX = 300;
   4019                 var momentumDurationY = 300;
   4020                 var momentumDistanceX = z.velocity.x * momentumDurationX;
   4021                 var newPositionX = z.image.currentX + momentumDistanceX;
   4022                 var momentumDistanceY = z.velocity.y * momentumDurationY;
   4023                 var newPositionY = z.image.currentY + momentumDistanceY;
   4024         
   4025                 //Fix duration
   4026                 if (z.velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);
   4027                 if (z.velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);
   4028                 var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
   4029         
   4030                 z.image.currentX = newPositionX;
   4031                 z.image.currentY = newPositionY;
   4032         
   4033                 // Define if we need image drag
   4034                 var scaledWidth = z.image.width * z.scale;
   4035                 var scaledHeight = z.image.height * z.scale;
   4036                 z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
   4037                 z.image.maxX = -z.image.minX;
   4038                 z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
   4039                 z.image.maxY = -z.image.minY;
   4040                 z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);
   4041                 z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);
   4042         
   4043                 z.gesture.imageWrap.transition(momentumDuration).transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
   4044             },
   4045             onTransitionEnd: function (s) {
   4046                 var z = s.zoom;
   4047                 if (z.gesture.slide && s.previousIndex !== s.activeIndex) {
   4048                     z.gesture.image.transform('translate3d(0,0,0) scale(1)');
   4049                     z.gesture.imageWrap.transform('translate3d(0,0,0)');
   4050                     z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;
   4051                     z.scale = z.currentScale = 1;
   4052                 }
   4053             },
   4054             // Toggle Zoom
   4055             toggleZoom: function (s, e) {
   4056                 var z = s.zoom;
   4057                 if (!z.gesture.slide) {
   4058                     z.gesture.slide = s.clickedSlide ? $(s.clickedSlide) : s.slides.eq(s.activeIndex);
   4059                     z.gesture.image = z.gesture.slide.find('img, svg, canvas');
   4060                     z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
   4061                 }
   4062                 if (!z.gesture.image || z.gesture.image.length === 0) return;
   4063         
   4064                 var touchX, touchY, offsetX, offsetY, diffX, diffY, translateX, translateY, imageWidth, imageHeight, scaledWidth, scaledHeight, translateMinX, translateMinY, translateMaxX, translateMaxY, slideWidth, slideHeight;
   4065         
   4066                 if (typeof z.image.touchesStart.x === 'undefined' && e) {
   4067                     touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
   4068                     touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
   4069                 }
   4070                 else {
   4071                     touchX = z.image.touchesStart.x;
   4072                     touchY = z.image.touchesStart.y;
   4073                 }
   4074         
   4075                 if (z.scale && z.scale !== 1) {
   4076                     // Zoom Out
   4077                     z.scale = z.currentScale = 1;
   4078                     z.gesture.imageWrap.transition(300).transform('translate3d(0,0,0)');
   4079                     z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(1)');
   4080                     z.gesture.slide = undefined;
   4081                 }
   4082                 else {
   4083                     // Zoom In
   4084                     z.scale = z.currentScale = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax;
   4085                     if (e) {
   4086                         slideWidth = z.gesture.slide[0].offsetWidth;
   4087                         slideHeight = z.gesture.slide[0].offsetHeight;
   4088                         offsetX = z.gesture.slide.offset().left;
   4089                         offsetY = z.gesture.slide.offset().top;
   4090                         diffX = offsetX + slideWidth/2 - touchX;
   4091                         diffY = offsetY + slideHeight/2 - touchY;
   4092         
   4093                         imageWidth = z.gesture.image[0].offsetWidth;
   4094                         imageHeight = z.gesture.image[0].offsetHeight;
   4095                         scaledWidth = imageWidth * z.scale;
   4096                         scaledHeight = imageHeight * z.scale;
   4097         
   4098                         translateMinX = Math.min((slideWidth / 2 - scaledWidth / 2), 0);
   4099                         translateMinY = Math.min((slideHeight / 2 - scaledHeight / 2), 0);
   4100                         translateMaxX = -translateMinX;
   4101                         translateMaxY = -translateMinY;
   4102         
   4103                         translateX = diffX * z.scale;
   4104                         translateY = diffY * z.scale;
   4105         
   4106                         if (translateX < translateMinX) {
   4107                             translateX =  translateMinX;
   4108                         }
   4109                         if (translateX > translateMaxX) {
   4110                             translateX = translateMaxX;
   4111                         }
   4112         
   4113                         if (translateY < translateMinY) {
   4114                             translateY =  translateMinY;
   4115                         }
   4116                         if (translateY > translateMaxY) {
   4117                             translateY = translateMaxY;
   4118                         }
   4119                     }
   4120                     else {
   4121                         translateX = 0;
   4122                         translateY = 0;
   4123                     }
   4124                     z.gesture.imageWrap.transition(300).transform('translate3d(' + translateX + 'px, ' + translateY + 'px,0)');
   4125                     z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(' + z.scale + ')');
   4126                 }
   4127             },
   4128             // Attach/Detach Events
   4129             attachEvents: function (detach) {
   4130                 var action = detach ? 'off' : 'on';
   4131         
   4132                 if (s.params.zoom) {
   4133                     var target = s.slides;
   4134                     var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
   4135                     // Scale image
   4136                     if (s.support.gestures) {
   4137                         s.slides[action]('gesturestart', s.zoom.onGestureStart, passiveListener);
   4138                         s.slides[action]('gesturechange', s.zoom.onGestureChange, passiveListener);
   4139                         s.slides[action]('gestureend', s.zoom.onGestureEnd, passiveListener);
   4140                     }
   4141                     else if (s.touchEvents.start === 'touchstart') {
   4142                         s.slides[action](s.touchEvents.start, s.zoom.onGestureStart, passiveListener);
   4143                         s.slides[action](s.touchEvents.move, s.zoom.onGestureChange, passiveListener);
   4144                         s.slides[action](s.touchEvents.end, s.zoom.onGestureEnd, passiveListener);
   4145                     }
   4146         
   4147                     // Move image
   4148                     s[action]('touchStart', s.zoom.onTouchStart);
   4149                     s.slides.each(function (index, slide){
   4150                         if ($(slide).find('.' + s.params.zoomContainerClass).length > 0) {
   4151                             $(slide)[action](s.touchEvents.move, s.zoom.onTouchMove);
   4152                         }
   4153                     });
   4154                     s[action]('touchEnd', s.zoom.onTouchEnd);
   4155         
   4156                     // Scale Out
   4157                     s[action]('transitionEnd', s.zoom.onTransitionEnd);
   4158                     if (s.params.zoomToggle) {
   4159                         s.on('doubleTap', s.zoom.toggleZoom);
   4160                     }
   4161                 }
   4162             },
   4163             init: function () {
   4164                 s.zoom.attachEvents();
   4165             },
   4166             destroy: function () {
   4167                 s.zoom.attachEvents(true);
   4168             }
   4169         };
   4170         
   4171 
   4172         /*=========================
   4173           Plugins API. Collect all and init all plugins
   4174           ===========================*/
   4175         s._plugins = [];
   4176         for (var plugin in s.plugins) {
   4177             var p = s.plugins[plugin](s, s.params[plugin]);
   4178             if (p) s._plugins.push(p);
   4179         }
   4180         // Method to call all plugins event/method
   4181         s.callPlugins = function (eventName) {
   4182             for (var i = 0; i < s._plugins.length; i++) {
   4183                 if (eventName in s._plugins[i]) {
   4184                     s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
   4185                 }
   4186             }
   4187         };
   4188         
   4189 
   4190         /*=========================
   4191           Events/Callbacks/Plugins Emitter
   4192           ===========================*/
   4193         function normalizeEventName (eventName) {
   4194             if (eventName.indexOf('on') !== 0) {
   4195                 if (eventName[0] !== eventName[0].toUpperCase()) {
   4196                     eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
   4197                 }
   4198                 else {
   4199                     eventName = 'on' + eventName;
   4200                 }
   4201             }
   4202             return eventName;
   4203         }
   4204         s.emitterEventListeners = {
   4205         
   4206         };
   4207         s.emit = function (eventName) {
   4208             // Trigger callbacks
   4209             if (s.params[eventName]) {
   4210                 s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
   4211             }
   4212             var i;
   4213             // Trigger events
   4214             if (s.emitterEventListeners[eventName]) {
   4215                 for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
   4216                     s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
   4217                 }
   4218             }
   4219             // Trigger plugins
   4220             if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
   4221         };
   4222         s.on = function (eventName, handler) {
   4223             eventName = normalizeEventName(eventName);
   4224             if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
   4225             s.emitterEventListeners[eventName].push(handler);
   4226             return s;
   4227         };
   4228         s.off = function (eventName, handler) {
   4229             var i;
   4230             eventName = normalizeEventName(eventName);
   4231             if (typeof handler === 'undefined') {
   4232                 // Remove all handlers for such event
   4233                 s.emitterEventListeners[eventName] = [];
   4234                 return s;
   4235             }
   4236             if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
   4237             for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
   4238                 if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
   4239             }
   4240             return s;
   4241         };
   4242         s.once = function (eventName, handler) {
   4243             eventName = normalizeEventName(eventName);
   4244             var _handler = function () {
   4245                 handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
   4246                 s.off(eventName, _handler);
   4247             };
   4248             s.on(eventName, _handler);
   4249             return s;
   4250         };
   4251         
   4252 
   4253         // Accessibility tools
   4254         s.a11y = {
   4255             makeFocusable: function ($el) {
   4256                 $el.attr('tabIndex', '0');
   4257                 return $el;
   4258             },
   4259             addRole: function ($el, role) {
   4260                 $el.attr('role', role);
   4261                 return $el;
   4262             },
   4263         
   4264             addLabel: function ($el, label) {
   4265                 $el.attr('aria-label', label);
   4266                 return $el;
   4267             },
   4268         
   4269             disable: function ($el) {
   4270                 $el.attr('aria-disabled', true);
   4271                 return $el;
   4272             },
   4273         
   4274             enable: function ($el) {
   4275                 $el.attr('aria-disabled', false);
   4276                 return $el;
   4277             },
   4278         
   4279             onEnterKey: function (event) {
   4280                 if (event.keyCode !== 13) return;
   4281                 if ($(event.target).is(s.params.nextButton)) {
   4282                     s.onClickNext(event);
   4283                     if (s.isEnd) {
   4284                         s.a11y.notify(s.params.lastSlideMessage);
   4285                     }
   4286                     else {
   4287                         s.a11y.notify(s.params.nextSlideMessage);
   4288                     }
   4289                 }
   4290                 else if ($(event.target).is(s.params.prevButton)) {
   4291                     s.onClickPrev(event);
   4292                     if (s.isBeginning) {
   4293                         s.a11y.notify(s.params.firstSlideMessage);
   4294                     }
   4295                     else {
   4296                         s.a11y.notify(s.params.prevSlideMessage);
   4297                     }
   4298                 }
   4299                 if ($(event.target).is('.' + s.params.bulletClass)) {
   4300                     $(event.target)[0].click();
   4301                 }
   4302             },
   4303         
   4304             liveRegion: $('<span class="' + s.params.notificationClass + '" aria-live="assertive" aria-atomic="true"></span>'),
   4305         
   4306             notify: function (message) {
   4307                 var notification = s.a11y.liveRegion;
   4308                 if (notification.length === 0) return;
   4309                 notification.html('');
   4310                 notification.html(message);
   4311             },
   4312             init: function () {
   4313                 // Setup accessibility
   4314                 if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
   4315                     s.a11y.makeFocusable(s.nextButton);
   4316                     s.a11y.addRole(s.nextButton, 'button');
   4317                     s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);
   4318                 }
   4319                 if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
   4320                     s.a11y.makeFocusable(s.prevButton);
   4321                     s.a11y.addRole(s.prevButton, 'button');
   4322                     s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);
   4323                 }
   4324         
   4325                 $(s.container).append(s.a11y.liveRegion);
   4326             },
   4327             initPagination: function () {
   4328                 if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {
   4329                     s.bullets.each(function () {
   4330                         var bullet = $(this);
   4331                         s.a11y.makeFocusable(bullet);
   4332                         s.a11y.addRole(bullet, 'button');
   4333                         s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));
   4334                     });
   4335                 }
   4336             },
   4337             destroy: function () {
   4338                 if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
   4339             }
   4340         };
   4341         
   4342 
   4343         /*=========================
   4344           Init/Destroy
   4345           ===========================*/
   4346         s.init = function () {
   4347             if (s.params.loop) s.createLoop();
   4348             s.updateContainerSize();
   4349             s.updateSlidesSize();
   4350             s.updatePagination();
   4351             if (s.params.scrollbar && s.scrollbar) {
   4352                 s.scrollbar.set();
   4353                 if (s.params.scrollbarDraggable) {
   4354                     s.scrollbar.enableDraggable();
   4355                 }
   4356             }
   4357             if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
   4358                 if (!s.params.loop) s.updateProgress();
   4359                 s.effects[s.params.effect].setTranslate();
   4360             }
   4361             if (s.params.loop) {
   4362                 s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
   4363             }
   4364             else {
   4365                 s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
   4366                 if (s.params.initialSlide === 0) {
   4367                     if (s.parallax && s.params.parallax) s.parallax.setTranslate();
   4368                     if (s.lazy && s.params.lazyLoading) {
   4369                         s.lazy.load();
   4370                         s.lazy.initialImageLoaded = true;
   4371                     }
   4372                 }
   4373             }
   4374             s.attachEvents();
   4375             if (s.params.observer && s.support.observer) {
   4376                 s.initObservers();
   4377             }
   4378             if (s.params.preloadImages && !s.params.lazyLoading) {
   4379                 s.preloadImages();
   4380             }
   4381             if (s.params.zoom && s.zoom) {
   4382                 s.zoom.init();
   4383             }
   4384             if (s.params.autoplay) {
   4385                 s.startAutoplay();
   4386             }
   4387             if (s.params.keyboardControl) {
   4388                 if (s.enableKeyboardControl) s.enableKeyboardControl();
   4389             }
   4390             if (s.params.mousewheelControl) {
   4391                 if (s.enableMousewheelControl) s.enableMousewheelControl();
   4392             }
   4393             // Deprecated hashnavReplaceState changed to replaceState for use in hashnav and history
   4394             if (s.params.hashnavReplaceState) {
   4395                 s.params.replaceState = s.params.hashnavReplaceState;
   4396             }
   4397             if (s.params.history) {
   4398                 if (s.history) s.history.init();
   4399             }
   4400             if (s.params.hashnav) {
   4401                 if (s.hashnav) s.hashnav.init();
   4402             }
   4403             if (s.params.a11y && s.a11y) s.a11y.init();
   4404             s.emit('onInit', s);
   4405         };
   4406         
   4407         // Cleanup dynamic styles
   4408         s.cleanupStyles = function () {
   4409             // Container
   4410             s.container.removeClass(s.classNames.join(' ')).removeAttr('style');
   4411         
   4412             // Wrapper
   4413             s.wrapper.removeAttr('style');
   4414         
   4415             // Slides
   4416             if (s.slides && s.slides.length) {
   4417                 s.slides
   4418                     .removeClass([
   4419                       s.params.slideVisibleClass,
   4420                       s.params.slideActiveClass,
   4421                       s.params.slideNextClass,
   4422                       s.params.slidePrevClass
   4423                     ].join(' '))
   4424                     .removeAttr('style')
   4425                     .removeAttr('data-swiper-column')
   4426                     .removeAttr('data-swiper-row');
   4427             }
   4428         
   4429             // Pagination/Bullets
   4430             if (s.paginationContainer && s.paginationContainer.length) {
   4431                 s.paginationContainer.removeClass(s.params.paginationHiddenClass);
   4432             }
   4433             if (s.bullets && s.bullets.length) {
   4434                 s.bullets.removeClass(s.params.bulletActiveClass);
   4435             }
   4436         
   4437             // Buttons
   4438             if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
   4439             if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
   4440         
   4441             // Scrollbar
   4442             if (s.params.scrollbar && s.scrollbar) {
   4443                 if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');
   4444                 if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');
   4445             }
   4446         };
   4447         
   4448         // Destroy
   4449         s.destroy = function (deleteInstance, cleanupStyles) {
   4450             // Detach evebts
   4451             s.detachEvents();
   4452             // Stop autoplay
   4453             s.stopAutoplay();
   4454             // Disable draggable
   4455             if (s.params.scrollbar && s.scrollbar) {
   4456                 if (s.params.scrollbarDraggable) {
   4457                     s.scrollbar.disableDraggable();
   4458                 }
   4459             }
   4460             // Destroy loop
   4461             if (s.params.loop) {
   4462                 s.destroyLoop();
   4463             }
   4464             // Cleanup styles
   4465             if (cleanupStyles) {
   4466                 s.cleanupStyles();
   4467             }
   4468             // Disconnect observer
   4469             s.disconnectObservers();
   4470         
   4471             // Destroy zoom
   4472             if (s.params.zoom && s.zoom) {
   4473                 s.zoom.destroy();
   4474             }
   4475             // Disable keyboard/mousewheel
   4476             if (s.params.keyboardControl) {
   4477                 if (s.disableKeyboardControl) s.disableKeyboardControl();
   4478             }
   4479             if (s.params.mousewheelControl) {
   4480                 if (s.disableMousewheelControl) s.disableMousewheelControl();
   4481             }
   4482             // Disable a11y
   4483             if (s.params.a11y && s.a11y) s.a11y.destroy();
   4484             // Delete history popstate
   4485             if (s.params.history && !s.params.replaceState) {
   4486                 window.removeEventListener('popstate', s.history.setHistoryPopState);
   4487             }
   4488             if (s.params.hashnav && s.hashnav)  {
   4489                 s.hashnav.destroy();
   4490             }
   4491             // Destroy callback
   4492             s.emit('onDestroy');
   4493             // Delete instance
   4494             if (deleteInstance !== false) s = null;
   4495         };
   4496         
   4497         s.init();
   4498         
   4499 
   4500     
   4501         // Return swiper instance
   4502         return s;
   4503     };
   4504     
   4505 
   4506     /*==================================================
   4507         Prototype
   4508     ====================================================*/
   4509     Swiper.prototype = {
   4510         isSafari: (function () {
   4511             var ua = window.navigator.userAgent.toLowerCase();
   4512             return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
   4513         })(),
   4514         isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent),
   4515         isArray: function (arr) {
   4516             return Object.prototype.toString.apply(arr) === '[object Array]';
   4517         },
   4518         /*==================================================
   4519         Browser
   4520         ====================================================*/
   4521         browser: {
   4522             ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
   4523             ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
   4524             lteIE9: (function() {
   4525                 // create temporary DIV
   4526                 var div = document.createElement('div');
   4527                 // add content to tmp DIV which is wrapped into the IE HTML conditional statement
   4528                 div.innerHTML = '<!--[if lte IE 9]><i></i><![endif]-->';
   4529                 // return true / false value based on what will browser render
   4530                 return div.getElementsByTagName('i').length === 1;
   4531             })()
   4532         },
   4533         /*==================================================
   4534         Devices
   4535         ====================================================*/
   4536         device: (function () {
   4537             var ua = window.navigator.userAgent;
   4538             var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
   4539             var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
   4540             var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
   4541             var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
   4542             return {
   4543                 ios: ipad || iphone || ipod,
   4544                 android: android
   4545             };
   4546         })(),
   4547         /*==================================================
   4548         Feature Detection
   4549         ====================================================*/
   4550         support: {
   4551             touch : (window.Modernizr && Modernizr.touch === true) || (function () {
   4552                 return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
   4553             })(),
   4554     
   4555             transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
   4556                 var div = document.createElement('div').style;
   4557                 return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
   4558             })(),
   4559     
   4560             flexbox: (function () {
   4561                 var div = document.createElement('div').style;
   4562                 var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
   4563                 for (var i = 0; i < styles.length; i++) {
   4564                     if (styles[i] in div) return true;
   4565                 }
   4566             })(),
   4567     
   4568             observer: (function () {
   4569                 return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
   4570             })(),
   4571     
   4572             passiveListener: (function () {
   4573                 var supportsPassive = false;
   4574                 try {
   4575                     var opts = Object.defineProperty({}, 'passive', {
   4576                         get: function() {
   4577                             supportsPassive = true;
   4578                         }
   4579                     });
   4580                     window.addEventListener('testPassiveListener', null, opts);
   4581                 } catch (e) {}
   4582                 return supportsPassive;
   4583             })(),
   4584     
   4585             gestures: (function () {
   4586                 return 'ongesturestart' in window;
   4587             })()
   4588         },
   4589         /*==================================================
   4590         Plugins
   4591         ====================================================*/
   4592         plugins: {}
   4593     };
   4594     
   4595 
   4596     /*===========================
   4597      Get jQuery
   4598      ===========================*/
   4599     addLibraryPlugin($);
   4600     
   4601     var domLib = $;
   4602     
   4603 
   4604     /*===========================
   4605     Add .swiper plugin from Dom libraries
   4606     ===========================*/
   4607     function addLibraryPlugin(lib) {
   4608         lib.fn.swiper = function (params) {
   4609             var firstInstance;
   4610             lib(this).each(function () {
   4611                 var s = new Swiper(this, params);
   4612                 if (!firstInstance) firstInstance = s;
   4613             });
   4614             return firstInstance;
   4615         };
   4616     }
   4617     
   4618     if (domLib) {
   4619         if (!('transitionEnd' in domLib.fn)) {
   4620             domLib.fn.transitionEnd = function (callback) {
   4621                 var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
   4622                     i, j, dom = this;
   4623                 function fireCallBack(e) {
   4624                     /*jshint validthis:true */
   4625                     if (e.target !== this) return;
   4626                     callback.call(this, e);
   4627                     for (i = 0; i < events.length; i++) {
   4628                         dom.off(events[i], fireCallBack);
   4629                     }
   4630                 }
   4631                 if (callback) {
   4632                     for (i = 0; i < events.length; i++) {
   4633                         dom.on(events[i], fireCallBack);
   4634                     }
   4635                 }
   4636                 return this;
   4637             };
   4638         }
   4639         if (!('transform' in domLib.fn)) {
   4640             domLib.fn.transform = function (transform) {
   4641                 for (var i = 0; i < this.length; i++) {
   4642                     var elStyle = this[i].style;
   4643                     elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
   4644                 }
   4645                 return this;
   4646             };
   4647         }
   4648         if (!('transition' in domLib.fn)) {
   4649             domLib.fn.transition = function (duration) {
   4650                 if (typeof duration !== 'string') {
   4651                     duration = duration + 'ms';
   4652                 }
   4653                 for (var i = 0; i < this.length; i++) {
   4654                     var elStyle = this[i].style;
   4655                     elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
   4656                 }
   4657                 return this;
   4658             };
   4659         }
   4660         if (!('outerWidth' in domLib.fn)) {
   4661             domLib.fn.outerWidth = function (includeMargins) {
   4662                 if (this.length > 0) {
   4663                     if (includeMargins)
   4664                         return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));
   4665                     else
   4666                         return this[0].offsetWidth;
   4667                 }
   4668                 else return null;
   4669             };
   4670         }
   4671     }
   4672     
   4673 
   4674 	return Swiper;
   4675 }));
   4676 
   4677 //# sourceMappingURL=maps/swiper.jquery.umd.js.map