PageSourceSearch

https://campamentosveranoava.com/wp-content/themes/sevenhills/fw/js/swiper/swiper.js

js campamentosveranoava.com collected 2026-10-04 20:07:53 UTC 168,962 bytes, 3,966 lines download raw bytes

1/**
2 * Swiper 3.1.2
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * 
5 * http://www.idangero.us/swiper/
6 * 
7 * Copyright 2015, Vladimir Kharlampidi
8 * The iDangero.us
9 * http://www.idangero.us/
10 * 
11 * Licensed under MIT
12 * 
13 * Released on: August 22, 2015
14 */
15(function () {
16    'use strict';
17    var $;
18    /*===========================
19    Swiper
20    ===========================*/
21    var Swiper = function (container, params) {
22        if (!(this instanceof Swiper)) return new Swiper(container, params);
23
24        var defaults = {
25            direction: 'horizontal',
26            touchEventsTarget: 'container',
27            initialSlide: 0,
28            speed: 300,
29            // autoplay
30            autoplay: false,
31            autoplayDisableOnInteraction: true,
32            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
33            iOSEdgeSwipeDetection: false,
34            iOSEdgeSwipeThreshold: 20,
35            // Free mode
36            freeMode: false,
37            freeModeMomentum: true,
38            freeModeMomentumRatio: 1,
39            freeModeMomentumBounce: true,
40            freeModeMomentumBounceRatio: 1,
41            freeModeSticky: false,
42            // Set wrapper width
43            setWrapperSize: false,
44            // Virtual Translate
45            virtualTranslate: false,
46            // Effects
47            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow'
48            coverflow: {
49                rotate: 50,
50                stretch: 0,
51                depth: 100,
52                modifier: 1,
53                slideShadows : true
54            },
55            cube: {
56                slideShadows: true,
57                shadow: true,
58                shadowOffset: 20,
59                shadowScale: 0.94
60            },
61            fade: {
62                crossFade: false
63            },
64            // Parallax
65            parallax: false,
66            // Scrollbar
67            scrollbar: null,
68            scrollbarHide: true,
69            // Keyboard Mousewheel
70            keyboardControl: false,
71            mousewheelControl: false,
72            mousewheelReleaseOnEdges: false,
73            mousewheelInvert: false,
74            mousewheelForceToAxis: false,
75            mousewheelSensitivity: 1,
76            // Hash Navigation
77            hashnav: false,
78            // Slides grid
79            spaceBetween: 0,
80            slidesPerView: 1,
81            slidesPerColumn: 1,
82            slidesPerColumnFill: 'column',
83            slidesPerGroup: 1,
84            centeredSlides: false,
85            slidesOffsetBefore: 0, // in px
86            slidesOffsetAfter: 0, // in px
87            // Round length
88            roundLengths: false,
89            // Touches
90            touchRatio: 1,
91            touchAngle: 45,
92            simulateTouch: true,
93            shortSwipes: true,
94            longSwipes: true,
95            longSwipesRatio: 0.5,
96            longSwipesMs: 300,
97            followFinger: true,
98            onlyExternal: false,
99            threshold: 0,
100            touchMoveStopPropagation: true,
101            // Pagination
102            pagination: null,
103            paginationElement: 'span',
104            paginationClickable: false,
105            paginationHide: false,
106            paginationBulletRender: null,
107            // Resistance
108            resistance: true,
109            resistanceRatio: 0.85,
110            // Next/prev buttons
111            nextButton: null,
112            prevButton: null,
113            // Progress
114            watchSlidesProgress: false,
115            watchSlidesVisibility: false,
116            // Cursor
117            grabCursor: false,
118            // Clicks
119            preventClicks: true,
120            preventClicksPropagation: true,
121            slideToClickedSlide: false,
122            // Lazy Loading
123            lazyLoading: false,
124            lazyLoadingInPrevNext: false,
125            lazyLoadingOnTransitionStart: false,
126            // Images
127            preloadImages: true,
128            updateOnImagesReady: true,
129            // loop
130            loop: false,
131            loopAdditionalSlides: 0,
132            loopedSlides: null,
133            // Control
134            control: undefined,
135            controlInverse: false,
136            controlBy: 'slide', //or 'container'
137            // Swiping/no swiping
138            allowSwipeToPrev: true,
139            allowSwipeToNext: true,
140            swipeHandler: null, //'.swipe-handler',
141            noSwiping: true,
142            noSwipingClass: 'swiper-no-swiping',
143            // NS
144            slideClass: 'swiper-slide',
145            slideActiveClass: 'swiper-slide-active',
146            slideVisibleClass: 'swiper-slide-visible',
147            slideDuplicateClass: 'swiper-slide-duplicate',
148            slideNextClass: 'swiper-slide-next',
149            slidePrevClass: 'swiper-slide-prev',
150            wrapperClass: 'swiper-wrapper',
151            bulletClass: 'swiper-pagination-bullet',
152            bulletActiveClass: 'swiper-pagination-bullet-active',
153            buttonDisabledClass: 'swiper-button-disabled',
154            paginationHiddenClass: 'swiper-pagination-hidden',
155            // Observer
156            observer: false,
157            observeParents: false,
158            // Accessibility
159            a11y: false,
160            prevSlideMessage: 'Previous slide',
161            nextSlideMessage: 'Next slide',
162            firstSlideMessage: 'This is the first slide',
163            lastSlideMessage: 'This is the last slide',
164            paginationBulletMessage: 'Go to slide {{index}}',
165            // Callbacks
166            runCallbacksOnInit: true
167            /*
168            Callbacks:
169            onInit: function (swiper)
170            onDestroy: function (swiper)
171            onClick: function (swiper, e)
172            onTap: function (swiper, e)
173            onDoubleTap: function (swiper, e)
174            onSliderMove: function (swiper, e)
175            onSlideChangeStart: function (swiper)
176            onSlideChangeEnd: function (swiper)
177            onTransitionStart: function (swiper)
178            onTransitionEnd: function (swiper)
179            onImagesReady: function (swiper)
180            onProgress: function (swiper, progress)
181            onTouchStart: function (swiper, e)
182            onTouchMove: function (swiper, e)
183            onTouchMoveOpposite: function (swiper, e)
184            onTouchEnd: function (swiper, e)
185            onReachBeginning: function (swiper)
186            onReachEnd: function (swiper)
187            onSetTransition: function (swiper, duration)
188            onSetTranslate: function (swiper, translate)
189            onAutoplayStart: function (swiper)
190            onAutoplayStop: function (swiper),
191            onLazyImageLoad: function (swiper, slide, image)
192            onLazyImageReady: function (swiper, slide, image)
193            */
194        
195        };
196        var initialVirtualTranslate = params && params.virtualTranslate;
197        
198        params = params || {};
199        for (var def in defaults) {
200            if (typeof params[def] === 'undefined') {
201                params[def] = defaults[def];
202            }
203            else if (typeof params[def] === 'object') {
204                for (var deepDef in defaults[def]) {
205                    if (typeof params[def][deepDef] === 'undefined') {
206                        params[def][deepDef] = defaults[def][deepDef];
207                    }
208                }
209            }
210        }
211        
212        // Swiper
213        var s = this;
214        
215        // Version
216        s.version = '3.1.0';
217        
218        // Params
219        s.params = params;
220        
221        // Classname
222        s.classNames = [];
223        /*=========================
224          Dom Library and plugins
225          ===========================*/
226        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){
227            $ = Dom7;
228        }  
229        if (typeof $ === 'undefined') {
230            if (typeof Dom7 === 'undefined') {
231                $ = window.Dom7 || window.Zepto || window.jQuery;
232            }
233            else {
234                $ = Dom7;
235            }
236            if (!$) return;
237        }
238        // Export it to Swiper instance
239        s.$ = $;
240        
241        /*=========================
242          Preparation - Define Container, Wrapper and Pagination
243          ===========================*/
244        s.container = $(container);
245        if (s.container.length === 0) return;
246        if (s.container.length > 1) {
247            s.container.each(function () {
248                new Swiper(this, params);
249            });
250            return;
251        }
252        
253        // Save instance in container HTML Element and in data
254        s.container[0].swiper = s;
255        s.container.data('swiper', s);
256        
257        s.classNames.push('swiper-container-' + s.params.direction);
258        
259        if (s.params.freeMode) {
260            s.classNames.push('swiper-container-free-mode');
261        }
262        if (!s.support.flexbox) {
263            s.classNames.push('swiper-container-no-flexbox');
264            s.params.slidesPerColumn = 1;
265        }
266        // Enable slides progress when required
267        if (s.params.parallax || s.params.watchSlidesVisibility) {
268            s.params.watchSlidesProgress = true;
269        }
270        // Coverflow / 3D
271        if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {
272            if (s.support.transforms3d) {
273                s.params.watchSlidesProgress = true;
274                s.classNames.push('swiper-container-3d');
275            }
276            else {
277                s.params.effect = 'slide';
278            }
279        }
280        if (s.params.effect !== 'slide') {
281            s.classNames.push('swiper-container-' + s.params.effect);
282        }
283        if (s.params.effect === 'cube') {
284            s.params.resistanceRatio = 0;
285            s.params.slidesPerView = 1;
286            s.params.slidesPerColumn = 1;
287            s.params.slidesPerGroup = 1;
288            s.params.centeredSlides = false;
289            s.params.spaceBetween = 0;
290            s.params.virtualTranslate = true;
291            s.params.setWrapperSize = false;
292        }
293        if (s.params.effect === 'fade') {
294            s.params.slidesPerView = 1;
295            s.params.slidesPerColumn = 1;
296            s.params.slidesPerGroup = 1;
297            s.params.watchSlidesProgress = true;
298            s.params.spaceBetween = 0;
299            if (typeof initialVirtualTranslate === 'undefined') {
300                s.params.virtualTranslate = true;
301            }
302        }
303        
304        // Grab Cursor
305        if (s.params.grabCursor && s.support.touch) {
306            s.params.grabCursor = false;
307        }
308        
309        // Wrapper
310        s.wrapper = s.container.children('.' + s.params.wrapperClass);
311        
312        // Pagination
313        if (s.params.pagination) {
314            s.paginationContainer = $(s.params.pagination);
315            if (s.params.paginationClickable) {
316                s.paginationContainer.addClass('swiper-pagination-clickable');
317            }
318        }
319        
320        // Is Horizontal
321        function isH() {
322            return s.params.direction === 'horizontal';
323        }
324        
325        // RTL
326        s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
327        if (s.rtl) {
328            s.classNames.push('swiper-container-rtl');
329        }
330        
331        // Wrong RTL support
332        if (s.rtl) {
333            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
334        }
335        
336        // Columns
337        if (s.params.slidesPerColumn > 1) {
338            s.classNames.push('swiper-container-multirow');
339        }
340        
341        // Check for Android
342        if (s.device.android) {
343            s.classNames.push('swiper-container-android');
344        }
345        
346        // Add classes
347        s.container.addClass(s.classNames.join(' '));
348        
349        // Translate
350        s.translate = 0;
351        
352        // Progress
353        s.progress = 0;
354        
355        // Velocity
356        s.velocity = 0;
357        
358        /*=========================
359          Locks, unlocks
360          ===========================*/
361        s.lockSwipeToNext = function () {
362            s.params.allowSwipeToNext = false;
363        };
364        s.lockSwipeToPrev = function () {
365            s.params.allowSwipeToPrev = false;
366        };
367        s.lockSwipes = function () {
368            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
369        };
370        s.unlockSwipeToNext = function () {
371            s.params.allowSwipeToNext = true;
372        };
373        s.unlockSwipeToPrev = function () {
374            s.params.allowSwipeToPrev = true;
375        };
376        s.unlockSwipes = function () {
377            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
378        };
379        
380        /*=========================
381          Round helper
382          ===========================*/
383        function round(a) {
384            return Math.floor(a);
385        }  
386        /*=========================
387          Set grab cursor
388          ===========================*/
389        if (s.params.grabCursor) {
390            s.container[0].style.cursor = 'move';
391            s.container[0].style.cursor = '-webkit-grab';
392            s.container[0].style.cursor = '-moz-grab';
393            s.container[0].style.cursor = 'grab';
394        }
395        /*=========================
396          Update on Images Ready
397          ===========================*/
398        s.imagesToLoad = [];
399        s.imagesLoaded = 0;
400        
401        s.loadImage = function (imgElement, src, checkForComplete, callback) {
402            var image;
403            function onReady () {
404                if (callback) callback();
405            }
406            if (!imgElement.complete || !checkForComplete) {
407                if (src) {
408                    image = new window.Image();
409                    image.onload = onReady;
410                    image.onerror = onReady;
411                    image.src = src;
412                } else {
413                    onReady();
414                }
415        
416            } else {//image already loaded...
417                onReady();
418            }
419        };
420        s.preloadImages = function () {
421            s.imagesToLoad = s.container.find('img');
422            function _onReady() {
423                if (typeof s === 'undefined' || s === null) return;
424                if (s.imagesLoaded !== undefined) s.imagesLoaded++;
425                if (s.imagesLoaded === s.imagesToLoad.length) {
426                    if (s.params.updateOnImagesReady) s.update();
427                    s.emit('onImagesReady', s);
428                }
429            }
430            for (var i = 0; i < s.imagesToLoad.length; i++) {
431                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), true, _onReady);
432            }
433        };
434        
435        /*=========================
436          Autoplay
437          ===========================*/
438        s.autoplayTimeoutId = undefined;
439        s.autoplaying = false;
440        s.autoplayPaused = false;
441        function autoplay() {
442            s.autoplayTimeoutId = setTimeout(function () {
443                if (s.params.loop) {
444                    s.fixLoop();
445                    s._slideNext();
446                }
447                else {
448                    if (!s.isEnd) {
449                        s._slideNext();
450                    }
451                    else {
452                        if (!params.autoplayStopOnLast) {
453                            s._slideTo(0);
454                        }
455                        else {
456                            s.stopAutoplay();
457                        }
458                    }
459                }
460            }, s.params.autoplay);
461        }
462        s.startAutoplay = function () {
463            if (typeof s.autoplayTimeoutId !== 'undefined') return false;
464            if (!s.params.autoplay) return false;
465            if (s.autoplaying) return false;
466            s.autoplaying = true;
467            s.emit('onAutoplayStart', s);
468            autoplay();
469        };
470        s.stopAutoplay = function (internal) {
471            if (!s.autoplayTimeoutId) return;
472            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
473            s.autoplaying = false;
474            s.autoplayTimeoutId = undefined;
475            s.emit('onAutoplayStop', s);
476        };
477        s.pauseAutoplay = function (speed) {
478            if (s.autoplayPaused) return;
479            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
480            s.autoplayPaused = true;
481            if (speed === 0) {
482                s.autoplayPaused = false;
483                autoplay();
484            }
485            else {
486                s.wrapper.transitionEnd(function () {
487                    if (!s) return;
488                    s.autoplayPaused = false;
489                    if (!s.autoplaying) {
490                        s.stopAutoplay();
491                    }
492                    else {
493                        autoplay();
494                    }
495                });
496            }
497        };
498        /*=========================
499          Min/Max Translate
500          ===========================*/
501        s.minTranslate = function () {
502            return (-s.snapGrid[0]);
503        };
504        s.maxTranslate = function () {
505            return (-s.snapGrid[s.snapGrid.length - 1]);
506        };
507        /*=========================
508          Slider/slides sizes
509          ===========================*/
510        s.updateContainerSize = function () {
511            var width, height;
512            if (typeof s.params.width !== 'undefined') {
513                width = s.params.width;
514            }
515            else {
516                width = s.container[0].clientWidth;
517            }
518            if (typeof s.params.height !== 'undefined') {
519                height = s.params.height;
520            }
521            else {
522                height = s.container[0].clientHeight;
523            }
524            if (width === 0 && isH() || height === 0 && !isH()) {
525                return;
526            }
527            
528            //Subtract paddings
529            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);
530            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);
531            
532            // Store values
533            s.width = width;
534            s.height = height;
535            s.size = isH() ? s.width : s.height;
536        };
537        
538        s.updateSlidesSize = function () {
539            s.slides = s.wrapper.children('.' + s.params.slideClass);
540            s.snapGrid = [];
541            s.slidesGrid = [];
542            s.slidesSizesGrid = [];
543        
544            var spaceBetween = s.params.spaceBetween,
545                slidePosition = -s.params.slidesOffsetBefore,
546                i,
547                prevSlideSize = 0,
548                index = 0;
549            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
550                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
551            }
552        
553            s.virtualSize = -spaceBetween;
554            // reset margins
555            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
556            else s.slides.css({marginRight: '', marginBottom: ''});
557        
558            var slidesNumberEvenToRows;
559            if (s.params.slidesPerColumn > 1) {
560                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
561                    slidesNumberEvenToRows = s.slides.length;
562                }
563                else {
564                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
565                }
566            }
567        
568            // Calc slides
569            var slideSize;
570            var slidesPerColumn = s.params.slidesPerColumn;
571            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
572            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);
573            for (i = 0; i < s.slides.length; i++) {
574                slideSize = 0;
575                var slide = s.slides.eq(i);
576                if (s.params.slidesPerColumn > 1) {
577                    // Set slides order
578                    var newSlideOrderIndex;
579                    var column, row;
580                    if (s.params.slidesPerColumnFill === 'column') {
581                        column = Math.floor(i / slidesPerColumn);
582                        row = i - column * slidesPerColumn;
583                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {
584                            if (++row >= slidesPerColumn) {
585                                row = 0;
586                                column++;
587                            }
588                        }
589                        newSlideOrderIndex = column + row * slidesNumber
589EvenToRows / slidesPerColumn;
590                        slide
591                            .css({
592                                '-webkit-box-ordinal-group': newSlideOrderIndex,
593                                '-moz-box-ordinal-group': newSlideOrderIndex,
594                                '-ms-flex-order': newSlideOrderIndex,
595                                '-webkit-order': newSlideOrderIndex,
596                                'order': newSlideOrderIndex
597                            });
598                    }
599                    else {
600                        row = Math.floor(i / slidesPerRow);
601                        column = i - row * slidesPerRow;
602                    }
603                    slide
604                        .css({
605                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
606                        })
607                        .attr('data-swiper-column', column)
608                        .attr('data-swiper-row', row);
609        
610                }
611                if (slide.css('display') === 'none') continue;
612                if (s.params.slidesPerView === 'auto') {
613                    slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true);
614                    if (s.params.roundLengths) slideSize = round(slideSize);
615                }
616                else {
617                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
618                    if (s.params.roundLengths) slideSize = round(slideSize);
619        
620                    if (isH()) {
621                        s.slides[i].style.width = slideSize + 'px';
622                    }
623                    else {
624                        s.slides[i].style.height = slideSize + 'px';
625                    }
626                }
627                s.slides[i].swiperSlideSize = slideSize;
628                s.slidesSizesGrid.push(slideSize);
629        
630        
631                if (s.params.centeredSlides) {
632                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
633                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
634                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
635                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
636                    s.slidesGrid.push(slidePosition);
637                }
638                else {
639                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
640                    s.slidesGrid.push(slidePosition);
641                    slidePosition = slidePosition + slideSize + spaceBetween;
642                }
643        
644                s.virtualSize += slideSize + spaceBetween;
645        
646                prevSlideSize = slideSize;
647        
648                index ++;
649            }
650            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;
651        
652            var newSlidesGrid;
653        
654            if (
655                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
656                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
657            }
658            if (!s.support.flexbox || s.params.setWrapperSize) {
659                if (isH()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
660                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
661            }
662        
663            if (s.params.slidesPerColumn > 1) {
664                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
665                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
666                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
667                if (s.params.centeredSlides) {
668                    newSlidesGrid = [];
669                    for (i = 0; i < s.snapGrid.length; i++) {
670                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
671                    }
672                    s.snapGrid = newSlidesGrid;
673                }
674            }
675        
676            // Remove last grid elements depending on width
677            if (!s.params.centeredSlides) {
678                newSlidesGrid = [];
679                for (i = 0; i < s.snapGrid.length; i++) {
680                    if (s.snapGrid[i] <= s.virtualSize - s.size) {
681                        newSlidesGrid.push(s.snapGrid[i]);
682                    }
683                }
684                s.snapGrid = newSlidesGrid;
685                if (Math.floor(s.virtualSize - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) {
686                    s.snapGrid.push(s.virtualSize - s.size);
687                }
688            }
689            if (s.snapGrid.length === 0) s.snapGrid = [0];
690        
691            if (s.params.spaceBetween !== 0) {
692                if (isH()) {
693                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
694                    else s.slides.css({marginRight: spaceBetween + 'px'});
695                }
696                else s.slides.css({marginBottom: spaceBetween + 'px'});
697            }
698            if (s.params.watchSlidesProgress) {
699                s.updateSlidesOffset();
700            }
701        };
702        s.updateSlidesOffset = function () {
703            for (var i = 0; i < s.slides.length; i++) {
704                s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
705            }
706        };
707        
708        /*=========================
709          Slider/slides progress
710          ===========================*/
711        s.updateSlidesProgress = function (translate) {
712            if (typeof translate === 'undefined') {
713                translate = s.translate || 0;
714            }
715            if (s.slides.length === 0) return;
716            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
717        
718            var offsetCenter = -translate;
719            if (s.rtl) offsetCenter = translate;
720        
721            // Visible Slides
722            var containerBox = s.container[0].getBoundingClientRect();
723            var sideBefore = isH() ? 'left' : 'top';
724            var sideAfter = isH() ? 'right' : 'bottom';
725            s.slides.removeClass(s.params.slideVisibleClass);
726            for (var i = 0; i < s.slides.length; i++) {
727                var slide = s.slides[i];
728                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
729                if (s.params.watchSlidesVisibility) {
730                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
731                    var slideAfter = slideBefore + s.slidesSizesGrid[i];
732                    var isVisible =
733                        (slideBefore >= 0 && slideBefore < s.size) ||
734                        (slideAfter > 0 && slideAfter <= s.size) ||
735                        (slideBefore <= 0 && slideAfter >= s.size);
736                    if (isVisible) {
737                        s.slides.eq(i).addClass(s.params.slideVisibleClass);
738                    }
739                }
740                slide.progress = s.rtl ? -slideProgress : slideProgress;
741            }
742        };
743        s.updateProgress = function (translate) {
744            if (typeof translate === 'undefined') {
745                translate = s.translate || 0;
746            }
747            var translatesDiff = s.maxTranslate() - s.minTranslate();
748            if (translatesDiff === 0) {
749                s.progress = 0;
750                s.isBeginning = s.isEnd = true;
751            }
752            else {
753                s.progress = (translate - s.minTranslate()) / (translatesDiff);
754                s.isBeginning = s.progress <= 0;
755                s.isEnd = s.progress >= 1;
756            }
757            if (s.isBeginning) s.emit('onReachBeginning', s);
758            if (s.isEnd) s.emit('onReachEnd', s);
759        
760            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
761            s.emit('onProgress', s, s.progress);
762        };
763        s.updateActiveIndex = function () {
764            var translate = s.rtl ? s.translate : -s.translate;
765            var newActiveIndex, i, snapIndex;
766            for (i = 0; i < s.slidesGrid.length; i ++) {
767                if (typeof s.slidesGrid[i + 1] !== 'undefined') {
768                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
769                        newActiveIndex = i;
770                    }
771                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
772                        newActiveIndex = i + 1;
773                    }
774                }
775                else {
776                    if (translate >= s.slidesGrid[i]) {
777                        newActiveIndex = i;
778                    }
779                }
780            }
781            // Normalize slideIndex
782            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
783            // for (i = 0; i < s.slidesGrid.length; i++) {
784                // if (- translate >= s.slidesGrid[i]) {
785                    // newActiveIndex = i;
786                // }
787            // }
788            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
789            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
790        
791            if (newActiveIndex === s.activeIndex) {
792                return;
793            }
794            s.snapIndex = snapIndex;
795            s.previousIndex = s.activeIndex;
796            s.activeIndex = newActiveIndex;
797            s.updateClasses();
798        };
799        
800        /*=========================
801          Classes
802          ===========================*/
803        s.updateClasses = function () {
804            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);
805            var activeSlide = s.slides.eq(s.activeIndex);
806            // Active classes
807            activeSlide.addClass(s.params.slideActiveClass);
808            activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
809            activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
810        
811            // Pagination
812            if (s.bullets && s.bullets.length > 0) {
813                s.bullets.removeClass(s.params.bulletActiveClass);
814                var bulletIndex;
815                if (s.params.loop) {
816                    bulletIndex = Math.ceil(s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup;
817                    if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {
818                        bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);
819                    }
820                    if (bulletIndex > s.bullets.length - 1) bulletIndex = bulletIndex - s.bullets.length;
821                }
822                else {
823                    if (typeof s.snapIndex !== 'undefined') {
824                        bulletIndex = s.snapIndex;
825                    }
826                    else {
827                        bulletIndex = s.activeIndex || 0;
828                    }
829                }
830                if (s.paginationContainer.length > 1) {
831                    s.bullets.each(function () {
832                        if ($(this).index() === bulletIndex) $(this).addClass(s.params.bulletActiveClass);
833                    });
834                }
835                else {
836                    s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);
837                }
838            }
839        
840            // Next/active buttons
841            if (!s.params.loop) {
842                if (s.params.prevButton) {
843                    if (s.isBeginning) {
844                        $(s.params.prevButton).addClass(s.params.buttonDisabledClass);
845                        if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.prevButton));
846                    }
847                    else {
848                        $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
849                        if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.prevButton));
850                    }
851                }
852                if (s.params.nextButton) {
853                    if (s.isEnd) {
854                        $(s.params.nextButton).addClass(s.params.buttonDisabledClass);
855                        if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.nextButton));
856                    }
857                    else {
858                        $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
859                        if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.nextButton));
860                    }
861                }
862            }
863        };
864        
865        /*=========================
866          Pagination
867          ===========================*/
868        s.updatePagination = function () {
869            if (!s.params.pagination) return;
870            if (s.paginationContainer && s.paginationContainer.length > 0) {
871                var bulletsHTML = '';
872                var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
873                for (var i = 0; i < numberOfBullets; i++) {
874                    if (s.params.paginationBulletRender) {
875                        bulletsHTML += s.params.paginationBulletRender(i, s.params.bulletClass);
876                    }
877                    else {
878                        bulletsHTML += '<' + s.params.paginationElement+' class="' + s.params.bulletClass + '"></' + s.params.paginationElement + '>';
879                    }
880                }
881                s.paginationContainer.html(bulletsHTML);
882                s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
883                if (s.params.paginationClickable && s.params.a11y && s.a11y) {
884                    s.a11y.initPagination();
885                }
886            }
887        };
888        /*=========================
889          Common update method
890          ===========================*/
891        s.update = function (updateTranslate) {
892            s.updateContainerSize();
893            s.updateSlidesSize();
894            s.updateProgress();
895            s.updatePagination();
896            s.updateClasses();
897            if (s.params.scrollbar && s.scrollbar) {
898                s.scrollbar.set();
899            }
900            function forceSetTranslate() {
901                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
902                s.setWrapperTranslate(newTranslate);
903                s.updateActiveIndex();
904                s.updateClasses();
905            }
906            if (updateTranslate) {
907                var translated, newTranslate;
908                if (s.controller && s.controller.spline) {
909                    s.controller.spline = undefined;
910                }
911                if (s.params.freeMode) {
912                    forceSetTranslate();
913                }
914                else {
915                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
916                        translated = s.slideTo(s.slides.length - 1, 0, false, true);
917                    }
918                    else {
919                        translated = s.slideTo(s.activeIndex, 0, false, true);
920                    }
921                    if (!translated) {
922                        forceSetTranslate();
923                    }
924                }
925        
926            }
927        };
928        
929        /*=========================
930          Resize Handler
931          ===========================*/
932        s.onResize = function (forceUpdatePagination) {
933            // Disable locks on resize
934            var allowSwipeToPrev = s.params.allowSwipeToPrev;
935            var allowSwipeToNext = s.params.allowSwipeToNext;
936            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;
937        
938            s.updateContainerSize();
939            s.updateSlidesSize();
940            if (s.params.slidesPerView === 'auto' || s.params.freeMode || force
940UpdatePagination) s.updatePagination();
941            if (s.params.scrollbar && s.scrollbar) {
942                s.scrollbar.set();
943            }
944            if (s.controller && s.controller.spline) {
945                s.controller.spline = undefined;
946            }
947            if (s.params.freeMode) {
948                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
949                s.setWrapperTranslate(newTranslate);
950                s.updateActiveIndex();
951                s.updateClasses();
952            }
953            else {
954                s.updateClasses();
955                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
956                    s.slideTo(s.slides.length - 1, 0, false, true);
957                }
958                else {
959                    s.slideTo(s.activeIndex, 0, false, true);
960                }
961            }
962            // Return locks after resize
963            s.params.allowSwipeToPrev = allowSwipeToPrev;
964            s.params.allowSwipeToNext = allowSwipeToNext;
965        };
966        
967        /*=========================
968          Events
969          ===========================*/
970        
971        //Define Touch Events
972        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
973        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
974        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
975        s.touchEvents = {
976            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],
977            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],
978            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]
979        };
980        
981        
982        // WP8 Touch Events Fix
983        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
984            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
985        }
986        
987        // Attach/detach events
988        s.initEvents = function (detach) {
989            var actionDom = detach ? 'off' : 'on';
990            var action = detach ? 'removeEventListener' : 'addEventListener';
991            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
992            var target = s.support.touch ? touchEventsTarget : document;
993        
994            var moveCapture = s.params.nested ? true : false;
995        
996            //Touch Events
997            if (s.browser.ie) {
998                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
999                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
1000                target[action](s.touchEvents.end, s.onTouchEnd, false);
1001            }
1002            else {
1003                if (s.support.touch) {
1004                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
1005                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
1006                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);
1007                }
1008                if (params.simulateTouch && !s.device.ios && !s.device.android) {
1009                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);
1010                    document[action]('mousemove', s.onTouchMove, moveCapture);
1011                    document[action]('mouseup', s.onTouchEnd, false);
1012                }
1013            }
1014            window[action]('resize', s.onResize);
1015        
1016            // Next, Prev, Index
1017            if (s.params.nextButton) {
1018                $(s.params.nextButton)[actionDom]('click', s.onClickNext);
1019                if (s.params.a11y && s.a11y) $(s.params.nextButton)[actionDom]('keydown', s.a11y.onEnterKey);
1020            }
1021            if (s.params.prevButton) {
1022                $(s.params.prevButton)[actionDom]('click', s.onClickPrev);
1023                if (s.params.a11y && s.a11y) $(s.params.prevButton)[actionDom]('keydown', s.a11y.onEnterKey);
1024            }
1025            if (s.params.pagination && s.params.paginationClickable) {
1026                $(s.paginationContainer)[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
1027                if (s.params.a11y && s.a11y) $(s.paginationContainer)[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);
1028            }
1029        
1030            // Prevent Links Clicks
1031            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
1032        };
1033        s.attachEvents = function (detach) {
1034            s.initEvents();
1035        };
1036        s.detachEvents = function () {
1037            s.initEvents(true);
1038        };
1039        
1040        /*=========================
1041          Handle Clicks
1042          ===========================*/
1043        // Prevent Clicks
1044        s.allowClick = true;
1045        s.preventClicks = function (e) {
1046            if (!s.allowClick) {
1047                if (s.params.preventClicks) e.preventDefault();
1048                if (s.params.preventClicksPropagation && s.animating) {
1049                    e.stopPropagation();
1050                    e.stopImmediatePropagation();
1051                }
1052            }
1053        };
1054        // Clicks
1055        s.onClickNext = function (e) {
1056            e.preventDefault();
1057            if (s.isEnd && !s.params.loop) return;
1058            s.slideNext();
1059        };
1060        s.onClickPrev = function (e) {
1061            e.preventDefault();
1062            if (s.isBeginning && !s.params.loop) return;
1063            s.slidePrev();
1064        };
1065        s.onClickIndex = function (e) {
1066            e.preventDefault();
1067            var index = $(this).index() * s.params.slidesPerGroup;
1068            if (s.params.loop) index = index + s.loopedSlides;
1069            s.slideTo(index);
1070        };
1071        
1072        /*=========================
1073          Handle Touches
1074          ===========================*/
1075        function findElementInEvent(e, selector) {
1076            var el = $(e.target);
1077            if (!el.is(selector)) {
1078                if (typeof selector === 'string') {
1079                    el = el.parents(selector);
1080                }
1081                else if (selector.nodeType) {
1082                    var found;
1083                    el.parents().each(function (index, _el) {
1084                        if (_el === selector) found = selector;
1085                    });
1086                    if (!found) return undefined;
1087                    else return selector;
1088                }
1089            }
1090            if (el.length === 0) {
1091                return undefined;
1092            }
1093            return el[0];
1094        }
1095        s.updateClickedSlide = function (e) {
1096            var slide = findElementInEvent(e, '.' + s.params.slideClass);
1097            var slideFound = false;
1098            if (slide) {
1099                for (var i = 0; i < s.slides.length; i++) {
1100                    if (s.slides[i] === slide) slideFound = true;
1101                }
1102            }
1103        
1104            if (slide && slideFound) {
1105                s.clickedSlide = slide;
1106                s.clickedIndex = $(slide).index();
1107            }
1108            else {
1109                s.clickedSlide = undefined;
1110                s.clickedIndex = undefined;
1111                return;
1112            }
1113            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
1114                var slideToIndex = s.clickedIndex,
1115                    realIndex;
1116                if (s.params.loop) {
1117                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');
1118                    if (slideToIndex > s.slides.length - s.params.slidesPerView) {
1119                        s.fixLoop();
1120                        slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]').eq(0).index();
1121                        setTimeout(function () {
1122                            s.slideTo(slideToIndex);
1123                        }, 0);
1124                    }
1125                    else if (slideToIndex < s.params.slidesPerView - 1) {
1126                        s.fixLoop();
1127                        var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]');
1128                        slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index();
1129                        setTimeout(function () {
1130                            s.slideTo(slideToIndex);
1131                        }, 0);
1132                    }
1133                    else {
1134                        s.slideTo(slideToIndex);
1135                    }
1136                }
1137                else {
1138                    s.slideTo(slideToIndex);
1139                }
1140            }
1141        };
1142        
1143        var isTouched,
1144            isMoved,
1145            touchStartTime,
1146            isScrolling,
1147            currentTranslate,
1148            startTranslate,
1149            allowThresholdMove,
1150            // Form elements to match
1151            formElements = 'input, select, textarea, button',
1152            // Last click time
1153            lastClickTime = Date.now(), clickTimeout,
1154            //Velocities
1155            velocities = [],
1156            allowMomentumBounce;
1157        
1158        // Animating Flag
1159        s.animating = false;
1160        
1161        // Touches information
1162        s.touches = {
1163            startX: 0,
1164            startY: 0,
1165            currentX: 0,
1166            currentY: 0,
1167            diff: 0
1168        };
1169        
1170        // Touch handlers
1171        var isTouchEvent, startMoving;
1172        s.onTouchStart = function (e) {
1173            if (e.originalEvent) e = e.originalEvent;
1174            isTouchEvent = e.type === 'touchstart';
1175            if (!isTouchEvent && 'which' in e && e.which === 3) return;
1176            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
1177                s.allowClick = true;
1178                return;
1179            }
1180            if (s.params.swipeHandler) {
1181                if (!findElementInEvent(e, s.params.swipeHandler)) return;
1182            }
1183        
1184            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
1185            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
1186            
1187            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
1188            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {
1189                return;
1190            }
1191        
1192            isTouched = true;
1193            isMoved = false;
1194            isScrolling = undefined;
1195            startMoving = undefined;
1196            s.touches.startX = startX;
1197            s.touches.startY = startY;
1198            touchStartTime = Date.now();
1199            s.allowClick = true;
1200            s.updateContainerSize();
1201            s.swipeDirection = undefined;
1202            if (s.params.threshold > 0) allowThresholdMove = false;
1203            if (e.type !== 'touchstart') {
1204                var preventDefault = true;
1205                if ($(e.target).is(formElements)) preventDefault = false;
1206                if (document.activeElement && $(document.activeElement).is(formElements)) {
1207                    document.activeElement.blur();
1208                }
1209                if (preventDefault) {
1210                    e.preventDefault();
1211                }
1212            }
1213            s.emit('onTouchStart', s, e);
1214        };
1215        
1216        s.onTouchMove = function (e) {
1217            if (e.originalEvent) e = e.originalEvent;
1218            if (isTouchEvent && e.type === 'mousemove') return;
1219            if (e.preventedByNestedSwiper) return;
1220            if (s.params.onlyExternal) {
1221                // isMoved = true;
1222                s.allowClick = false;
1223                if (isTouched) {
1224                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1225                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1226                    touchStartTime = Date.now();
1227                }
1228                return;
1229            }
1230            if (isTouchEvent && document.activeElement) {
1231                if (e.target === document.activeElement && $(e.target).is(formElements)) {
1232                    isMoved = true;
1233                    s.allowClick = false;
1234                    return;
1235                }
1236            }
1237        
1238            s.emit('onTouchMove', s, e);
1239        
1240            if (e.targetTouches && e.targetTouches.length > 1) return;
1241        
1242            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1243            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1244        
1245            if (typeof isScrolling === 'undefined') {
1246                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
1247                isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
1248            }
1249            if (isScrolling) {
1250                s.emit('onTouchMoveOpposite', s, e);
1251            }
1252            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {
1253                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
1254                    startMoving = true;
1255                }
1256            }
1257            if (!isTouched) return;
1258            if (isScrolling)  {
1259                isTouched = false;
1260                return;
1261            }
1262            if (!startMoving && s.browser.ieTouch) {
1263                return;
1264            }
1265            s.allowClick = false;
1266            s.emit('onSliderMove', s, e);
1267            e.preventDefault();
1268            if (s.params.touchMoveStopPropagation && !s.params.nested) {
1269                e.stopPropagation();
1270            }
1271        
1272            if (!isMoved) {
1273                if (params.loop) {
1274                    s.fixLoop();
1275                }
1276                startTranslate = s.getWrapperTranslate();
1277                s.setWrapperTransition(0);
1278                if (s.animating) {
1279                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
1280                }
1281                if (s.params.autoplay && s.autoplaying) {
1282                    if (s.params.autoplayDisableOnInteraction) {
1283                        s.stopAutoplay();
1284                    }
1285                    else {
1286                        s.pauseAutoplay();
1287                    }
1288                }
1289                allowMomentumBounce = false;
1290                //Grab Cursor
1291                if (s.params.grabCursor) {
1292                    s.container[0].style.cursor = 'move';
1293                    s.container[0].style.cursor = '-webkit-grabbing';
1294                    s.container[0].style.cursor = '-moz-grabbin';
1295                    s.container[0].style.cursor = 'grabbing';
1296                }
1297            }
1298            isMoved = true;
1299        
1300            var diff = s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1301            
1302            diff = diff * s.params.touchRatio;
1303            if (s.rtl) diff = -diff;
1304        
1305            s.swipeDirection = diff > 0 ? 'prev' : 'next';
1306            currentTranslate = diff + startTranslate;
1307        
1308            var disableParentSwiper = true;
1309            if ((diff > 0 && currentTranslate > s.minTranslate())) {
1310                disableParentSwiper = false;
1311                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
1312            }
1313            else if (diff < 0 && currentTranslate < s.maxTranslate()) {
1314                disableParentSwiper = false;
1315                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
1316            }
1317        
1318            if (disableParentSwiper) {
1319                e.preventedByNestedSwiper = true;
1320            }
1321        
1322            // Directions locks
1323            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
1324                currentTranslate = startTranslate;
1325            }
1326            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
1327                currentTranslate = startTranslate;
1328            }
1329        
1330            if (!s.params.followFinger) return;
1331        
1332            // Threshold
1333            if (s.params.threshold > 0) {
1334                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
1335                    if (!allowThresholdMove) {
1336                        allowThresholdMove = true;
1337                        s.touches.startX = s.touches.currentX;
1338                        s.touches.startY = s.touches.currentY;
1339                        currentTranslate = startTranslate;
1340                        s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1341                        return;
1342                    }
1343                }
1344                else {
1345                    currentTranslate = startTranslate;
1346                    return;
1347                }
1348            }
1349            // Update active index in free mode
1350            if (s.params.freeMode || s.params.watchSlidesProgress) {
1351                s.updateActiveIndex();
1352            }
1353            if (s.params.freeMode) {
1354                //Velocity
1355                if (velocities.length === 0) {
1356                    velocities.push({
1357                        position: s.touches[isH() ? 'startX' : 'startY'],
1358                        time: touchStartTime
1359                    });
1360                }
1361                velocities.push({
1362                    position: s.touches[isH() ? 'currentX' : 'currentY'],
1363                    time: (new window.Date()).getTime()
1364                });
1365            }
1366            // Update progress
1367            s.updateProgress(currentTranslate);
1368            // Update translate
1369            s.setWrapperTranslate(currentTranslate);
1370        };
1371        s.onTouchEnd = function (e) {
1372            if (e.originalEvent) e = e.originalEvent;
1373            s.emit('onTouchEnd', s, e);
1374            if (!isTouched) return;
1375            //Return Grab Cursor
1376            if (s.params.grabCursor && isMoved && isTouched) {
1377                s.container[0].style.cursor = 'move';
1378                s.container[0].style.cursor = '-webkit-grab';
1379                s.container[0].style.cursor = '-moz-grab';
1380                s.container[0].style.cursor = 'grab';
1381            }
1382        
1383            // Time diff
1384            var touchEndTime = Date.now();
1385            var timeDiff = touchEndTime - touchStartTime;
1386        
1387            // Tap, doubleTap, Click
1388            if (s.allowClick) {
1389                s.updateClickedSlide(e);
1390                s.emit('onTap', s, e);
1391                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
1392                    if (clickTimeout) clearTimeout(clickTimeout);
1393                    clickTimeout = setTimeout(function () {
1394                        if (!s) return;
1395                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
1396                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
1397                        }
1398                        s.emit('onClick', s, e);
1399                    }, 300);
1400        
1401                }
1402                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
1403                    if (clickTimeout) clearTimeout(clickTimeout);
1404                    s.emit('onDoubleTap', s, e);
1405                }
1406            }
1407        
1408            lastClickTime = Date.now();
1409            setTimeout(function () {
1410                if (s) s.allowClick = true;
1411            }, 0);
1412        
1413            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
1414                isTouched = isMoved = false;
1415                return;
1416            }
1417            isTouched = isMoved = false;
1418        
1419            var currentPos;
1420            if (s.params.followFinger) {
1421                currentPos = s.rtl ? s.translate : -s.translate;
1422            }
1423            else {
1424                currentPos = -currentTranslate;
1425            }
1426            if (s.params.freeMode) {
1427                if (currentPos < -s.minTranslate()) {
1428                    s.slideTo(s.activeIndex);
1429                    return;
1430                }
1431                else if (currentPos > -s.maxTranslate()) {
1432                    if (s.slides.length < s.snapGrid.length) {
1433                        s.slideTo(s.snapGrid.length - 1);
1434                    }
1435                    else {
1436                        s.slideTo(s.slides.length - 1);
1437                    }
1438                    return;
1439                }
1440        
1441                if (s.params.freeModeMomentum) {
1442                    if (velocities.length > 1) {
1443                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
1444        
1445                        var distance = lastMoveEvent.position - velocityEvent.position;
1446                        var time = lastMoveEvent.time - velocityEvent.time;
1447                        s.velocity = distance / time;
1448                        s.velocity = s.velocity / 2;
1449                        if (Math.abs(s.velocity) < 0.02) {
1450                            s.velocity = 0;
1451                        }
1452                        // this implies that the user stopped moving a finger then released.
1453                        // There would be no events with distance zero, so the last event is stale.
1454                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {
1455                            s.velocity = 0;
1456                        }
1457                    } else {
1458                        s.velocity = 0;
1459                    }
1460        
1461                    velocities.length = 0;
1462                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
1463                    var momentumDistance = s.velocity * momentumDuration;
1464        
1465                    var newPosition = s.translate + momentumDistance;
1466                    if (s.rtl) newPosition = - newPosition;
1467                    var doBounce = false;
1468                    var afterBouncePosition;
1469                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
1470                    if (newPosition < s.maxTranslate()) {
1471                        if (s.params.freeModeMomentumBounce) {
1472                            if (newPosition + s.maxTranslate() < -bounceAmount) {
1473                                newPosition = s.maxTranslate() - bounceAmount;
1474                            }
1475                            afterBouncePosition = s.maxTranslate();
1476                            doBounce = true;
1477                            allowMomentumBounce = true;
1478                        }
1479                        else {
1480                            newPosition = s.maxTranslate();
1481                        }
1482                    }
1483                    else if (newPosition > s.minTranslate()) {
1484                        if (s.params.freeModeMomentumBounce) {
1485                            if (newPosition - s.minTranslate() > bounceAmount) {
1486                                newPosition = s.minTranslate() + bounceAmount;
1487                            }
1488                            afterBouncePosition = s.minTranslate();
1489                            doBounce = true;
1490                            allowMomentumBounce = true;
1491                        }
1492                        else {
1493                            newPosition = s.minTranslate();
1494                        }
1495                    }
1496                    else if (s.params.freeModeSticky) {
1497                        var j = 0,
1498                            nextSlide;
1499                        for (j = 0; j < s.snapGrid.length; j += 1) {
1500                            if (s.snapGrid[j] > -newPosition) {
1501                                nextSlide = j;
1502                                break;
1503                            }
1504        
1505                        }
1506                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
1507                            newPosition = s.snapGrid[nextSlide];
1508                        } else {
1509                            newPosition = s.snapGrid[nextSlide - 1];
1510                        }
1511                        if (!s.rtl) newPosition = - newPosition;
1512                    }
1513                    //Fix duration
1514                    if (s.velocity !== 0) {
1515                        if (s.rtl) {
1516                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
1517                        }
1518                        else {
1519                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
1520                        }
1521                    }
1522                    else if (s.params.freeModeSticky) {
1523                        s.slideReset();
1524                        return;
1525                    }
1526        
1527                    if (s.params.freeModeMomentumBounce && doBounce) {
1528                        s.updateProgress(afterBouncePosition);
1529                        s.setWrapperTransition(momentumDuration);
1530                        s.setWrapperTranslate(newPosition);
1531                        s.onTransitionStart();
1532                        s.animating = true;
1533                        s.wrapper.transitionEnd(function () {
1534                            if (!s || !allowMomentumBounce) return;
1535                            s.emit('onMomentumBounce', s);
1536        
1537                            s.setWrapperTransition(s.params.speed);
1538                            s.setWrapperTranslate(afterBouncePosition);
1539                            s.wrapper.transitionEnd(function () {
1540                                if (!s) return;
1541                                s.onTransitionEnd();
1542                            });
1543                        });
1544                    } else if (s.velocity) {
1545                        s.updateProgress(newPosition);
1546                        s.setWrapperTransition(momentumDuration);
1547                        s.setWrapperTranslate(newPosition);
1548                        s.onTransitionStart();
1549                        if (!s.animating) {
1550                            s.animating = true;
1551                            s.wrapper.transitionEnd(function () {
1552                                if (!s) return;
1553                                s.onTransitionEnd();
1554                            });
1555                        }
1556        
1557                    } else {
1558                        s.updateProgress(newPosition);
1559                    }
1560        
1561                    s.updateActiveIndex();
1562                }
1563                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
1564                    s.updateProgress();
1565                    s.updateActiveIndex();
1566                }
1567                return;
1568            }
1569        
1570            // Find current slide
1571            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
1572            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
1573                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
1574                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
1575                        stopIndex = i;
1576                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
1577                    }
1578                }
1579                else {
1580                    if (currentPos >= s.slidesGrid[i]) {
1581                        stopIndex = i;
1582                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
1583                    }
1584                }
1585            }
1586        
1587            // Find current slide size
1588            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
1589        
1590            if (timeDiff > s.params.longSwipesMs) {
1591                // Long touches
1592                if (!s.params.longSwipes) {
1593                    s.slideTo(s.activeIndex);
1594                    return;
1595                }
1596                if (s.swipeDirection === 'next') {
1597                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
1598                    else s.slideTo(stopIndex);
1599        
1600                }
1601                if (s.swipeDirection === 'prev') {
1602                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
1603                    else s.slideTo(stopIndex);
1604                }
1605            }
1606            else {
1607                // Short swipes
1608                if (!s.params.shortSwipes) {
1609                    s.slideTo(s.activeIndex);
1610                    return;
1611                }
1612                if (s.swipeDirection === 'next') {
1613                    s.slideTo(stopIndex + s.params.slidesPerGroup);
1614        
1615                }
1616                if (s.swipeDirection === 'prev') {
1617                    s.slideTo(stopIndex);
1618                }
1619            }
1620        };
1621        /*=========================
1622          Transitions
1623          ===========================*/
1624        s._slideTo = function (slideIndex, speed) {
1625            return s.slideTo(slideIndex, speed, true, true);
1626        };
1627        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
1628            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1629            if (typeof slideIndex === 'undefined') slideIndex = 0;
1630            if (slideIndex < 0) slideIndex = 0;
1631            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
1632            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
1633        
1634            var translate = - s.snapGrid[s.snapIndex];
1635        
1636            // Stop autoplay
1637            if (s.params.autoplay && s.autoplaying) {
1638                if (internal || !s.params.autoplayDisableOnInteraction) {
1639                    s.pauseAutoplay(speed);
1640                }
1641                else {
1642                    s.stopAutoplay();
1643                }
1644            }
1645            // Update progress
1646            s.updateProgress(translate);
1647        
1648            // Normalize slideIndex
1649            for (var i = 0; i < s.slidesGrid.length; i++) {
1650                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {
1651                    slideIndex = i;
1652                }
1653            }
1654        
1655            // Directions locks
1656            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {
1657                return false;
1658            }
1659            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {
1660                if ((s.activeIndex || 0) !== slideIndex ) return false;
1661            }
1662        
1663            // Update Index
1664            if (typeof speed === 'undefined') speed = s.params.speed;
1665            s.previousIndex = s.activeIndex || 0;
1666            s.activeIndex = slideIndex;
1667        
1668            if (translate === s.translate) {
1669                s.updateClasses();
1670                return false;
1671            }
1672            s.updateClasses();
1673            s.onTransitionStart(runCallbacks);
1674            var translateX = isH() ? translate : 0, translateY = isH() ? 0 : translate;
1675            if (speed === 0) {
1676                s.setWrapperTransition(0);
1677                s.setWrapperTranslate(translate);
1678                s.onTransitionEnd(runCallbacks);
1679            }
1680            else {
1681                s.setWrapperTransition(speed);
1682                s.setWrapperTranslate(translate);
1683                if (!s.animating) {
1684                    s.animating = true;
1685                    s.wrapper.transitionEnd(function () {
1686                        if (!s) return;
1687                        s.onTransitionEnd(runCallbacks);
1688                    });
1689                }
1690        
1691            }
1692        
1693            return true;
1694        };
1695        
1696        s.onTransitionStart = function (runCallbacks) {
1697            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1698            if (s.lazy) s.lazy.onTransitionStart();
1699            if (runCallbacks) {
1700                s.emit('onTransitionStart', s);
1701                if (s.activeIndex !== s.previousIndex) {
1702                    s.emit('onSlideChangeStart', s);
1703                }
1704            }
1705        };
1706        s.onTransitionEnd = function (runCallbacks) {
1707            s.animating = false;
1708            s.setWrapperTransition(0);
1709            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1710            if (s.lazy) s.lazy.onTransitionEnd();
1711            if (runCallbacks) {
1712                s.emit('onTransitionEnd', s);
1713                if (s.activeIndex !== s.previousIndex) {
1714                    s.emit('onSlideChangeEnd', s);
1715                }
1716            }
1717            if (s.params.hashnav && s.hashnav) {
1718                s.hashnav.setHash();
1719            }
1720        
1721        };
1722        s.slideNext = function (runCallbacks, speed, internal) {
1723            if (s.params.loop) {
1724                if (s.animating) return false;
1725                s.fixLoop();
1726                var clientLeft = s.container[0].clientLeft;
1727                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
1728            }
1729            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
1730        };
1731        s._slideNext = function (speed) {
1732            return s.slideNext(true, speed, true);
1733        };
1734        s.slidePrev = function (runCallbacks, speed, internal) {
1735            if (s.params.loop) {
1736                if (s.animating) return false;
1737                s.fixLoop();
1738                var clientLeft = s.container[0].clientLeft;
1739                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
1740            }
1741            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
1742        };
1743        s._slidePrev = function (speed) {
1744            return s.slidePrev(true, speed, true);
1745        };
1746        s.slideReset = function (runCallbacks, speed, internal) {
1747            return s.slideTo(s.activeIndex, speed, runCallbacks);
1748        };
1749        
1750        /*=========================
1751          Translate/transition helpers
1752          ===========================*/
1753        s.setWrapperTransition = function (duration, byController) {
1754            s.wrapper.transition(duration);
1755            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
1756                s.effects[s.params.effect].setTransition(duration);
1757            }
1758            if (s.params.parallax && s.parallax) {
1759                s.parallax.setTransition(duration);
1760            }
1761            if (s.params.scrollbar && s.scrollbar) {
1762                s.scrollbar.setTransition(duration);
1763            }
1764            if (s.params.control && s.controller) {
1765                s.controller.setTransition(duration, byController);
1766            }
1767            s.emit('onSetTransition', s, duration);
1768        };
1769        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
1770            var x = 0, y = 0, z = 0;
1771            if (isH()) {
1772                x = s.rtl ? -translate : translate;
1773            }
1774            else {
1775                y = translate;
1776            }
1777            if (!s.params.virtualTranslate) {
1778                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
1779                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
1780            }
1781        
1782            s.translate = isH() ? x : y;
1783        
1784            if (updateActiveIndex) s.updateActiveIndex();
1785            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
1786                s.effects[s.params.effect].setTranslate(s.translate);
1787            }
1788            if (s.params.parallax && s.parallax) {
1789                s.parallax.setTranslate(s.translate);
1790            }
1791            if (s.params.scrollbar && s.scrollbar) {
1792                s.scrollbar.setTranslate(s.translate);
1793            }
1794            if (s.params.control && s.controller) {
1795                s.controller.setTranslate(s.translate, byController);
1796            }
1797            s.emit('onSetTranslate', s, s.translate);
1798        };
1799        
1800        s.getTranslate = function (el, axis) {
1801            var matrix, curTransform, curStyle, transformMatrix;
1802        
1803            // automatic axis detection
1804            if (typeof axis === 'undefined') {
1805                axis = 'x';
1806            }
1807        
1808            if (s.params.virtualTranslate) {
1809                return s.rtl ? -s.translate : s.translate;
1810            }
1811        
1812            curStyle = window.getComputedStyle(el, null);
1813            if (window.WebKitCSSMatrix) {
1814                // Some old versions of Webkit choke when 'none' is passed; pass
1815                // empty string instead in this case
1816                transformMatrix = new window.WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);
1817            }
1818            else {
1819                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
1820                matrix = transformMatrix.toString().split(',');
1821            }
1822        
1823            if (axis === 'x') {
1824                //Latest Chrome and webkits Fix
1825                if (window.WebKitCSSMatrix)
1826                    curTransform = transformMatrix.m41;
1827                //Crazy IE10 Matrix
1828                else if (matrix.length === 16)
1829                    curTransform = parseFloat(matrix[12]);
1830                //Normal Browsers
1831                else
1832                    curTransform = parseFloat(matrix[4]);
1833            }
1834            if (axis === 'y') {
1835                //Latest Chrome and webkits Fix
1836                if (window.WebKitCSSMatrix)
1837                    curTransform = transformMatrix.m42;
1838                //Crazy IE10 Matrix
1839                else if (matrix.length === 16)
1840                    curTransform = parseFloat(matrix[13]);
1841                //Normal Browsers
1842                else
1843                    curTransform = parseFloat(matrix[5]);
1844            }
1845            if (s.rtl && curTransform) curTransform = -curTransform;
1846            return curTransform || 0;
1847        };
1848        s.getWrapperTranslate = function (axis) {
1849            if (typeof axis === 'undefined') {
1850                axis = isH() ? 'x' : 'y';
1851            }
1852            return s.getTranslate(s.wrapper[0], axis);
1853        };
1854        
1855        /*=========================
1856          Observer
1857          ===========================*/
1858        s.observers = [];
1859        function initObserver(target, options) {
1860            options = options || {};
1861            // create an observer instance
1862            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
1863            var observer = new ObserverFunc(function (mutations) {
1864                mutations.forEach(function (mutation) {
1865                    s.onResize(true);
1866                    s.emit('onObserverUpdate', s, mutation);
1867                });
1868            });
1869        
1870            observer.observe(target, {
1871                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
1872                childList: typeof options.childList === 'undefined' ? true : options.childList,
1873                characterData: typeof options.characterData === 'undefined' ? true : options.characterData
1874            });
1875        
1876            s.observers.push(observer);
1877        }
1878        s.initObservers = function () {
1879            if (s.params.observeParents) {
1880                var containerParents = s.container.parents();
1881                for (var i = 0; i < containerParents.length; i++) {
1882                    initObserver(containerParents[i]);
1883                }
1884            }
1885        
1886            // Observe container
1887            initObserver(s.container[0], {childList: false});
1888        
1889            // Observe wrapper
1890            initObserver(s.wrapper[0], {attributes: false});
1891        };
1892        s.disconnectObservers = function () {
1893            for (var i = 0; i < s.observers.length; i++) {
1894                s.observers[i].disconnect();
1895            }
1896            s.observers = [];
1897        };
1898        /*=========================
1899          Loop
1900          ===========================*/
1901        // Create looped slides
1902        s.createLoop = function () {
1903            // Remove duplicated slides
1904            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
1905        
1906            var slides = s.wrapper.children('.' + s.params.slideClass);
1907        
1908            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;
1909        
1910            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
1911            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
1912            if (s.loopedSlides > slides.length) {
1913                s.loopedSlides = slides.length;
1914            }
1915        
1916            var prependSlides = [], appendSlides = [], i;
1917            slides.each(function (index, el) {
1918                var slide = $(this);
1919                if (index < s.loopedSlides) appendSlides.push(el);
1920                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
1921                slide.attr('data-swiper-slide-index', index);
1922            });
1923            for (i = 0; i < appendSlides.length; i++) {
1924                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
1925            }
1926            for (i = prependSlides.length - 1; i >= 0; i--) {
1927                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
1928            }
1929        };
1930        s.destroyLoop = function () {
1931            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
1932            s.slides.removeAttr('data-swiper-slide-index');
1933        };
1934        s.fixLoop = function () {
1935            var newIndex;
1936            //Fix For Negative Oversliding
1937            if (s.activeIndex < s.loopedSlides) {
1938                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
1939                newIndex = newIndex + s.loopedSlides;
1940                s.slideTo(newIndex, 0, false, true);
1941            }
1942            //Fix For Positive Oversliding
1943            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
1944                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
1945                newIndex = newIndex + s.loopedSlides;
1946                s.slideTo(newIndex, 0, false, true);
1947            }
1948        };
1949        /*=========================
1950          Append/Prepend/Remove Slides
1951          ===========================*/
1952        s.appendSlide = function (slides) {
1953            if (s.params.loop) {
1954                s.destroyLoop();
1955            }
1956            if (typeof slides === 'object' && slides.length) {
1957                for (var i = 0; i < slides.length; i++) {
1958                    if (slides[i]) s.wrapper.append(slides[i]);
1959                }
1960            }
1961            else {
1962                s.wrapper.append(slides);
1963            }
1964            if (s.params.loop) {
1965                s.createLoop();
1966            }
1967            if (!(s.params.observer && s.support.observer)) {
1968                s.update(true);
1969            }
1970        };
1971        s.prependSlide = function (slides) {
1972            if (s.params.loop) {
1973                s.destroyLoop();
1974            }
1975            var newActiveIndex = s.activeIndex + 1;
1976            if (typeof slides === 'object' && slides.length) {
1977                for (var i = 0; i < slides.length; i++) {
1978                    if (slides[i]) s.wrapper.prepend(slides[i]);
1979                }
1980                newActiveIndex = s.activeIndex + slides.length;
1981            }
1982            else {
1983                s.wrapper.prepend(slides);
1984            }
1985            if (s.params.loop) {
1986                s.createLoop();
1987            }
1988            if (!(s.params.observer && s.support.observer)) {
1989                s.update(true);
1990            }
1991            s.slideTo(newActiveIndex, 0, false);
1992        };
1993        s.removeSlide = function (slidesIndexes) {
1994            if (s.params.loop) {
1995                s.destroyLoop();
1996                s.slides = s.wrapper.children('.' + s.params.slideClass);
1997            }
1998            var newActiveIndex = s.activeIndex,
1999                indexToRemove;
2000            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
2001                for (var i = 0; i < slidesIndexes.length; i++) {
2002                    indexToRemove = slidesIndexes[i];
2003                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
2004                    if (indexToRemove < newActiveIndex) newActiveIndex--;
2005                }
2006                newActiveIndex = Math.max(newActiveIndex, 0);
2007            }
2008            else {
2009                indexToRemove = slidesIndexes;
2010                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
2011                if (indexToRemove < newActiveIndex) newActiveIndex--;
2012                newActiveIndex = Math.max(newActiveIndex, 0);
2013            }
2014        
2015            if (s.params.loop) {
2016                s.createLoop();
2017            }
2018        
2019            if (!(s.params.observer && s.support.observer)) {
2020                s.update(true);
2021            }
2022            if (s.params.loop) {
2023                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);
2024            }
2025            else {
2026                s.slideTo(newActiveIndex, 0, false);
2027            }
2028        
2029        };
2030        s.removeAllSlides = function () {
2031            var slidesIndexes = [];
2032            for (var i = 0; i < s.slides.length; i++) {
2033                slidesIndexes.push(i);
2034            }
2035            s.removeSlide(slidesIndexes);
2036        };
2037        
2038
2039        /*=========================
2040          Effects
2041          ===========================*/
2042        s.effects = {
2043            fade: {
2044                setTranslate: function () {
2045                    for (var i = 0; i < s.slides.length; i++) {
2046                        var slide = s.slides.eq(i);
2047                        var offset = slide[0].swiperSlideOffset;
2048                        var tx = -offset;
2049                        if (!s.params.virtualTranslate) tx = tx - s.translate;
2050                        var ty = 0;
2051                        if (!isH()) {
2052                            ty = tx;
2053                            tx = 0;
2054                        }
2055                        var slideOpacity = s.params.fade.crossFade ?
2056                                Math.max(1 - Math.abs(slide[0].progress), 0) :
2057                                1 + Math.min(Math.max(slide[0].progress, -1), 0);
2058                        slide
2059                            .css({
2060                                opacity: slideOpacity
2061                            })
2062                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
2063        
2064                    }
2065        
2066                },
2067                setTransition: function (duration) {
2068                    s.slides.transition(duration);
2069                    if (s.params.virtualTranslate && duration !== 0) {
2070                        var eventTriggered = false;
2071                        s.slides.transitionEnd(function () {
2072                            if (eventTriggered) return;
2073                            if (!s) return;
2074                            eventTriggered = true;
2075                            s.animating = false;
2076                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
2077                            for (var i = 0; i < triggerEvents.length; i++) {
2078                                s.wrapper.trigger(triggerEvents[i]);
2079                            }
2080                        });
2081                    }
2082                }
2083            },
2084            cube: {
2085                setTranslate: function () {
2086                    var wrapperRotate = 0, cubeShadow;
2087                    if (s.params.cube.shadow) {
2088                        if (isH()) {
2089                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');
2090                            if (cubeShadow.length === 0) {
2091                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
2092                                s.wrapper.append(cubeShadow);
2093                            }
2094                            cubeShadow.css({height: s.width + 'px'});
2095                        }
2096                        else {
2097                            cubeShadow = s.container.find('.swiper-cube-shadow');
2098                            if (cubeShadow.length === 0) {
2099                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
2100                                s.container.append(cubeShadow);
2101                            }
2102                        }
2103                    }
2104                    for (var i = 0; i < s.slides.length; i++) {
2105                        var slide = s.slides.eq(i);
2106                        var slideAngle = i * 90;
2107                        var round = Math.floor(slideAngle / 360);
2108                        if (s.rtl) {
2109                            slideAngle = -slideAngle;
2110                            round = Math.floor(-slideAngle / 360);
2111                        }
2112                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);
2113                        var tx = 0, ty = 0, tz = 0;
2114                        if (i % 4 === 0) {
2115                            tx = - round * 4 * s.size;
2116                            tz = 0;
2117                        }
2118                        else if ((i - 1) % 4 === 0) {
2119                            tx = 0;
2120                            tz = - round * 4 * s.size;
2121                        }
2122                        else if ((i - 2) % 4 === 0) {
2123                            tx = s.size + round * 4 * s.size;
2124                            tz = s.size;
2125                        }
2126                        else if ((i - 3) % 4 === 0) {
2127                            tx = - s.size;
2128                            tz = 3 * s.size + s.size * 4 * round;
2129                        }
2130                        if (s.rtl) {
2131                            tx = -tx;
2132                        }
2133                        
2134                        if (!isH()) {
2135                            ty = tx;
2136                            tx = 0;
2137                        }
2138                        
2139                        var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
2140                        if (progress <= 1 && progress > -1) {
2141                            wrapperRotate = i * 90 + progress * 90;
2142                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
2143                        }
2144                        slide.transform(transform);
2145                        if (s.params.cube.slideShadows) {
2146                            //Set shadows
2147                            var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2148                            var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2149                            if (shadowBefore.length === 0) {
2150                                shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
2151                                slide.append(shadowBefore);
2152                            }
2153                            if (shadowAfter.length === 0) {
2154                                shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
2155                                slide.append(shadowAfter);
2156                            }
2157                            var shadowOpacity = slide[0].progress;
2158                            if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;
2159                            if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;
2160                        }
2161                    }
2162                    s.wrapper.css({
2163                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2164                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2165                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2166                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
2167                    });
2168                        
2169                    if (s.params.cube.shadow) {
2170                        if (isH()) {
2171                            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) + ')');
2172                        }
2173                        else {
2174                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
2175                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
2176                            var scale1 = s.params.cube.shadowScale,
2177                                scale2 = s.params.cube.shadowScale / multiplier,
2178                                offset = s.params.cube.shadowOffset;
2179                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
2180                        }
2181                    }
2182                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
2183                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)');
2184                },
2185                setTransition: function (duration) {
2186                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2187                    if (s.params.cube.shadow && !isH()) {
2188                        s.container.find('.swiper-cube-shadow').transition(duration);
2189                    }
2190                }
2191            },
2192            coverflow: {
2193                setTranslate: function () {
2194                    var transform = s.translate;
2195                    var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;
2196                    var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
2197                    var translate = s.params.coverflow.depth;
2198                    //Each slide offset from center
2199                    for (var i = 0, length = s.slides.length; i < length; i++) {
2200                        var slide = s.slides.eq(i);
2201                        var slideSize = s.slidesSizesGrid[i];
2202                        var slideOffset = slide[0].swiperSlideOffset;
2203                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
2204        
2205                        var rotateY = isH() ? rotate * offsetMultiplier : 0;
2206                        var rotateX = isH() ? 0 : rotate * offsetMultiplier;
2207                        // var rotateZ = 0
2208                        var translateZ = -translate * Math.abs(offsetMultiplier);
2209        
2210                        var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
2211                        var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
2212        
2213                        //Fix for ultra small values
2214                        if (Math.abs(translateX) < 0.001) translateX = 0;
2215                        if (Math.abs(translateY) < 0.001) translateY = 0;
2216                        if (Math.abs(translateZ) < 0.001) translateZ = 0;
2217                        if (Math.abs(rotateY) < 0.001) rotateY = 0;
2218                        if (Math.abs(rotateX) < 0.001) rotateX = 0;
2219        
2220                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
2221        
2222                        slide.transform(slideTransform);
2223                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
2224                        if (s.params.coverflow.slideShadows) {
2225                            //Set shadows
2226                            var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2227                            var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2228                            if (shadowBefore.length === 0) {
2229                                shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
2230                                slide.append(shadowBefore);
2231                            }
2232                            if (shadowAfter.length === 0) {
2233                                shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
2234                                slide.append(shadowAfter);
2235                            }
2236                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
2237                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
2238                        }
2239                    }
2240        
2241                    //Set correct perspective for IE10
2242                    if (s.browser.ie) {
2243                        var ws = s.wrapper[0].style;
2244                        ws.perspectiveOrigin = center + 'px 50%';
2245                    }
2246                },
2247                setTransition: function (duration) {
2248                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2249                }
2250            }
2251        };
2252
2253        /*=========================
2254          Images Lazy Loading
2255          ===========================*/
2256        s.lazy = {
2257            initialImageLoaded: false,
2258            loadImageInSlide: function (index, loadInDuplicate) {
2259                if (typeof index === 'undefined') return;
2260                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;
2261                if (s.slides.length === 0) return;
2262                
2263                var slide = s.slides.eq(index);
2264                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');
2265                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {
2266                    img.add(slide[0]);
2267                }
2268                if (img.length === 0) return;
2269        
2270                img.each(function () {
2271                    var _img = $(this);
2272                    _img.addClass('swiper-lazy-loading');
2273                    var background = _img.attr('data-background');
2274                    var src = _img.attr('data-src');
2275                    s.loadImage(_img[0], (src || background), false, function () {
2276                        if (background) {
2277                            _img.css('background-image', 'url(' + background + ')');
2278                            _img.removeAttr('data-background');
2279                        }
2280                        else {
2281                            _img.attr('src', src);
2282                            _img.removeAttr('data-src');
2283                        }
2284                            
2285                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');
2286                        slide.find('.swiper-lazy-preloader, .preloader').remove();
2287                        if (s.params.loop && loadInDuplicate) {
2288                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');
2289                            if (slide.hasClass(s.params.slideDuplicateClass)) {
2290                                var originalSlide = s.wrapper.children('[data-swiper-slide-index="' + slideOriginalIndex + '"]:not(.' + s.params.slideDuplicateClass + ')');
2291                                s.lazy.loadImageInSlide(originalSlide.index(), false);
2292                            }
2293                            else {
2294                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + slideOriginalIndex + '"]');
2295                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);
2296                            }
2297                        }
2298                        s.emit('onLazyImageReady', s, slide[0], _img[0]);
2299                    });
2300                    
2301                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);
2302                });
2303                    
2304            },
2305            load: function () {
2306                var i;
2307                if (s.params.watchSlidesVisibility) {
2308                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
2309                        s.lazy.loadImageInSlide($(this).index());
2310                    });
2311                }
2312                else {
2313                    if (s.params.slidesPerView > 1) {
2314                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {
2315                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2316                        }
2317                    }
2318                    else {
2319                        s.lazy.loadImageInSlide(s.activeIndex);    
2320                    }
2321                }
2322                if (s.params.lazyLoadingInPrevNext) {
2323                    if (s.params.slidesPerView > 1) {
2324                        // Next Slides
2325                        for (i = s.activeIndex + s.params.slidesPerView; i < s.activeIndex + s.params.slidesPerView + s.params.slidesPerView; i++) {
2326                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2327                        }
2328                        // Prev Slides
2329                        for (i = s.activeIndex - s.params.slidesPerView; i < s.activeIndex ; i++) {
2330                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2331                        }
2332                    }
2333                    else {
2334                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
2335                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
2336        
2337                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
2338                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
2339                    }
2340                }
2341            },
2342            onTransitionStart: function () {
2343                if (s.params.lazyLoading) {
2344                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
2345                        s.lazy.load();
2346                    }
2347                }
2348            },
2349            onTransitionEnd: function () {
2350                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
2351                    s.lazy.load();
2352                }
2353            }
2354        };
2355        
2356
2357        /*=========================
2358          Scrollbar
2359          ===========================*/
2360        s.scrollbar = {
2361            set: function () {
2362                if (!s.params.scrollbar) return;
2363                var sb = s.scrollbar;
2364                sb.track = $(s.params.scrollbar);
2365                sb.drag = sb.track.find('.swiper-scrollbar-drag');
2366                if (sb.drag.length === 0) {
2367                    sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
2368                    sb.track.append(sb.drag);
2369                }
2370                sb.drag[0].style.width = '';
2371                sb.drag[0].style.height = '';
2372                sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
2373                
2374                sb.divider = s.size / s.virtualSize;
2375                sb.moveDivider = sb.divider * (sb.trackSize / s.size);
2376                sb.dragSize = sb.trackSize * sb.divider;
2377        
2378                if (isH()) {
2379                    sb.drag[0].style.width = sb.dragSize + 'px';
2380                }
2381                else {
2382                    sb.drag[0].style.height = sb.dragSize + 'px';
2383                }
2384        
2385                if (sb.divider >= 1) {
2386                    sb.track[0].style.display = 'none';
2387                }
2388                else {
2389                    sb.track[0].style.display = '';
2390                }
2391                if (s.params.scrollbarHide) {
2392                    sb.track[0].style.opacity = 0;
2393                }
2394            },
2395            setTranslate: function () {
2396                if (!s.params.scrollbar) return;
2397                var diff;
2398                var sb = s.scrollbar;
2399                var translate = s.translate || 0;
2400                var newPos;
2401                
2402                var newSize = sb.dragSize;
2403                newPos = (sb.trackSize - sb.dragSize) * s.progress;
2404                if (s.rtl && isH()) {
2405                    newPos = -newPos;
2406                    if (newPos > 0) {
2407                        newSize = sb.dragSize - newPos;
2408                        newPos = 0;
2409                    }
2410                    else if (-newPos + sb.dragSize > sb.trackSize) {
2411                        newSize = sb.trackSize + newPos;
2412                    }
2413                }
2414                else {
2415                    if (newPos < 0) {
2416                        newSize = sb.dragSize + newPos;
2417                        newPos = 0;
2418                    }
2419                    else if (newPos + sb.dragSize > sb.trackSize) {
2420                        newSize = sb.trackSize - newPos;
2421                    }
2422                }
2423                if (isH()) {
2424                    if (s.support.transforms3d) {
2425                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
2426                    }
2427                    else {
2428                        sb.drag.transform('translateX(' + (newPos) + 'px)');   
2429                    }
2430                    sb.drag[0].style.width = newSize + 'px';
2431                }
2432                else {
2433                    if (s.support.transforms3d) {
2434                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
2435                    }
2436                    else {
2437                        sb.drag.transform('translateY(' + (newPos) + 'px)');   
2438                    }
2439                    sb.drag[0].style.height = newSize + 'px';
2440                }
2441                if (s.params.scrollbarHide) {
2442                    clearTimeout(sb.timeout);
2443                    sb.track[0].style.opacity = 1;
2444                    sb.timeout = setTimeout(function () {
2445                        sb.track[0].style.opacity = 0;
2446                        sb.track.transition(400);
2447                    }, 1000);
2448                }
2449            },
2450            setTransition: function (duration) {
2451                if (!s.params.scrollbar) return;
2452                s.scrollbar.drag.transition(duration);
2453            }
2454        };
2455
2456        /*=========================
2457          Controller
2458          ===========================*/
2459        s.controller = {
2460            LinearSpline: function (x, y) {
2461                this.x = x;
2462                this.y = y;
2463                this.lastIndex = x.length - 1;
2464                // Given an x value (x2), return the expected y2 value:
2465                // (x1,y1) is the known point before given value,
2466                // (x3,y3) is the known point after given value.
2467                var i1, i3;
2468                var l = this.x.length;
2469        
2470                this.interpolate = function (x2) {
2471                    if (!x2) return 0;
2472        
2473                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):
2474                    i3 = binarySearch(this.x, x2);
2475                    i1 = i3 - 1;
2476        
2477                    // We have our indexes i1 & i3, so we can calculate already:
2478                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
2479                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
2480                };
2481        
2482                var binarySearch = (function() {
2483                    var maxIndex, minIndex, guess;
2484                    return function(array, val) {
2485                        minIndex = -1;
2486                        maxIndex = array.length;
2487                        while (maxIndex - minIndex > 1)
2488                            if (array[guess = maxIndex + minIndex >> 1] <= val) {
2489                                minIndex = guess;
2490                            } else {
2491                                maxIndex = guess;
2492                            }
2493                        return maxIndex;
2494                    };
2495                })();
2496            },
2497            //xxx: for now i will just save one spline function to to 
2498            getInterpolateFunction: function(c){
2499                if(!s.controller.spline) s.controller.spline = s.params.loop ? 
2500                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :
2501                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);
2502            },
2503            setTranslate: function (translate, byController) {
2504               var controlled = s.params.control;
2505               var multiplier, controlledTranslate;
2506               function setControlledTranslate(c) {
2507                    // this will create an Interpolate function based on the snapGrids
2508                    // x is the Grid of the scrolled scroller and y will be the controlled scroller
2509                    // it makes sense to create this only once and recall it for the interpolation
2510                    // the function does a lot of value caching for performance 
2511                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;
2512                    if (s.params.controlBy === 'slide') {
2513                        s.controller.getInterpolateFunction(c);
2514                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
2515                        // but it did not work out
2516                        controlledTranslate = -s.controller.spline.interpolate(-translate);
2517                    }
2518                        
2519                    if(!controlledTranslate || s.params.controlBy === 'container'){
2520                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());
2521                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();
2522                    }
2523                   
2524                    if (s.params.controlInverse) {
2525                        controlledTranslate = c.maxTranslate() - controlledTranslate;
2526                    }
2527                    c.updateProgress(controlledTranslate);
2528                    c.setWrapperTranslate(controlledTranslate, false, s);
2529                    c.updateActiveIndex();
2530               }
2531               if (s.isArray(controlled)) {
2532                   for (var i = 0; i < controlled.length; i++) {
2533                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
2534                           setControlledTranslate(controlled[i]);
2535                       }
2536                   }
2537               }
2538               else if (controlled instanceof Swiper && byController !== controlled) {
2539        
2540                   setControlledTranslate(controlled);
2541               }
2542            },
2543            setTransition: function (duration, byController) {
2544                var controlled = s.params.control;
2545                var i;
2546                function setControlledTransition(c) {
2547                    c.setWrapperTransition(duration, s);
2548                    if (duration !== 0) {
2549                        c.onTransitionStart();
2550                        c.wrapper.transitionEnd(function(){
2551                            if (!controlled) return;
2552                            if (c.params.loop && s.params.controlBy === 'slide') {
2553                                c.fixLoop();
2554                            }
2555                            c.onTransitionEnd();
2556                            
2557                        });
2558                    }
2559                }
2560                if (s.isArray(controlled)) {
2561                    for (i = 0; i < controlled.length; i++) {
2562                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
2563                            setControlledTransition(controlled[i]);
2564                        }
2565                    }
2566                }
2567                else if (controlled instanceof Swiper && byController !== controlled) {
2568                    setControlledTransition(controlled);
2569                }
2570            }
2571        };
2572
2573        /*=========================
2574          Hash Navigation
2575          ===========================*/
2576        s.hashnav = {
2577            init: function () {
2578                if (!s.params.hashnav) return;
2579                s.hashnav.initialized = true;
2580                var hash = document.location.hash.replace('#', '');
2581                if (!hash) return;
2582                var speed = 0;
2583                for (var i = 0, length = s.slides.length; i < length; i++) {
2584                    var slide = s.slides.eq(i);
2585                    var slideHash = slide.attr('data-hash');
2586                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {
2587                        var index = slide.index();
2588                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);
2589                    }
2590                }
2591            },
2592            setHash: function () {
2593                if (!s.hashnav.initialized || !s.params.hashnav) return;
2594                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';
2595            }
2596        };
2597
2598        /*=========================
2599          Keyboard Control
2600          ===========================*/
2601        function handleKeyboard(e) {
2602            if (e.originalEvent) e = e.originalEvent; //jquery fix
2603            var kc = e.keyCode || e.charCode;
2604            // Directions locks
2605            if (!s.params.allowSwipeToNext && (isH() && kc === 39 || !isH() && kc === 40)) {
2606                return false;
2607            }
2608            if (!s.params.allowSwipeToPrev && (isH() && kc === 37 || !isH() && kc === 38)) {
2609                return false;
2610            }
2611            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
2612                return;
2613            }
2614            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
2615                return;
2616            }
2617            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
2618                var inView = false;
2619                //Check that swiper should be inside of visible area of window
2620                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {
2621                    return;
2622                }
2623                var windowScroll = {
2624                    left: window.pageXOffset,
2625                    top: window.pageYOffset
2626                };
2627                var windowWidth = window.innerWidth;
2628                var windowHeight = window.innerHeight;
2629                var swiperOffset = s.container.offset();
2630                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;
2631                var swiperCoord = [
2632                    [swiperOffset.left, swiperOffset.top],
2633                    [swiperOffset.left + s.width, swiperOffset.top],
2634                    [swiperOffset.left, swiperOffset.top + s.height],
2635                    [swiperOffset.left + s.width, swiperOffset.top + s.height]
2636                ];
2637                for (var i = 0; i < swiperCoord.length; i++) {
2638                    var point = swiperCoord[i];
2639                    if (
2640                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
2641                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight
2642                    ) {
2643                        inView = true;
2644                    }
2645        
2646                }
2647                if (!inView) return;
2648            }
2649            if (isH()) {
2650                if (kc === 37 || kc === 39) {
2651                    if (e.preventDefault) e.preventDefault();
2652                    else e.returnValue = false;
2653                }
2654                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();
2655                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();
2656            }
2657            else {
2658                if (kc === 38 || kc === 40) {
2659                    if (e.preventDefault) e.preventDefault();
2660                    else e.returnValue = false;
2661                }
2662                if (kc === 40) s.slideNext();
2663                if (kc === 38) s.slidePrev();
2664            }
2665        }
2666        s.disableKeyboardControl = function () {
2667            $(document).off('keydown', handleKeyboard);
2668        };
2669        s.enableKeyboardControl = function () {
2670            $(document).on('keydown', handleKeyboard);
2671        };
2672        
2673
2674        /*=========================
2675          Mousewheel Control
2676          ===========================*/
2677        s.mousewheel = {
2678            event: false,
2679            lastScrollTime: (new window.Date()).getTime()
2680        };
2681        if (s.params.mousewheelControl) {
2682            try {
2683                new window.WheelEvent('wheel');
2684                s.mousewheel.event = 'wheel';
2685            } catch (e) {}
2686        
2687            if (!s.mousewheel.event && document.onmousewheel !== undefined) {
2688                s.mousewheel.event = 'mousewheel';
2689            }
2690            if (!s.mousewheel.event) {
2691                s.mousewheel.event = 'DOMMouseScroll';
2692            }
2693        }
2694        function handleMousewheel(e) {
2695            if (e.originalEvent) e = e.originalEvent; //jquery fix
2696            var we = s.mousewheel.event;
2697            var delta = 0;
2698            //Opera & IE
2699            if (e.detail) delta = -e.detail;
2700            //WebKits
2701            else if (we === 'mousewheel') {
2702                if (s.params.mousewheelForceToAxis) {
2703                    if (isH()) {
2704                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX;
2705                        else return;
2706                    }
2707                    else {
2708                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
2709                        else return;
2710                    }
2711                }
2712                else {
2713                    delta = e.wheelDelta;
2714                }
2715            }
2716            //Old FireFox
2717            else if (we === 'DOMMouseScroll') delta = -e.detail;
2718            //New FireFox
2719            else if (we === 'wheel') {
2720                if (s.params.mousewheelForceToAxis) {
2721                    if (isH()) {
2722                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX;
2723                        else return;
2724                    }
2725                    else {
2726                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
2727                        else return;
2728                    }
2729                }
2730                else {
2731                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
2732                }
2733            }
2734        
2735            if (s.params.mousewheelInvert) delta = -delta;
2736        
2737            if (!s.params.freeMode) {
2738                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {
2739                    if (delta < 0) {
2740                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();
2741                        else if (s.params.mousewheelReleaseOnEdges) return true;
2742                    }
2743                    else {
2744                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();
2745                        else if (s.params.mousewheelReleaseOnEdges) return true;
2746                    }
2747                }
2748                s.mousewheel.lastScrollTime = (new window.Date()).getTime();
2749        
2750            }
2751            else {
2752                //Freemode or scrollContainer:
2753        
2754                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;
2755        
2756                if (position > 0) position = 0;
2757                if (position < s.maxTranslate()) position = s.maxTranslate();
2758        
2759                s.setWrapperTransition(0);
2760                s.setWrapperTranslate(position);
2761                s.updateProgress();
2762                s.updateActiveIndex();
2763        
2764                if (s.params.freeModeSticky) {
2765                    clearTimeout(s.mousewheel.timeout);
2766                    s.mousewheel.timeout = setTimeout(function () {
2767                        s.slideReset();
2768                    }, 300);
2769                }
2770        
2771                // Return page scroll on edge positions
2772                if (position === 0 || position === s.maxTranslate()) return;
2773            }
2774            if (s.params.autoplay) s.stopAutoplay();
2775        
2776            if (e.preventDefault) e.preventDefault();
2777            else e.returnValue = false;
2778            return false;
2779        }
2780        s.disableMousewheelControl = function () {
2781            if (!s.mousewheel.event) return false;
2782            s.container.off(s.mousewheel.event, handleMousewheel);
2783            return true;
2784        };
2785        
2786        s.enableMousewheelControl = function () {
2787            if (!s.mousewheel.event) return false;
2788            s.container.on(s.mousewheel.event, handleMousewheel);
2789            return true;
2790        };
2791
2792        /*=========================
2793          Parallax
2794          ===========================*/
2795        function setParallaxTransform(el, progress) {
2796            el = $(el);
2797            var p, pX, pY;
2798            
2799            p = el.attr('data-swiper-parallax') || '0';
2800            pX = el.attr('data-swiper-parallax-x');
2801            pY = el.attr('data-swiper-parallax-y');
2802            if (pX || pY) {
2803                pX = pX || '0';
2804                pY = pY || '0';
2805            }
2806            else {
2807                if (isH()) {
2808                    pX = p;
2809                    pY = '0';
2810                }
2811                else {
2812                    pY = p;
2813                    pX = '0';
2814                }
2815            }
2816            if ((pX).indexOf('%') >= 0) {
2817                pX = parseInt(pX, 10) * progress + '%';
2818            }
2819            else {
2820                pX = pX * progress + 'px' ;
2821            }
2822            if ((pY).indexOf('%') >= 0) {
2823                pY = parseInt(pY, 10) * progress + '%';
2824            }
2825            else {
2826                pY = pY * progress + 'px' ;
2827            }
2828            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
2829        }   
2830        s.parallax = {
2831            setTranslate: function () {
2832                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
2833                    setParallaxTransform(this, s.progress);
2834                    
2835                });
2836                s.slides.each(function () {
2837                    var slide = $(this);
2838                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
2839                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);
2840                        setParallaxTransform(this, progress);
2841                    });
2842                });
2843            },
2844            setTransition: function (duration) {
2845                if (typeof duration === 'undefined') duration = s.params.speed;
2846                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
2847                    var el = $(this);
2848                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
2849                    if (duration === 0) parallaxDuration = 0;
2850                    el.transition(parallaxDuration);
2851                });
2852            }
2853        };
2854        
2855
2856        /*=========================
2857          Plugins API. Collect all and init all plugins
2858          ===========================*/
2859        s._plugins = [];
2860        for (var plugin in s.plugins) {
2861            var p = s.plugins[plugin](s, s.params[plugin]);
2862            if (p) s._plugins.push(p);
2863        }
2864        // Method to call all plugins event/method
2865        s.callPlugins = function (eventName) {
2866            for (var i = 0; i < s._plugins.length; i++) {
2867                if (eventName in s._plugins[i]) {
2868                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2869                }
2870            }
2871        };
2872
2873        /*=========================
2874          Events/Callbacks/Plugins Emitter
2875          ===========================*/
2876        function normalizeEventName (eventName) {
2877            if (eventName.indexOf('on') !== 0) {
2878                if (eventName[0] !== eventName[0].toUpperCase()) {
2879                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
2880                }
2881                else {
2882                    eventName = 'on' + eventName;
2883                }
2884            }
2885            return eventName;
2886        }
2887        s.emitterEventListeners = {
2888        
2889        };
2890        s.emit = function (eventName) {
2891            // Trigger callbacks
2892            if (s.params[eventName]) {
2893                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2894            }
2895            var i;
2896            // Trigger events
2897            if (s.emitterEventListeners[eventName]) {
2898                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
2899                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2900                }
2901            }
2902            // Trigger plugins
2903            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2904        };
2905        s.on = function (eventName, handler) {
2906            eventName = normalizeEventName(eventName);
2907            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
2908            s.emitterEventListeners[eventName].push(handler);
2909            return s;
2910        };
2911        s.off = function (eventName, handler) {
2912            var i;
2913            eventName = normalizeEventName(eventName);
2914            if (typeof handler === 'undefined') {
2915                // Remove all handlers for such event
2916                s.emitterEventListeners[eventName] = [];
2917                return s;
2918            }
2919            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
2920            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
2921                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
2922            }
2923            return s;
2924        };
2925        s.once = function (eventName, handler) {
2926            eventName = normalizeEventName(eventName);
2927            var _handler = function () {
2928                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
2929                s.off(eventName, _handler);
2930            };
2931            s.on(eventName, _handler);
2932            return s;
2933        };
2934
2935        // Accessibility tools
2936        s.a11y = {
2937            makeFocusable: function ($el) {
2938                $el.attr('tabIndex', '0');
2939                return $el;
2940            },
2941            addRole: function ($el, role) {
2942                $el.attr('role', role);
2943                return $el;
2944            },
2945        
2946            addLabel: function ($el, label) {
2947                $el.attr('aria-label', label);
2948                return $el;
2949            },
2950        
2951            disable: function ($el) {
2952                $el.attr('aria-disabled', true);
2953                return $el;
2954            },
2955        
2956            enable: function ($el) {
2957                $el.attr('aria-disabled', false);
2958                return $el;
2959            },
2960        
2961            onEnterKey: function (event) {
2962                if (event.keyCode !== 13) return;
2963                if ($(event.target).is(s.params.nextButton)) {
2964                    s.onClickNext(event);
2965                    if (s.isEnd) {
2966                        s.a11y.notify(s.params.lastSlideMessage);
2967                    }
2968                    else {
2969                        s.a11y.notify(s.params.nextSlideMessage);
2970                    }
2971                }
2972                else if ($(event.target).is(s.params.prevButton)) {
2973                    s.onClickPrev(event);
2974                    if (s.isBeginning) {
2975                        s.a11y.notify(s.params.firstSlideMessage);
2976                    }
2977                    else {
2978                        s.a11y.notify(s.params.prevSlideMessage);
2979                    }
2980                }
2981                if ($(event.target).is('.' + s.params.bulletClass)) {
2982                    $(event.target)[0].click();
2983                }
2984            },
2985        
2986            liveRegion: $('<span class="swiper-notification" aria-l
2986ive="assertive" aria-atomic="true"></span>'),
2987        
2988            notify: function (message) {
2989                var notification = s.a11y.liveRegion;
2990                if (notification.length === 0) return;
2991                notification.html('');
2992                notification.html(message);
2993            },
2994            init: function () {
2995                // Setup accessibility
2996                if (s.params.nextButton) {
2997                    var nextButton = $(s.params.nextButton);
2998                    s.a11y.makeFocusable(nextButton);
2999                    s.a11y.addRole(nextButton, 'button');
3000                    s.a11y.addLabel(nextButton, s.params.nextSlideMessage);
3001                }
3002                if (s.params.prevButton) {
3003                    var prevButton = $(s.params.prevButton);
3004                    s.a11y.makeFocusable(prevButton);
3005                    s.a11y.addRole(prevButton, 'button');
3006                    s.a11y.addLabel(prevButton, s.params.prevSlideMessage);
3007                }
3008        
3009                $(s.container).append(s.a11y.liveRegion);
3010            },
3011            initPagination: function () {
3012                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {
3013                    s.bullets.each(function () {
3014                        var bullet = $(this);
3015                        s.a11y.makeFocusable(bullet);
3016                        s.a11y.addRole(bullet, 'button');
3017                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));
3018                    });
3019                }
3020            },
3021            destroy: function () {
3022                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
3023            }
3024        };
3025        
3026
3027        /*=========================
3028          Init/Destroy
3029          ===========================*/
3030        s.init = function () {
3031            if (s.params.loop) s.createLoop();
3032            s.updateContainerSize();
3033            s.updateSlidesSize();
3034            s.updatePagination();
3035            if (s.params.scrollbar && s.scrollbar) {
3036                s.scrollbar.set();
3037            }
3038            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
3039                if (!s.params.loop) s.updateProgress();
3040                s.effects[s.params.effect].setTranslate();
3041            }
3042            if (s.params.loop) {
3043                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
3044            }
3045            else {
3046                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
3047                if (s.params.initialSlide === 0) {
3048                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();
3049                    if (s.lazy && s.params.lazyLoading) {
3050                        s.lazy.load();
3051                        s.lazy.initialImageLoaded = true;
3052                    }
3053                }
3054            }
3055            s.attachEvents();
3056            if (s.params.observer && s.support.observer) {
3057                s.initObservers();
3058            }
3059            if (s.params.preloadImages && !s.params.lazyLoading) {
3060                s.preloadImages();
3061            }
3062            if (s.params.autoplay) {
3063                s.startAutoplay();
3064            }
3065            if (s.params.keyboardControl) {
3066                if (s.enableKeyboardControl) s.enableKeyboardControl();
3067            }
3068            if (s.params.mousewheelControl) {
3069                if (s.enableMousewheelControl) s.enableMousewheelControl();
3070            }
3071            if (s.params.hashnav) {
3072                if (s.hashnav) s.hashnav.init();
3073            }
3074            if (s.params.a11y && s.a11y) s.a11y.init();
3075            s.emit('onInit', s);
3076        };
3077        
3078        // Cleanup dynamic styles
3079        s.cleanupStyles = function () {
3080            // Container
3081            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');
3082        
3083            // Wrapper
3084            s.wrapper.removeAttr('style');
3085        
3086            // Slides
3087            if (s.slides && s.slides.length) {
3088                s.slides
3089                    .removeClass([
3090                      s.params.slideVisibleClass,
3091                      s.params.slideActiveClass,
3092                      s.params.slideNextClass,
3093                      s.params.slidePrevClass
3094                    ].join(' '))
3095                    .removeAttr('style')
3096                    .removeAttr('data-swiper-column')
3097                    .removeAttr('data-swiper-row');
3098            }
3099        
3100            // Pagination/Bullets
3101            if (s.paginationContainer && s.paginationContainer.length) {
3102                s.paginationContainer.removeClass(s.params.paginationHiddenClass);
3103            }
3104            if (s.bullets && s.bullets.length) {
3105                s.bullets.removeClass(s.params.bulletActiveClass);
3106            }
3107        
3108            // Buttons
3109            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
3110            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
3111        
3112            // Scrollbar
3113            if (s.params.scrollbar && s.scrollbar) {
3114                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');
3115                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');
3116            }
3117        };
3118        
3119        // Destroy
3120        s.destroy = function (deleteInstance, cleanupStyles) {
3121            // Detach evebts
3122            s.detachEvents();
3123            // Stop autoplay
3124            s.stopAutoplay();
3125            // Destroy loop
3126            if (s.params.loop) {
3127                s.destroyLoop();
3128            }
3129            // Cleanup styles
3130            if (cleanupStyles) {
3131                s.cleanupStyles();
3132            }
3133            // Disconnect observer
3134            s.disconnectObservers();
3135            // Disable keyboard/mousewheel
3136            if (s.params.keyboardControl) {
3137                if (s.disableKeyboardControl) s.disableKeyboardControl();
3138            }
3139            if (s.params.mousewheelControl) {
3140                if (s.disableMousewheelControl) s.disableMousewheelControl();
3141            }
3142            // Disable a11y
3143            if (s.params.a11y && s.a11y) s.a11y.destroy();
3144            // Destroy callback
3145            s.emit('onDestroy');
3146            // Delete instance
3147            if (deleteInstance !== false) s = null;
3148        };
3149        
3150        s.init();
3151        
3152
3153    
3154        // Return swiper instance
3155        return s;
3156    };
3157    
3158
3159    /*==================================================
3160        Prototype
3161    ====================================================*/
3162    Swiper.prototype = {
3163        isSafari: (function () {
3164            var ua = navigator.userAgent.toLowerCase();
3165            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
3166        })(),
3167        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),
3168        isArray: function (arr) {
3169            return Object.prototype.toString.apply(arr) === '[object Array]';
3170        },
3171        /*==================================================
3172        Browser
3173        ====================================================*/
3174        browser: {
3175            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
3176            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
3177        },
3178        /*==================================================
3179        Devices
3180        ====================================================*/
3181        device: (function () {
3182            var ua = navigator.userAgent;
3183            var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
3184            var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
3185            var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
3186            var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
3187            return {
3188                ios: ipad || iphone || ipod,
3189                android: android
3190            };
3191        })(),
3192        /*==================================================
3193        Feature Detection
3194        ====================================================*/
3195        support: {
3196            touch : (window.Modernizr && Modernizr.touch === true) || (function () {
3197                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
3198            })(),
3199    
3200            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
3201                var div = document.createElement('div').style;
3202                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
3203            })(),
3204    
3205            flexbox: (function () {
3206                var div = document.createElement('div').style;
3207                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
3208                for (var i = 0; i < styles.length; i++) {
3209                    if (styles[i] in div) return true;
3210                }
3211            })(),
3212    
3213            observer: (function () {
3214                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
3215            })()
3216        },
3217        /*==================================================
3218        Plugins
3219        ====================================================*/
3220        plugins: {}
3221    };
3222    
3223
3224    /*===========================
3225    Dom7 Library
3226    ===========================*/
3227    var Dom7 = (function () {
3228        var Dom7 = function (arr) {
3229            var _this = this, i = 0;
3230            // Create array-like object
3231            for (i = 0; i < arr.length; i++) {
3232                _this[i] = arr[i];
3233            }
3234            _this.length = arr.length;
3235            // Return collection with methods
3236            return this;
3237        };
3238        var $ = function (selector, context) {
3239            var arr = [], i = 0;
3240            if (selector && !context) {
3241                if (selector instanceof Dom7) {
3242                    return selector;
3243                }
3244            }
3245            if (selector) {
3246                // String
3247                if (typeof selector === 'string') {
3248                    var els, tempParent, html = selector.trim();
3249                    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
3250                        var toCreate = 'div';
3251                        if (html.indexOf('<li') === 0) toCreate = 'ul';
3252                        if (html.indexOf('<tr') === 0) toCreate = 'tbody';
3253                        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
3254                        if (html.indexOf('<tbody') === 0) toCreate = 'table';
3255                        if (html.indexOf('<option') === 0) toCreate = 'select';
3256                        tempParent = document.createElement(toCreate);
3257                        tempParent.innerHTML = selector;
3258                        for (i = 0; i < tempParent.childNodes.length; i++) {
3259                            arr.push(tempParent.childNodes[i]);
3260                        }
3261                    }
3262                    else {
3263                        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
3264                            // Pure ID selector
3265                            els = [document.getElementById(selector.split('#')[1])];
3266                        }
3267                        else {
3268                            // Other selectors
3269                            els = (context || document).querySelectorAll(selector);
3270                        }
3271                        for (i = 0; i < els.length; i++) {
3272                            if (els[i]) arr.push(els[i]);
3273                        }
3274                    }
3275                }
3276                // Node/element
3277                else if (selector.nodeType || selector === window || selector === document) {
3278                    arr.push(selector);
3279                }
3280                //Array of elements or instance of Dom
3281                else if (selector.length > 0 && selector[0].nodeType) {
3282                    for (i = 0; i < selector.length; i++) {
3283                        arr.push(selector[i]);
3284                    }
3285                }
3286            }
3287            return new Dom7(arr);
3288        };
3289        Dom7.prototype = {
3290            // Classes and attriutes
3291            addClass: function (className) {
3292                if (typeof className === 'undefined') {
3293                    return this;
3294                }
3295                var classes = className.split(' ');
3296                for (var i = 0; i < classes.length; i++) {
3297                    for (var j = 0; j < this.length; j++) {
3298                        this[j].classList.add(classes[i]);
3299                    }
3300                }
3301                return this;
3302            },
3303            removeClass: function (className) {
3304                var classes = className.split(' ');
3305                for (var i = 0; i < classes.length; i++) {
3306                    for (var j = 0; j < this.length; j++) {
3307                        this[j].classList.remove(classes[i]);
3308                    }
3309                }
3310                return this;
3311            },
3312            hasClass: function (className) {
3313                if (!this[0]) return false;
3314                else return this[0].classList.contains(className);
3315            },
3316            toggleClass: function (className) {
3317                var classes = className.split(' ');
3318                for (var i = 0; i < classes.length; i++) {
3319                    for (var j = 0; j < this.length; j++) {
3320                        this[j].classList.toggle(classes[i]);
3321                    }
3322                }
3323                return this;
3324            },
3325            attr: function (attrs, value) {
3326                if (arguments.length === 1 && typeof attrs === 'string') {
3327                    // Get attr
3328                    if (this[0]) return this[0].getAttribute(attrs);
3329                    else return undefined;
3330                }
3331                else {
3332                    // Set attrs
3333                    for (var i = 0; i < this.length; i++) {
3334                        if (arguments.length === 2) {
3335                            // String
3336                            this[i].setAttribute(attrs, value);
3337                        }
3338                        else {
3339                            // Object
3340                            for (var attrName in attrs) {
3341                                this[i][attrName] = attrs[attrName];
3342                                this[i].setAttribute(attrName, attrs[attrName]);
3343                            }
3344                        }
3345                    }
3346                    return this;
3347                }
3348            },
3349            removeAttr: function (attr) {
3350                for (var i = 0; i < this.length; i++) {
3351                    this[i].removeAttribute(attr);
3352                }
3353                return this;
3354            },
3355            data: function (key, value) {
3356                if (typeof value === 'undefined') {
3357                    // Get value
3358                    if (this[0]) {
3359                        var dataKey = this[0].getAttribute('data-' + key);
3360                        if (dataKey) return dataKey;
3361                        else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];
3362                        else return undefined;
3363                    }
3364                    else return undefined;
3365                }
3366                else {
3367                    // Set value
3368                    for (var i = 0; i < this.length; i++) {
3369                        var el = this[i];
3370                        if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
3371                        el.dom7ElementDataStorage[key] = value;
3372                    }
3373                    return this;
3374                }
3375            },
3376            // Transforms
3377            transform : function (transform) {
3378                for (var i = 0; i < this.length; i++) {
3379                    var elStyle = this[i].style;
3380                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
3381                }
3382                return this;
3383            },
3384            transition: function (duration) {
3385                if (typeof duration !== 'string') {
3386                    duration = duration + 'ms';
3387                }
3388                for (var i = 0; i < this.length; i++) {
3389                    var elStyle = this[i].style;
3390                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
3391                }
3392                return this;
3393            },
3394            //Events
3395            on: function (eventName, targetSelector, listener, capture) {
3396                function handleLiveEvent(e) {
3397                    var target = e.target;
3398                    if ($(target).is(targetSelector)) listener.call(target, e);
3399                    else {
3400                        var parents = $(target).parents();
3401                        for (var k = 0; k < parents.length; k++) {
3402                            if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);
3403                        }
3404                    }
3405                }
3406                var events = eventName.split(' ');
3407                var i, j;
3408                for (i = 0; i < this.length; i++) {
3409                    if (typeof targetSelector === 'function' || targetSelector === false) {
3410                        // Usual events
3411                        if (typeof targetSelector === 'function') {
3412                            listener = arguments[1];
3413                            capture = arguments[2] || false;
3414                        }
3415                        for (j = 0; j < events.length; j++) {
3416                            this[i].addEventListener(events[j], listener, capture);
3417                        }
3418                    }
3419                    else {
3420                        //Live events
3421                        for (j = 0; j < events.length; j++) {
3422                            if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];
3423                            this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});
3424                            this[i].addEventListener(events[j], handleLiveEvent, capture);
3425                        }
3426                    }
3427                }
3428    
3429                return this;
3430            },
3431            off: function (eventName, targetSelector, listener, capture) {
3432                var events = eventName.split(' ');
3433                for (var i = 0; i < events.length; i++) {
3434                    for (var j = 0; j < this.length; j++) {
3435                        if (typeof targetSelector === 'function' || targetSelector === false) {
3436                            // Usual events
3437                            if (typeof targetSelector === 'function') {
3438                                listener = arguments[1];
3439                                capture = arguments[2] || false;
3440                            }
3441                            this[j].removeEventListener(events[i], listener, capture);
3442                        }
3443                        else {
3444                            // Live event
3445                            if (this[j].dom7LiveListeners) {
3446                                for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {
3447                                    if (this[j].dom7LiveListeners[k].listener === listener) {
3448                                        this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);
3449                                    }
3450                                }
3451                            }
3452                        }
3453                    }
3454                }
3455                return this;
3456            },
3457            once: function (eventName, targetSelector, listener, capture) {
3458                var dom = this;
3459                if (typeof targetSelector === 'function') {
3460                    targetSelector = false;
3461                    listener = arguments[1];
3462                    capture = arguments[2];
3463                }
3464                function proxy(e) {
3465                    listener(e);
3466                    dom.off(eventName, targetSelector, proxy, capture);
3467                }
3468                dom.on(eventName, targetSelector, proxy, capture);
3469            },
3470            trigger: function (eventName, eventData) {
3471                for (var i = 0; i < this.length; i++) {
3472                    var evt;
3473                    try {
3474                        evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});
3475                    }
3476                    catch (e) {
3477                        evt = document.createEvent('Event');
3478                        evt.initEvent(eventName, true, true);
3479                        evt.detail = eventData;
3480                    }
3481                    this[i].dispatchEvent(evt);
3482                }
3483                return this;
3484            },
3485            transitionEnd: function (callback) {
3486                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
3487                    i, j, dom = this;
3488                function fireCallBack(e) {
3489                    /*jshint validthis:true */
3490                    if (e.target !== this) return;
3491                    callback.call(this, e);
3492                    for (i = 0; i < events.length; i++) {
3493                        dom.off(events[i], fireCallBack);
3494                    }
3495                }
3496                if (callback) {
3497                    for (i = 0; i < events.length; i++) {
3498                        dom.on(events[i], fireCallBack);
3499                    }
3500                }
3501                return this;
3502            },
3503            // Sizing/Styles
3504            width: function () {
3505                if (this[0] === window) {
3506                    return window.innerWidth;
3507                }
3508                else {
3509                    if (this.length > 0) {
3510                        return parseFloat(this.css('width'));
3511                    }
3512                    else {
3513                        return null;
3514                    }
3515                }
3516            },
3517            outerWidth: function (includeMargins) {
3518                if (this.length > 0) {
3519                    if (includeMargins)
3520                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));
3521                    else
3522                        return this[0].offsetWidth;
3523                }
3524                else return null;
3525            },
3526            height: function () {
3527                if (this[0] === window) {
3528                    return window.innerHeight;
3529                }
3530                else {
3531                    if (this.length > 0) {
3532                        return parseFloat(this.css('height'));
3533                    }
3534                    else {
3535                        return null;
3536                    }
3537                }
3538            },
3539            outerHeight: function (includeMargins) {
3540                if (this.length > 0) {
3541                    if (includeMargins)
3542                        return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));
3543                    else
3544                        return this[0].offsetHeight;
3545                }
3546                else return null;
3547            },
3548            offset: function () {
3549                if (this.length > 0) {
3550                    var el = this[0];
3551                    var box = el.getBoundingClientRect();
3552                    var body = document.body;
3553                    var clientTop  = el.clientTop  || body.clientTop  || 0;
3554                    var clientLeft = el.clientLeft || body.clientLeft || 0;
3555                    var scrollTop  = window.pageYOffset || el.scrollTop;
3556                    var scrollLeft = window.pageXOffset || el.scrollLeft;
3557                    return {
3558                        top: box.top  + scrollTop  - clientTop,
3559                        left: box.left + scrollLeft - clientLeft
3560                    };
3561                }
3562                else {
3563                    return null;
3564                }
3565            },
3566            css: function (props, value) {
3567                var i;
3568                if (arguments.length === 1) {
3569                    if (typeof props === 'string') {
3570                        if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
3571                    }
3572                    else {
3573                        for (i = 0; i < this.length; i++) {
3574                            for (var prop in props) {
3575                                this[i].style[prop] = props[prop];
3576                            }
3577                        }
3578                        return this;
3579                    }
3580                }
3581                if (arguments.length === 2 && typeof props === 'string') {
3582                    for (i = 0; i < this.length; i++) {
3583                        this[i].style[props] = value;
3584                    }
3585                    return this;
3586                }
3587                return this;
3588            },
3589    
3590            //Dom manipulation
3591            each: function (callback) {
3592                for (var i = 0; i < this.length; i++) {
3593                    callback.call(this[i], i, this[i]);
3594                }
3595                return this;
3596            },
3597            html: function (html) {
3598                if (typeof html === 'undefined') {
3599                    return this[0] ? this[0].innerHTML : undefined;
3600                }
3601                else {
3602                    for (var i = 0; i < this.length; i++) {
3603                        this[i].innerHTML = html;
3604                    }
3605                    return this;
3606                }
3607            },
3608            is: function (selector) {
3609                if (!this[0]) return false;
3610                var compareWith, i;
3611                if (typeof selector === 'string') {
3612                    var el = this[0];
3613                    if (el === document) return selector === document;
3614                    if (el === window) return selector === window;
3615    
3616                    if (el.matches) return el.matches(selector);
3617                    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
3618                    else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);
3619                    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);
3620                    else {
3621                        compareWith = $(selector);
3622                        for (i = 0; i < compareWith.length; i++) {
3623                            if (compareWith[i] === this[0]) return true;
3624                        }
3625                        return false;
3626                    }
3627                }
3628                else if (selector === document) return this[0] === document;
3629                else if (selector === window) return this[0] === window;
3630                else {
3631                    if (selector.nodeType || selector instanceof Dom7) {
3632                        compareWith = selector.nodeType ? [selector] : selector;
3633                        for (i = 0; i < compareWith.length; i++) {
3634                            if (compareWith[i] === this[0]) return true;
3635                        }
3636                        return false;
3637                    }
3638                    return false;
3639                }
3640    
3641            },
3642            index: function () {
3643                if (this[0]) {
3644                    var child = this[0];
3645                    var i = 0;
3646                    while ((child = child.previousSibling) !== null) {
3647                        if (child.nodeType === 1) i++;
3648                    }
3649                    return i;
3650                }
3651                else return undefined;
3652            },
3653            eq: function (index) {
3654                if (typeof index === 'undefined') return this;
3655                var length = this.length;
3656                var returnIndex;
3657                if (index > length - 1) {
3658                    return new Dom7([]);
3659                }
3660                if (index < 0) {
3661                    returnIndex = length + index;
3662                    if (returnIndex < 0) return new Dom7([]);
3663                    else return new Dom7([this[returnIndex]]);
3664                }
3665                return new Dom7([this[index]]);
3666            },
3667            append: function (newChild) {
3668                var i, j;
3669                for (i = 0; i < this.length; i++) {
3670                    if (typeof newChild === 'string') {
3671                        var tempDiv = document.createElement('div');
3672                        tempDiv.innerHTML = newChild;
3673                        while (tempDiv.firstChild) {
3674                            this[i].appendChild(tempDiv.firstChild);
3675                        }
3676                    }
3677                    else if (newChild instanceof Dom7) {
3678                        for (j = 0; j < newChild.length; j++) {
3679                            this[i].appendChild(newChild[j]);
3680                        }
3681                    }
3682                    else {
3683                        this[i].appendChild(newChild);
3684                    }
3685                }
3686                return this;
3687            },
3688            prepend: function (newChild) {
3689                var i, j;
3690                for (i = 0; i < this.length; i++) {
3691                    if (typeof newChild === 'string') {
3692                        var tempDiv = document.createElement('div');
3693                        tempDiv.innerHTML = newChild;
3694                        for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {
3695                            this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
3696                        }
3697                        // this[i].insertAdjacentHTML('afterbegin', newChild);
3698                    }
3699                    else if (newChild instanceof Dom7) {
3700                        for (j = 0; j < newChild.length; j++) {
3701                            this[i].insertBefore(newChild[j], this[i].childNodes[0]);
3702                        }
3703                    }
3704                    else {
3705                        this[i].insertBefore(newChild, this[i].childNodes[0]);
3706                    }
3707                }
3708                return this;
3709            },
3710            insertBefore: function (selector) {
3711                var before = $(selector);
3712                for (var i = 0; i < this.length; i++) {
3713                    if (before.length === 1) {
3714                        before[0].parentNode.insertBefore(this[i], before[0]);
3715                    }
3716                    else if (before.length > 1) {
3717                        for (var j = 0; j < before.length; j++) {
3718                            before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
3719                        }
3720                    }
3721                }
3722            },
3723            insertAfter: function (selector) {
3724                var after = $(selector);
3725                for (var i = 0; i < this.length; i++) {
3726                    if (after.length === 1) {
3727                        after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
3728                    }
3729                    else if (after.length > 1) {
3730                        for (var j = 0; j < after.length; j++) {
3731                            after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
3732                        }
3733                    }
3734                }
3735            },
3736            next: function (selector) {
3737                if (this.length > 0) {
3738                    if (selector) {
3739                        if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);
3740                        else return new Dom7([]);
3741                    }
3742                    else {
3743                        if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);
3744                        else return new Dom7([]);
3745                    }
3746                }
3747                else return new Dom7([]);
3748            },
3749            nextAll: function (selector) {
3750                var nextEls = [];
3751                var el = this[0];
3752                if (!el) return new Dom7([]);
3753                while (el.nextElementSibling) {
3754                    var next = el.nextElementSibling;
3755                    if (selector) {
3756                        if($(next).is(selector)) nextEls.push(next);
3757                    }
3758                    else nextEls.push(next);
3759                    el = next;
3760                }
3761                return new Dom7(nextEls);
3762            },
3763            prev: function (selector) {
3764                if (this.length > 0) {
3765                    if (selector) {
3766                        if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);
3767                        else return new Dom7([]);
3768                    }
3769                    else {
3770                        if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);
3771                        else return new Dom7([]);
3772                    }
3773                }
3774                else return new Dom7([]);
3775            },
3776            prevAll: function (selector) {
3777                var prevEls = [];
3778                var el = this[0];
3779                if (!el) return new Dom7([]);
3780                while (el.previousElementSibling) {
3781                    var prev = el.previousElementSibling;
3782                    if (selector) {
3783                        if($(prev).is(selector)) prevEls.push(prev);
3784                    }
3785                    else prevEls.push(prev);
3786                    el = prev;
3787                }
3788                return new Dom7(prevEls);
3789            },
3790            parent: function (selector) {
3791                var parents = [];
3792                for (var i = 0; i < this.length; i++) {
3793                    if (selector) {
3794                        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
3795                    }
3796                    else {
3797                        parents.push(this[i].parentNode);
3798                    }
3799                }
3800                return $($.unique(parents));
3801            },
3802            parents: function (selector) {
3803                var parents = [];
3804                for (var i = 0; i < this.length; i++) {
3805                    var parent = this[i].parentNode;
3806                    while (parent) {
3807                        if (selector) {
3808                            if ($(parent).is(selector)) parents.push(parent);
3809                        }
3810                        else {
3811                            parents.push(parent);
3812                        }
3813                        parent = parent.parentNode;
3814                    }
3815                }
3816                return $($.unique(parents));
3817            },
3818            find : function (selector) {
3819                var foundElements = [];
3820                for (var i = 0; i < this.length; i++) {
3821                    var found = this[i].querySelectorAll(selector);
3822                    for (var j = 0; j < found.length; j++) {
3823                        foundElements.push(found[j]);
3824                    }
3825                }
3826                return new Dom7(foundElements);
3827            },
3828            children: function (selector) {
3829                var children = [];
3830                for (var i = 0; i < this.length; i++) {
3831                    var childNodes = this[i].childNodes;
3832    
3833                    for (var j = 0; j < childNodes.length; j++) {
3834                        if (!selector) {
3835                            if (childNodes[j].nodeType === 1) children.push(childNodes[j]);
3836                        }
3837                        else {
3838                            if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);
3839                        }
3840                    }
3841                }
3842                return new Dom7($.unique(children));
3843            },
3844            remove: function () {
3845                for (var i = 0; i < this.length; i++) {
3846                    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
3847                }
3848                return this;
3849            },
3850            add: function () {
3851                var dom = this;
3852                var i, j;
3853                for (i = 0; i < arguments.length; i++) {
3854                    var toAdd = $(arguments[i]);
3855                    for (j = 0; j < toAdd.length; j++) {
3856                        dom[dom.length] = toAdd[j];
3857                        dom.length++;
3858                    }
3859                }
3860                return dom;
3861            }
3862        };
3863        $.fn = Dom7.prototype;
3864        $.unique = function (arr) {
3865            var unique = [];
3866            for (var i = 0; i < arr.length; i++) {
3867                if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);
3868            }
3869            return unique;
3870        };
3871    
3872        return $;
3873    })();
3874    
3875
3876    /*===========================
3877     Get Dom libraries
3878     ===========================*/
3879    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];
3880    for (var i = 0; i < swiperDomPlugins.length; i++) {
3881    	if (window[swiperDomPlugins[i]]) {
3882    		addLibraryPlugin(window[swiperDomPlugins[i]]);
3883    	}
3884    }
3885    // Required DOM Plugins
3886    var domLib;
3887    if (typeof Dom7 === 'undefined') {
3888    	domLib = window.Dom7 || window.Zepto || window.jQuery;
3889    }
3890    else {
3891    	domLib = Dom7;
3892    }
3893
3894    /*===========================
3895    Add .swiper plugin from Dom libraries
3896    ===========================*/
3897    function addLibraryPlugin(lib) {
3898        lib.fn.swiper = function (params) {
3899            var firstInstance;
3900            lib(this).each(function () {
3901                var s = new Swiper(this, params);
3902                if (!firstInstance) firstInstance = s;
3903            });
3904            return firstInstance;
3905        };
3906    }
3907    
3908    if (domLib) {
3909        if (!('transitionEnd' in domLib.fn)) {
3910            domLib.fn.transitionEnd = function (callback) {
3911                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
3912                    i, j, dom = this;
3913                function fireCallBack(e) {
3914                    /*jshint validthis:true */
3915                    if (e.target !== this) return;
3916                    callback.call(this, e);
3917                    for (i = 0; i < events.length; i++) {
3918                        dom.off(events[i], fireCallBack);
3919                    }
3920                }
3921                if (callback) {
3922                    for (i = 0; i < events.length; i++) {
3923                        dom.on(events[i], fireCallBack);
3924                    }
3925                }
3926                return this;
3927            };
3928        }
3929        if (!('transform' in domLib.fn)) {
3930            domLib.fn.transform = function (transform) {
3931                for (var i = 0; i < this.length; i++) {
3932                    var elStyle = this[i].style;
3933                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
3934                }
3935                return this;
3936            };
3937        }
3938        if (!('transition' in domLib.fn)) {
3939            domLib.fn.transition = function (duration) {
3940                if (typeof duration !== 'string') {
3941                    duration = duration + 'ms';
3942                }
3943                for (var i = 0; i < this.length; i++) {
3944                    var elStyle = this[i].style;
3945                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
3946                }
3947                return this;
3948            };
3949        }
3950    }
3951
3952    window.Swiper = Swiper;
3953})();
3954/*===========================
3955Swiper AMD Export
3956===========================*/
3957if (typeof(module) !== 'undefined')
3958{
3959    module.exports = window.Swiper;
3960}
3961else if (typeof define === 'function' && define.amd) {
3962    define([], function () {
3963        'use strict';
3964        return window.Swiper;
3965    });
3966}

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.