PageSourceSearch

https://www.guamplay.com/include/js/swipejs/swiper.custom.js?ver=1791445341

js guamplay.com collected 2026-10-08 07:43:45 UTC 206,731 bytes, 4,690 lines download raw bytes

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

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