PageSourceSearch

https://www.outdoors.com.cn/Public/Home/js/idangerous.swiper.js

js outdoors.com.cn collected 2026-10-04 11:52:06 UTC 113,619 bytes, 2,878 lines download raw bytes

1var Swiper = function (selector, params) {
2    'use strict';
3
4    /*=========================
5      A little bit dirty but required part for IE8 and old FF support
6      ===========================*/
7    if (!document.body.outerHTML && document.body.__defineGetter__) {
8        if (HTMLElement) {
9            var element = HTMLElement.prototype;
10            if (element.__defineGetter__) {
11                element.__defineGetter__('outerHTML', function () { return new XMLSerializer().serializeToString(this); });
12            }
13        }
14    }
15
16    if (!window.getComputedStyle) {
17        window.getComputedStyle = function (el, pseudo) {
18            this.el = el;
19            this.getPropertyValue = function (prop) {
20                var re = /(\-([a-z]){1})/g;
21                if (prop === 'float') prop = 'styleFloat';
22                if (re.test(prop)) {
23                    prop = prop.replace(re, function () {
24                        return arguments[2].toUpperCase();
25                    });
26                }
27                return el.currentStyle[prop] ? el.currentStyle[prop] : null;
28            };
29            return this;
30        };
31    }
32    if (!Array.prototype.indexOf) {
33        Array.prototype.indexOf = function (obj, start) {
34            for (var i = (start || 0), j = this.length; i < j; i++) {
35                if (this[i] === obj) { return i; }
36            }
37            return -1;
38        };
39    }
40    if (!document.querySelectorAll) {
41        if (!window.jQuery) return;
42    }
43    function $$(selector, context) {
44        if (document.querySelectorAll)
45            return (context || document).querySelectorAll(selector);
46        else
47            return jQuery(selector, context);
48    }
49
50    /*=========================
51      Check for correct selector
52      ===========================*/
53    if (typeof selector === 'undefined') return;
54
55    if (!(selector.nodeType)) {
56        if ($$(selector).length === 0) return;
57    }
58
59     /*=========================
60      _this
61      ===========================*/
62    var _this = this;
63
64     /*=========================
65      Default Flags and vars
66      ===========================*/
67    _this.touches = {
68        start: 0,
69        startX: 0,
70        startY: 0,
71        current: 0,
72        currentX: 0,
73        currentY: 0,
74        diff: 0,
75        abs: 0
76    };
77    _this.positions = {
78        start: 0,
79        abs: 0,
80        diff: 0,
81        current: 0
82    };
83    _this.times = {
84        start: 0,
85        end: 0
86    };
87
88    _this.id = (new Date()).getTime();
89    _this.container = (selector.nodeType) ? selector : $$(selector)[0];
90    _this.isTouched = false;
91    _this.isMoved = false;
92    _this.activeIndex = 0;
93    _this.centerIndex = 0;
94    _this.activeLoaderIndex = 0;
95    _this.activeLoopIndex = 0;
96    _this.previousIndex = null;
97    _this.velocity = 0;
98    _this.snapGrid = [];
99    _this.slidesGrid = [];
100    _this.imagesToLoad = [];
101    _this.imagesLoaded = 0;
102    _this.wrapperLeft = 0;
103    _this.wrapperRight = 0;
104    _this.wrapperTop = 0;
105    _this.wrapperBottom = 0;
106    _this.isAndroid = navigator.userAgent.toLowerCase().indexOf('android') >= 0;
107    var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize;
108
109    /*=========================
110      Default Parameters
111      ===========================*/
112    var defaults = {
113        eventTarget: 'wrapper', // or 'container'
114        mode : 'horizontal', // or 'vertical'
115        touchRatio : 1,
116        speed : 300,
117        freeMode : false,
118        freeModeFluid : false,
119        momentumRatio: 1,
120        momentumBounce: true,
121        momentumBounceRatio: 1,
122        slidesPerView : 1,
123        slidesPerGroup : 1,
124        slidesPerViewFit: true, //Fit to slide when spv "auto" and slides larger than container
125        simulateTouch : true,
126        followFinger : true,
127        shortSwipes : true,
128        longSwipesRatio: 0.5,
129        moveStartThreshold: false,
130        onlyExternal : false,
131        createPagination : true,
132        pagination : false,
133        paginationElement: 'span',
134        paginationClickable: false,
135        paginationAsRange: true,
136        resistance : true, // or false or 100%
137        scrollContainer : false,
138        preventLinks : true,
139        preventLinksPropagation: false,
140        noSwiping : false, // or class
141        noSwipingClass : 'swiper-no-swiping', //:)
142        initialSlide: 0,
143        keyboardControl: false,
144        mousewheelControl : false,
145        mousewheelControlForceToAxis : false,
146        useCSS3Transforms : true,
147        // Autoplay
148        autoplay: false,
149        autoplayDisableOnInteraction: true,
150        autoplayStopOnLast: false,
151        //Loop mode
152        loop: false,
153        loopAdditionalSlides: 0,
154        // Round length values
155        roundLengths: false,
156        //Auto Height
157        calculateHeight: false,
158        //Apply CSS for width and/or height
159        cssWidthAndHeight: false, // or true or 'width' or 'height'
160        //Images Preloader
161        updateOnImagesReady : true,
162        //Form elements
163        releaseFormElements : true,
164        //Watch for active slide, useful when use effects on different slide states
165        watchActiveIndex: false,
166        //Slides Visibility Fit
167        visibilityFullFit : false,
168        //Slides Offset
169        offsetPxBefore : 0,
170        offsetPxAfter : 0,
171        offsetSlidesBefore : 0,
172        offsetSlidesAfter : 0,
173        centeredSlides: false,
174        //Queue callbacks
175        queueStartCallbacks : false,
176        queueEndCallbacks : false,
177        //Auto Resize
178        autoResize : true,
179        resizeReInit : false,
180        //DOMAnimation
181        DOMAnimation : true,
182        //Slides Loader
183        loader: {
184            slides: [], //array with slides
185            slidesHTMLType: 'inner', // or 'outer'
186            surroundGroups: 1, //keep preloaded slides groups around view
187            logic: 'reload', //or 'change'
188            loadAllSlides: false
189        },
190        // One way swipes
191        swipeToPrev: true,
192        swipeToNext: true,
193        //Namespace
194        slideElement: 'div',
195        slideClass: 'swiper-slide',
196        slideActiveClass: 'swiper-slide-active',
197        slideVisibleClass: 'swiper-slide-visible',
198        slideDuplicateClass: 'swiper-slide-duplicate',
199        wrapperClass: 'swiper-wrapper',
200        paginationElementClass: 'swiper-pagination-switch',
201        paginationActiveClass: 'swiper-active-switch',
202        paginationVisibleClass: 'swiper-visible-switch'
203    };
204    params = params || {};
205    for (var prop in defaults) {
206        if (prop in params && typeof params[prop] === 'object') {
207            for (var subProp in defaults[prop]) {
208                if (! (subProp in params[prop])) {
209                    params[prop][subProp] = defaults[prop][subProp];
210                }
211            }
212        }
213        else if (! (prop in params)) {
214            params[prop] = defaults[prop];
215        }
216    }
217    _this.params = params;
218    if (params.scrollContainer) {
219        params.freeMode = true;
220        params.freeModeFluid = true;
221    }
222    if (params.loop) {
223        params.resistance = '100%';
224    }
225    var isH = params.mode === 'horizontal';
226
227    /*=========================
228      Define Touch Events
229      ===========================*/
230    var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
231    if (_this.browser.ie10) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
232    if (_this.browser.ie11) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
233
234    _this.touchEvents = {
235        touchStart : _this.support.touch || !params.simulateTouch  ? 'touchstart' : desktopEvents[0],
236        touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : desktopEvents[1],
237        touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : desktopEvents[2]
238    };
239
240    /*=========================
241      Wrapper
242      ===========================*/
243    for (var i = _this.container.childNodes.length - 1; i >= 0; i--) {
244        if (_this.container.childNodes[i].className) {
245            var _wrapperClasses = _this.container.childNodes[i].className.split(/\s+/);
246            for (var j = 0; j < _wrapperClasses.length; j++) {
247                if (_wrapperClasses[j] === params.wrapperClass) {
248                    wrapper = _this.container.childNodes[i];
249                }
250            }
251        }
252    }
253
254    _this.wrapper = wrapper;
255    /*=========================
256      Slide API
257      ===========================*/
258    _this._extendSwiperSlide = function  (el) {
259        el.append = function () {
260            if (params.loop) {
261                el.insertAfter(_this.slides.length - _this.loopedSlides);
262            }
263            else {
264                _this.wrapper.appendChild(el);
265                _this.reInit();
266            }
267
268            return el;
269        };
270        el.prepend = function () {
271            if (params.loop) {
272                _this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]);
273                _this.removeLoopedSlides();
274                _this.calcSlides();
275                _this.createLoop();
276            }
277            else {
278                _this.wrapper.insertBefore(el, _this.wrapper.firstChild);
279            }
280            _this.reInit();
281            return el;
282        };
283        el.insertAfter = function (index) {
284            if (typeof index === 'undefined') return false;
285            var beforeSlide;
286
287            if (params.loop) {
288                beforeSlide = _this.slides[index + 1 + _this.loopedSlides];
289                if (beforeSlide) {
290                    _this.wrapper.insertBefore(el, beforeSlide);
291                }
292                else {
293                    _this.wrapper.appendChild(el);
294                }
295                _this.removeLoopedSlides();
296                _this.calcSlides();
297                _this.createLoop();
298            }
299            else {
300                beforeSlide = _this.slides[index + 1];
301                _this.wrapper.insertBefore(el, beforeSlide);
302            }
303            _this.reInit();
304            return el;
305        };
306        el.clone = function () {
307            return _this._extendSwiperSlide(el.cloneNode(true));
308        };
309        el.remove = function () {
310            _this.wrapper.removeChild(el);
311            _this.reInit();
312        };
313        el.html = function (html) {
314            if (typeof html === 'undefined') {
315                return el.innerHTML;
316            }
317            else {
318                el.innerHTML = html;
319                return el;
320            }
321        };
322        el.index = function () {
323            var index;
324            for (var i = _this.slides.length - 1; i >= 0; i--) {
325                if (el === _this.slides[i]) index = i;
326            }
327            return index;
328        };
329        el.isActive = function () {
330            if (el.index() === _this.activeIndex) return true;
331            else return false;
332        };
333        if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage = {};
334        el.getData = function (name) {
335            return el.swiperSlideDataStorage[name];
336        };
337        el.setData = function (name, value) {
338            el.swiperSlideDataStorage[name] = value;
339            return el;
340        };
341        el.data = function (name, value) {
342            if (typeof value === 'undefined') {
343                return el.getAttribute('data-' + name);
344            }
345            else {
346                el.setAttribute('data-' + name, value);
347                return el;
348            }
349        };
350        el.getWidth = function (outer, round) {
351            return _this.h.getWidth(el, outer, round);
352        };
353        el.getHeight = function (outer, round) {
354            return _this.h.getHeight(el, outer, round);
355        };
356        el.getOffset = function () {
357            return _this.h.getOffset(el);
358        };
359        return el;
360    };
361
362    //Calculate information about number of slides
363    _this.calcSlides = function (forceCalcSlides) {
364        var oldNumber = _this.slides ? _this.slides.length : false;
365        _this.slides = [];
366        _this.displaySlides = [];
367        for (var i = 0; i < _this.wrapper.childNodes.length; i++) {
368            if (_this.wrapper.childNodes[i].className) {
369                var _className = _this.wrapper.childNodes[i].className;
370                var _slideClasses = _className.split(/\s+/);
371                for (var j = 0; j < _slideClasses.length; j++) {
372                    if (_slideClasses[j] === params.slideClass) {
373                        _this.slides.push(_this.wrapper.childNodes[i]);
374                    }
375                }
376            }
377        }
378        for (i = _this.slides.length - 1; i >= 0; i--) {
379            _this._extendSwiperSlide(_this.slides[i]);
380        }
381        if (oldNumber === false) return;
382        if (oldNumber !== _this.slides.length || forceCalcSlides) {
383
384            // Number of slides has been changed
385            removeSlideEvents();
386            addSlideEvents();
387            _this.updateActiveSlide();
388            if (_this.params.pagination) _this.createPagination();
389            _this.callPlugins('numberOfSlidesChanged');
390        }
391    };
392
393    //Create Slide
394    _this.createSlide = function (html, slideClassList, el) {
395        slideClassList = slideClassList || _this.params.slideClass;
396        el = el || params.slideElement;
397        var newSlide = document.createElement(el);
398        newSlide.innerHTML = html || '';
399        newSlide.className = slideClassList;
400        return _this._extendSwiperSlide(newSlide);
401    };
402
403    //Append Slide
404    _this.appendSlide = function (html, slideClassList, el) {
405        if (!html) return;
406        if (html.nodeType) {
407            return _this._extendSwiperSlide(html).append();
408        }
409        else {
410            return _this.createSlide(html, slideClassList, el).append();
411        }
412    };
413    _this.prependSlide = function (html, slideClassList, el) {
414        if (!html) return;
415        if (html.nodeType) {
416            return _this._extendSwiperSlide(html).prepend();
417        }
418        else {
419            return _this.createSlide(html, slideClassList, el).prepend();
420        }
421    };
422    _this.insertSlideAfter = function (index, html, slideClassList, el) {
423        if (typeof index === 'undefined') return false;
424        if (html.nodeType) {
425            return _this._extendSwiperSlide(html).insertAfter(index);
426        }
427        else {
428            return _this.createSlide(html, slideClassList, el).insertAfter(index);
429        }
430    };
431    _this.removeSlide = function (index) {
432        if (_this.slides[index]) {
433            if (params.loop) {
434                if (!_this.slides[index + _this.loopedSlides]) return false;
435                _this.slides[index + _this.loopedSlides].remove();
436                _this.removeLoopedSlides();
437                _this.calcSlides();
438                _this.createLoop();
439            }
440            else _this.slides[index].remove();
441            return true;
442        }
443        else return false;
444    };
445    _this.removeLastSlide = function () {
446        if (_this.slides.length > 0) {
447            if (params.loop) {
448                _this.slides[_this.slides.length - 1 - _this.loopedSlides].remove();
449                _this.removeLoopedSlides();
450                _this.calcSlides();
451                _this.createLoop();
452            }
453            else _this.slides[_this.slides.length - 1].remove();
454            return true;
455        }
456        else {
457            return false;
458        }
459    };
460    _this.removeAllSlides = function () {
461        var num = _this.slides.length;
462        for (var i = _this.slides.length - 1; i >= 0; i--) {
463            _this.slides[i].remove();
464            if (i === num - 1) {
465                _this.setWrapperTranslate(0);
466            }
467        }
468    };
469    _this.getSlide = function (index) {
470        return _this.slides[index];
471    };
472    _this.getLastSlide = function () {
473        return _this.slides[_this.slides.length - 1];
474    };
475    _this.getFirstSlide = function () {
476        return _this.slides[0];
477    };
478
479    //Currently Active Slide
480    _this.activeSlide = function () {
481        return _this.slides[_this.activeIndex];
482    };
483
484    /*=========================
485     Wrapper for Callbacks : Allows additive callbacks via function arrays
486     ===========================*/
487    _this.fireCallback = function () {
488        var callback = arguments[0];
489        if (Object.prototype.toString.call(callback) === '[object Array]') {
490            for (var i = 0; i < callback.length; i++) {
491                if (typeof callback[i] === 'function') {
492                    callback[i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
493                }
494            }
495        } else if (Object.prototype.toString.call(callback) === '[object String]') {
496            if (params['on' + callback]) _this.fireCallback(params['on' + callback], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
497        } else {
498            callback(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
499        }
500    };
501    function isArray(obj) {
502        if (Object.prototype.toString.apply(obj) === '[object Array]') return true;
503        return false;
504    }
505
506    /**
507     * Allows user to add callbacks, rather than replace them
508     * @param callback
509     * @param func
510     * @return {*}
511     */
512    _this.addCallback = function (callback, func) {
513        var _this = this, tempFunc;
514        if (_this.params['on' + callback]) {
515            if (isArray(this.params['on' + callback])) {
516                return this.params['on' + callback].push(func);
517            } else if (typeof this.params['on' + callback] === 'function') {
518                tempFunc = this.params['on' + callback];
519                this.params['on' + callback] = [];
520                this.params['on' + callback].push(tempFunc);
521                return this.params['on' + callback].push(func);
522            }
523        } else {
524            this.params['on' + callback] = [];
525            return this.params['on' + callback].push(func);
526        }
527    };
528    _this.removeCallbacks = function (callback) {
529        if (_this.params['on' + callback]) {
530            _this.params['on' + callback] = null;
531        }
532    };
533
534    /*=========================
535      Plugins API
536      ===========================*/
537    var _plugins = [];
538    for (var plugin in _this.plugins) {
539        if (params[plugin]) {
540            var p = _this.plugins[plugin](_this, params[plugin]);
541            if (p) _plugins.push(p);
542        }
543    }
544    _this.callPlugins = function (method, args) {
545        if (!args) args = {};
546        for (var i = 0; i < _plugins.length; i++) {
547            if (method in _plugins[i]) {
548                _plugins[i][method](args);
549            }
550        }
551    };
552
553    /*=========================
554      Windows Phone 8 Fix
555      ===========================*/
556    if ((_this.browser.ie10 || _this.browser.ie11) && !params.onlyExternal) {
557        _this.wrapper.classList.add('swiper-wp8-' + (isH ? 'horizontal' : 'vertical'));
558    }
559
560    /*=========================
561      Free Mode Class
562      ===========================*/
563    if (params.freeMode) {
564        _this.container.className += ' swiper-free-mode';
565    }
566
567    /*==================================================
568        Init/Re-init/Resize Fix
569    ====================================================*/
570    _this.initialized = false;
571    _this.init = function (force, forceCalcSlides) {
572        var _width = _this.h.getWidth(_this.container, false, params.roundLengths);
573        var _height = _this.h.getHeight(_this.container, false, params.roundLengths);
574        if (_width === _this.width && _height === _this.height && !force) return;
575
576        _this.width = _width;
577        _this.height = _height;
578
579        var slideWidth, slideHeight, slideMaxHeight, wrapperWidth, wrapperHeight, slideLeft;
580        var i; // loop index variable to avoid JSHint W004 / W038
581        containerSize = isH ? _width : _height;
582        var wrapper = _this.wrapper;
583
584        if (force) {
585            _this.calcSlides(forceCalcSlides);
586        }
587
588        if (params.slidesPerView === 'auto') {
589            //Auto mode
590            var slidesWidth = 0;
591            var slidesHeight = 0;
592
593            //Unset Styles
594            if (params.slidesOffset > 0) {
595                wrapper.style.paddingLeft = '';
596                wrapper.style.paddingRight = '';
597                wrapper.style.paddingTop = '';
598                wrapper.style.paddingBottom = '';
599            }
600            wrapper.style.width = '';
601            wrapper.style.height = '';
602            if (params.offsetPxBefore > 0) {
603                if (isH) _this.wrapperLeft = params.offsetPxBefore;
604                else _this.wrapperTop = params.offsetPxBefore;
605            }
606            if (params.offsetPxAfter > 0) {
607                if (isH) _this.wrapperRight = params.offsetPxAfter;
608                else _this.wrapperBottom = params.offsetPxAfter;
609            }
610
611            if (params.centeredSlides) {
612                if (isH) {
613                    _this.wrapperLeft = (containerSize - this.slides[0].getWidth(true, params.roundLengths)) / 2;
614                    _this.wrapperRight = (containerSize - _this.slides[_this.slides.length - 1].getWidth(true, params.roundLengths)) / 2;
615                }
616                else {
617                    _this.wrapperTop = (containerSize - _this.slides[0].getHeight(true, params.roundLengths)) / 2;
618                    _this.wrapperBottom = (containerSize - _this.slides[_this.slides.length - 1].getHeight(true, params.roundLengths)) / 2;
619                }
620            }
621
622            if (isH) {
623                if (_this.wrapperLeft >= 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
624                if (_this.wrapperRight >= 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
625            }
626            else {
627                if (_this.wrapperTop >= 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
628                if (_this.wrapperBottom >= 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
629            }
630            slideLeft = 0;
631            var centeredSlideLeft = 0;
632            _this.snapGrid = [];
633            _this.slidesGrid = [];
634
635            slideMaxHeight = 0;
636            for (i = 0; i < _this.slides.length; i++) {
637                slideWidth = _this.slides[i].getWidth(true, params.roundLengths);
638                slideHeight = _this.slides[i].getHeight(true, params.roundLengths);
639                if (params.calculateHeight) {
640                    slideMaxHeight = Math.max(slideMaxHeight, slideHeight);
641                }
642                var _slideSize = isH ? slideWidth : slideHeight;
643                if (params.centeredSlides) {
644                    var nextSlideWidth = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getWidth(true, params.roundLengths);
645                    var nextSlideHeight = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getHeight(true, params.roundLengths);
646                    var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight;
647                    if (_slideSize > containerSize) {
648                        if (params.slidesPerViewFit) {
649                            _this.snapGrid.push(slideLeft + _this.wrapperLeft);
650                            _this.snapGrid.push(slideLeft + _slideSize - containerSize + _this.wrapperLeft);
651                        }
652                        else {
653                            for (var j = 0; j <= Math.floor(_slideSize / (containerSize + _this.wrapperLeft)); j++) {
654                                if (j === 0) _this.snapGrid.push(slideLeft + _this.wrapperLeft);
655                                else _this.snapGrid.push(slideLeft + _this.wrapperLeft + containerSize * j);
656                            }
657                        }
658                        _this.slidesGrid.push(slideLeft + _this.wrapperLeft);
659                    }
660                    else {
661                        _this.snapGrid.push(centeredSlideLeft);
662                        _this.slidesGrid.push(centeredSlideLeft);
663                    }
664                    centeredSlideLeft += _slideSize / 2 + nextSlideSize / 2;
665                }
666                else {
667                    if (_slideSize > containerSize) {
668                        if (params.slidesPerViewFit) {
669                            _this.snapGrid.push(slideLeft);
670                            _this.snapGrid.push(slideLeft + _slideSize - containerSize);
671                        }
672                        else {
673                            if (containerSize !== 0) {
674                                for (var k = 0; k <= Math.floor(_slideSize / containerSize); k++) {
675                                    _this.snapGrid.push(slideLeft + containerSize * k);
676                                }
677                            }
678                            else {
679                                _this.snapGrid.push(slideLeft);
680                            }
681                        }
682
683                    }
684                    else {
685                        _this.snapGrid.push(slideLeft);
686                    }
687                    _this.slidesGrid.push(slideLeft);
688                }
689
690                slideLeft += _slideSize;
691
692                slidesWidth += slideWidth;
693                slidesHeight += slideHeight;
694            }
695            if (params.calculateHeight) _this.height = slideMaxHeight;
696            if (isH) {
697                wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft;
698                if(!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') {
699                    wrapper.style.width = (slidesWidth) + 'px';
700                }
701                if(!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') {
702                    wrapper.style.height = (_this.height) + 'px';
703                }
704            }
705            else {
706                if(!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') {
707                    wrapper.style.width = (_this.width) + 'px';
708                }
709                if(!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') {
710                    wrapper.style.height = (slidesHeight) + 'px';
711                }
712                wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom;
713            }
714
715        }
716        else if (params.scrollContainer) {
717            //Scroll Container
718            wrapper.style.width = '';
719            wrapper.style.height = '';
720            wrapperWidth = _this.slides[0].getWidth(true, params.roundLengths);
721            wrapperHeight = _this.slides[0].getHeight(true, params.roundLengths);
722            wrapperSize = isH ? wrapperWidth : wrapperHeight;
723            wrapper.style.width = wrapperWidth + 'px';
724            wrapper.style.height = wrapperHeight + 'px';
725            slideSize = isH ? wrapperWidth : wrapperHeight;
726
727        }
728        else {
729            //For usual slides
730            if (params.calculateHeight) {
731                slideMaxHeight = 0;
732                wrapperHeight = 0;
733                //ResetWrapperSize
734                if (!isH) _this.container.style.height = '';
735                wrapper.style.height = '';
736
737                for (i = 0; i < _this.slides.length; i++) {
738                    //ResetSlideSize
739                    _this.slides[i].style.height = '';
740                    slideMaxHeight = Math.max(_this.slides[i].getHeight(true), slideMaxHeight);
741                    if (!isH) wrapperHeight += _this.slides[i].getHeight(true);
742                }
743                slideHeight = slideMaxHeight;
744                _this.height = slideHeight;
745
746                if (isH) wrapperHeight = slideHeight;
747                else {
748                    containerSize = slideHeight;
749                    _this.container.style.height = containerSize + 'px';
750                }
751            }
752            else {
753                slideHeight = isH ? _this.height : _this.height / params.slidesPerView;
754                if (params.roundLengths) slideHeight = Math.ceil(slideHeight);
755                wrapperHeight = isH ? _this.height : _this.slides.length * slideHeight;
756            }
757            slideWidth = isH ? _this.width / params.slidesPerView : _this.width;
758            if (params.roundLengths) slideWidth = Math.ceil(slideWidth);
759            wrapperWidth = isH ? _this.slides.length * slideWidth : _this.width;
760            slideSize = isH ? slideWidth : slideHeight;
761
762            if (params.offsetSlidesBefore > 0) {
763                if (isH) _this.wrapperLeft = slideSize * params.offsetSlidesBefore;
764                else _this.wrapperTop = slideSize * params.offsetSlidesBefore;
765            }
766            if (params.offsetSlidesAfter > 0) {
767                if (isH) _this.wrapperRight = slideSize * params.offsetSlidesAfter;
768                else _this.wrapperBottom = slideSize * params.offsetSlidesAfter;
769            }
770            if (params.offsetPxBefore > 0) {
771                if (isH) _this.wrapperLeft = params.offsetPxBefore;
772                else _this.wrapperTop = params.offsetPxBefore;
773            }
774            if (params.offsetPxAfter > 0) {
775                if (isH) _this.wrapperRight = params.offsetPxAfter;
776                else _this.wrapperBottom = params.offsetPxAfter;
777            }
778            if (params.centeredSlides) {
779                if (isH) {
780                    _this.wrapperLeft = (containerSize - slideSize) / 2;
781                    _this.wrapperRight = (containerSize - slideSize) / 2;
782                }
783                else {
784                    _this.wrapperTop = (containerSize - slideSize) / 2;
785                    _this.wrapperBottom = (containerSize - slideSize) / 2;
786                }
787            }
788            if (isH) {
789                if (_this.wrapperLeft > 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
790                if (_this.wrapperRight > 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
791            }
792            else {
793                if (_this.wrapperTop > 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
794                if (_this.wrapperBottom > 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
795            }
796
797            wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom;
798            if (parseFloat(wrapperWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) {
799                wrapper.style.width = wrapperWidth + 'px';
800            }
801            if (parseFloat(wrapperHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) {
802                wrapper.style.height = wrapperHeight + 'px';
803            }
804            slideLeft = 0;
805            _this.snapGrid = [];
806            _this.slidesGrid = [];
807            for (i = 0; i < _this.slides.length; i++) {
808                _this.snapGrid.push(slideLeft);
809                _this.slidesGrid.push(slideLeft);
810                slideLeft += slideSize;
811                if (parseFloat(slideWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) {
812                    _this.slides[i].style.width = slideWidth + 'px';
813                }
814                if (parseFloat(slideHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) {
815                    _this.slides[i].style.height = slideHeight + 'px';
816                }
817            }
818
819        }
820
821        if (!_this.initialized) {
822            _this.callPlugins('onFirstInit');
823            if (params.onFirstInit) _this.fireCallback(params.onFirstInit, _this);
824        }
825        else {
826            _this.callPlugins('onInit');
827            if (params.onInit) _this.fireCallback(params.onInit, _this);
828        }
829        _this.initialized = true;
830    };
831
832    _this.reInit = function (forceCalcSlides) {
833        _this.init(true, forceCalcSlides);
834    };
835
836    _this.resizeFix = function (reInit) {
837        _this.callPlugins('beforeResizeFix');
838
839        _this.init(params.resizeReInit || reInit);
840
841        // swipe to active slide in fixed mode
842        if (!params.freeMode) {
843            _this.swipeTo((params.loop ? _this.activeLoopIndex : _this.activeIndex), 0, false);
844            // Fix autoplay
845            if (params.autoplay) {
846                if (_this.support.transitions && typeof autoplayTimeoutId !== 'undefined') {
847                    if (typeof autoplayTimeoutId !== 'undefined') {
848                        clearTimeout(autoplayTimeoutId);
849                        autoplayTimeoutId = undefined;
850                        _this.startAutoplay();
851                    }
852                }
853                else {
854                    if (typeof autoplayIntervalId !== 'undefined') {
855                        clearInterval(autoplayIntervalId);
856                        autoplayIntervalId = undefined;
857                        _this.startAutoplay();
858                    }
859                }
860            }
861        }
862        // move wrapper to the beginning in free mode
863        else if (_this.getWrapperTranslate() < -maxWrapperPosition()) {
864            _this.setWrapperTransition(0);
865            _this.setWrapperTranslate(-maxWrapperPosition());
866        }
867
868        _this.callPlugins('afterResizeFix');
869    };
870
871    /*==========================================
872        Max and Min Positions
873    ============================================*/
874    function maxWrapperPosition() {
875        var a = (wrapperSize - containerSize);
876        if (params.freeMode) {
877            a = wrapperSize - containerSize;
878        }
879        // if (params.loop) a -= containerSize;
880        if (params.slidesPerView > _this.slides.length && !params.centeredSlides) {
881            a = 0;
882        }
883        if (a < 0) a = 0;
884        return a;
885    }
886
887    /*==========================================
888        Event Listeners
889    ============================================*/
890    function initEvents() {
891        var bind = _this.h.addEventListener;
892        var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
893        //Touch Events
894        if (! (_this.browser.ie10 || _this.browser.ie11)) {
895            if (_this.support.touch) {
896                bind(eventTarget, 'touchstart', onTouchStart);
897                bind(eventTarget, 'touchmove', onTouchMove);
898                bind(eventTarget, 'touchend', onTouchEnd);
899            }
900            if (params.simulateTouch) {
901                bind(eventTarget, 'mousedown', onTouchStart);
902                bind(document, 'mousemove', onTouchMove);
903                bind(document, 'mouseup', onTouchEnd);
904            }
905        }
906        else {
907            bind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
908            bind(document, _this.touchEvents.touchMove, onTouchMove);
909            bind(document, _this.touchEvents.touchEnd, onTouchEnd);
910        }
911
912        //Resize Event
913        if (params.autoResize) {
914            bind(window, 'resize', _this.resizeFix);
915        }
916        //Slide Events
917        addSlideEvents();
918        //Mousewheel
919        _this._wheelEvent = false;
920        if (params.mousewheelControl) {
921            if (document.onmousewheel !== undefined) {
922                _this._wheelEvent = 'mousewheel';
923            }
924            if (!_this._wheelEvent) {
925                try {
926                    new WheelEvent('wheel');
927                    _this._wheelEvent = 'wheel';
928                } catch (e) {}
929            }
930            if (!_this._wheelEvent) {
931                _this._wheelEvent = 'DOMMouseScroll';
932            }
933            if (_this._wheelEvent) {
934                bind(_this.container, _this._wheelEvent, handleMousewheel);
935            }
936        }
937
938        //Keyboard
939		function _loadImage(img) {
940			var image, src;
941			var onReady = function () {
942				if (typeof _this === 'undefined' || _this === null) return;
943				if (_this.imagesLoaded !== undefined) _this.imagesLoaded++;
944				if (_this.imagesLoaded === _this.imagesToLoad.length) {
945					_this.reInit();
946					if (params.onImagesReady) _this.fireCallback(params.onImagesReady, _this);
947				}
948			};
949
950			if(!img.complete){
951				src = (img.currentSrc || img.getAttribute('src'))
952				if( src ){
953					image = new Image();
954					image.onload = onReady;
955					image.onerror = onReady;
956					image.src = src;
957				} else {
958					onReady();
959				}
960
961			} else {//image already loaded...
962				onReady();
963			}
964		}
965
966		if (params.keyboardControl) {
967			bind(document, 'keydown', handleKeyboardKeys);
968		}
969		if (params.updateOnImagesReady) {
970			_this.imagesToLoad = $$('img', _this.container);
971
972			for (var i = 0; i < _this.imagesToLoad.length; i++) {
973				_loadImage(_this.imagesToLoad[i]);
974			}
975		}
976    }
977
978    //Remove Event Listeners
979    _this.destroy = function (removeStyles) {
980        var unbind = _this.h.removeEventListener;
981        var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
982        //Touch Events
983        if (! (_this.browser.ie10 || _this.browser.ie11)) {
984            if (_this.support.touch) {
985                unbind(eventTarget, 'touchstart', onTouchStart);
986                unbind(eventTarget, 'touchmove', onTouchMove);
987                unbind(eventTarget, 'touchend', onTouchEnd);
988            }
989            if (params.simulateTouch) {
990                unbind(eventTarget, 'mousedown', onTouchStart);
991                unbind(document, 'mousemove', onTouchMove);
992                unbind(document, 'mouseup', onTouchEnd);
993            }
994        }
995        else {
996            unbind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
997            unbind(document, _this.touchEvents.touchMove, onTouchMove);
998            unbind(document, _this.touchEvents.touchEnd, onTouchEnd);
999        }
1000
1001        //Resize Event
1002        if (params.autoResize) {
1003            unbind(window, 'resize', _this.resizeFix);
1004        }
1005
1006        //Init Slide Events
1007        removeSlideEvents();
1008
1009        //Pagination
1010        if (params.paginationClickable) {
1011            removePaginationEvents();
1012        }
1013
1014        //Mousewheel
1015        if (params.mousewheelControl && _this._wheelEvent) {
1016            unbind(_this.container, _this._wheelEvent, handleMousewheel);
1017        }
1018
1019        //Keyboard
1020        if (params.keyboardControl) {
1021            unbind(document, 'keydown', handleKeyboardKeys);
1022        }
1023
1024        //Stop autoplay
1025        if (params.autoplay) {
1026            _this.stopAutoplay();
1027        }
1028        // Remove styles
1029        if (removeStyles) {
1030            _this.wrapper.removeAttribute('style');
1031            for (var i = 0; i < _this.slides.length; i++) {
1032                _this.slides[i].removeAttribute('style');
1033            }
1034        }
1035        // Plugins
1036        _this.callPlugins('onDestroy');
1037
1038        // Check jQuery/Zepto data
1039        if (window.jQuery && window.jQuery(_this.container).data('swiper')) {
1040            window.jQuery(_this.container).removeData('swiper');
1041        }
1042        if (window.Zepto && window.Zepto(_this.container).data('swiper')) {
1043            window.Zepto(_this.container).removeData('swiper');
1044        }
1045
1046        //Destroy variable
1047        _this = null;
1048    };
1049
1050    function addSlideEvents() {
1051        var bind = _this.h.addEventListener,
1052            i;
1053
1054        //Prevent Links Events
1055        if (params.preventLinks) {
1056            var links = $$('a', _this.container);
1057            for (i = 0; i < links.length; i++) {
1058                bind(links[i], 'click', preventClick);
1059            }
1060        }
1061        //Release Form Elements
1062        if (params.releaseFormElements) {
1063            var formElements = $$('input, textarea, select', _this.container);
1064            for (i = 0; i < formElements.length; i++) {
1065                bind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
1066                if (_this.support.touch && params.simulateTouch) {
1067                    bind(formElements[i], 'mousedown', releaseForms, true);
1068                }
1069            }
1070        }
1071
1072        //Slide Clicks & Touches
1073        if (params.onSlideClick) {
1074            for (i = 0; i < _this.slides.length; i++) {
1075                bind(_this.slides[i], 'click', slideClick);
1076            }
1077        }
1078        if (params.onSlideTouch) {
1079            for (i = 0; i < _this.slides.length; i++) {
1080                bind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
1081            }
1082        }
1083    }
1084    function removeSlideEvents() {
1085        var unbind = _this.h.removeEventListener,
1086            i;
1087
1088        //Slide Clicks & Touches
1089        if (params.onSlideClick) {
1090            for (i = 0; i < _this.slides.length; i++) {
1091                unbind(_this.slides[i], 'click', slideClick);
1092            }
1093        }
1094        if (params.onSlideTouch) {
1095            for (i = 0; i < _this.slides.length; i++) {
1096                unbind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
1097            }
1098        }
1099        //Release Form Elements
1100        if (params.releaseFormElements) {
1101            var formElements = $$('input, textarea, select', _this.container);
1102            for (i = 0; i < formElements.length; i++) {
1103                unbind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
1104                if (_this.support.touch && params.simulateTouch) {
1105                    unbind(formElements[i], 'mousedown', releaseForms, true);
1106                }
1107            }
1108        }
1109        //Prevent Links Events
1110        if (params.preventLinks) {
1111            var links = $$('a', _this.container);
1112            for (i = 0; i < links.length; i++) {
1113                unbind(links[i], 'click', preventClick);
1114            }
1115        }
1116    }
1117    /*==========================================
1118        Keyboard Control
1119    ============================================*/
1120    function handleKeyboardKeys(e) {
1121        var kc = e.keyCode || e.charCode;
1122        if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;
1123        if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
1124            var inView = false;
1125            //Check that swiper should be inside of visible area of window
1126            var swiperOffset = _this.h.getOffset(_this.container);
1127            var scrollLeft = _this.h.windowScroll().left;
1128            var scrollTop = _this.h.windowScroll().top;
1129            var windowWidth = _this.h.windowWidth();
1130            var windowHeight = _this.h.windowHeight();
1131            var swiperCoord = [
1132                [swiperOffset.left, swiperOffset.top],
1133                [swiperOffset.left + _this.width, swiperOffset.top],
1134                [swiperOffset.left, swiperOffset.top + _this.height],
1135                [swiperOffset.left + _this.width, swiperOffset.top + _this.height]
1136            ];
1137            for (var i = 0; i < swiperCoord.length; i++) {
1138                var point = swiperCoord[i];
1139                if (
1140                    point[0] >= scrollLeft && point[0] <= scrollLeft + windowWidth &&
1141                    point[1] >= scrollTop && point[1] <= scrollTop + windowHeight
1142                ) {
1143                    inView = true;
1144                }
1145
1146            }
1147            if (!inView) return;
1148        }
1149        if (isH) {
1150            if (kc === 37 || kc === 39) {
1151                if (e.preventDefault) e.preventDefault();
1152                else e.returnValue = false;
1153            }
1154            if (kc === 39) _this.swipeNext();
1155            if (kc === 37) _this.swipePrev();
1156        }
1157        else {
1158            if (kc === 38 || kc === 40) {
1159                if (e.preventDefault) e.preventDefault();
1160                else e.returnValue = false;
1161            }
1162            if (kc === 40) _this.swipeNext();
1163            if (kc === 38) _this.swipePrev();
1164        }
1165    }
1166
1167    _this.disableKeyboardControl = function () {
1168        params.keyboardControl = false;
1169        _this.h.removeEventListener(document, 'keydown', handleKeyboardKeys);
1170    };
1171
1172    _this.enableKeyboardControl = function () {
1173        params.keyboardControl = true;
1174        _this.h.addEventListener(document, 'keydown', handleKeyboardKeys);
1175    };
1176
1177    /*==========================================
1178        Mousewheel Control
1179    ============================================*/
1180    var lastScrollTime = (new Date()).getTime();
1181    function handleMousewheel(e) {
1182        var we = _this._wheelEvent;
1183        var delta = 0;
1184
1185        //Opera & IE
1186        if (e.detail) delta = -e.detail;
1187        //WebKits
1188        else if (we === 'mousewheel') {
1189            if (params.mousewheelControlForceToAxis) {
1190                if (isH) {
1191                    if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX;
1192                    else return;
1193                }
1194                else {
1195                    if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
1196                    else return;
1197                }
1198            }
1199            else {
1200                delta = e.wheelDelta;
1201            }
1202        }
1203        //Old FireFox
1204        else if (we === 'DOMMouseScroll') delta = -e.detail;
1205        //New FireFox
1206        else if (we === 'wheel') {
1207            if (params.mousewheelControlForceToAxis) {
1208                if (isH) {
1209                    if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX;
1210                    else return;
1211                }
1212                else {
1213                    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
1214                    else return;
1215                }
1216            }
1217            else {
1218                delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
1219            }
1220        }
1221
1222        if (!params.freeMode) {
1223            if ((new Date()).getTime() - lastScrollTime > 60) {
1224                if (delta < 0) _this.swipeNext();
1225                else _this.swipePrev();
1226            }
1227            lastScrollTime = (new Date()).getTime();
1228
1229        }
1230        else {
1231            //Freemode or scrollContainer:
1232            var position = _this.getWrapperTranslate() + delta;
1233
1234            if (position > 0) position = 0;
1235            if (position < -maxWrapperPosition()) position = -maxWrapperPosition();
1236
1237            _this.setWrapperTransition(0);
1238            _this.setWrapperTranslate(position);
1239            _this.updateActiveSlide(position);
1240
1241            // Return page scroll on edge positions
1242            if (position === 0 || position === -maxWrapperPosition()) return;
1243        }
1244        if (params.autoplay) _this.stopAutoplay(true);
1245
1246        if (e.preventDefault) e.preventDefault();
1247        else e.returnValue = false;
1248        return false;
1249    }
1250    _this.disableMousewheelControl = function () {
1251        if (!_this._wheelEvent) return false;
1252        params.mousewheelControl = false;
1253        _this.h.removeEventListener(_this.container, _this._wheelEvent, handleMousewheel);
1254        return true;
1255    };
1256
1257    _this.enableMousewheelControl = function () {
1258        if (!_this._wheelEvent) return false;
1259        params.mousewheelControl = true;
1260        _this.h.addEventListener(_this.container, _this._wheelEvent, handleMousewheel);
1261        return true;
1262    };
1263
1264    /*=========================
1265      Grab Cursor
1266      ===========================*/
1267    if (params.grabCursor) {
1268        var containerStyle = _this.container.style;
1269        containerStyle.cursor = 'move';
1270        containerStyle.cursor = 'grab';
1271        containerStyle.cursor = '-moz-grab';
1272        containerStyle.cursor = '-webkit-grab';
1273    }
1274
1275    /*=========================
1276      Slides Events Handlers
1277      ===========================*/
1278
1279    _this.allowSlideClick = true;
1280    function slideClick(event) {
1281        if (_this.allowSlideClick) {
1282            setClickedSlide(event);
1283            _this.fireCallback(params.onSlideClick, _this, event);
1284        }
1285    }
1286
1287    function slideTouch(event) {
1288        setClickedSlide(event);
1289        _this.fireCallback(params.onSlideTouch, _this, event);
1290    }
1291
1292    function setClickedSlide(event) {
1293
1294        // IE 6-8 support
1295        if (!event.currentTarget) {
1296            var element = event.srcElement;
1297            do {
1298                if (element.className.indexOf(params.slideClass) > -1) {
1299                    break;
1300                }
1301                element = element.parentNode;
1302            } while (element);
1303            _this.clickedSlide = element;
1304        }
1305        else {
1306            _this.clickedSlide = event.currentTarget;
1307        }
1308
1309        _this.clickedSlideIndex     = _this.slides.indexOf(_this.clickedSlide);
1310        _this.clickedSlideLoopIndex = _this.clickedSlideIndex - (_this.loopedSlides || 0);
1311    }
1312
1313    _this.allowLinks = true;
1314    function preventClick(e) {
1315        if (!_this.allowLinks) {
1316            if (e.preventDefault) e.preventDefault();
1317            else e.returnValue = false;
1318            if (params.preventLinksPropagation && 'stopPropagation' in e) {
1319                e.stopPropagation();
1320            }
1321            return false;
1322        }
1323    }
1324    function releaseForms(e) {
1325        if (e.stopPropagation) e.stopPropagation();
1326        else e.returnValue = false;
1327        return false;
1328
1329    }
1330
1331    /*==================================================
1332        Event Handlers
1333    ====================================================*/
1334    var isTouchEvent = false;
1335    var allowThresholdMove;
1336    var allowMomentumBounce = true;
1337    function onTouchStart(event) {
1338        if (params.preventLinks) _this.allowLinks = true;
1339        //Exit if slider is already was touched
1340        if (_this.isTouched || params.onlyExternal) {
1341            return false;
1342        }
1343
1344        // Blur active elements
1345        var eventTarget = event.target || event.srcElement;
1346        if (document.activeElement) {
1347            if (document.activeElement !== eventTarget) document.activeElement.blur();
1348        }
1349
1350        // Form tag names
1351        var formTagNames = ('input select textarea').split(' ');
1352
1353        // Check for no swiping
1354        if (params.noSwiping && (eventTarget) && noSwipingSlide(eventTarget)) return false;
1355        allowMomentumBounce = false;
1356        //Check For Nested Swipers
1357        _this.isTouched = true;
1358        isTouchEvent = event.type === 'touchstart';
1359
1360        // prevent user enter with right and the swiper move (needs isTouchEvent)
1361        if (!isTouchEvent && 'which' in event && event.which === 3) {
1362            _this.isTouched = false;
1363            return false;
1364        }
1365
1366        if (!isTouchEvent || event.targetTouches.length === 1) {
1367            _this.callPlugins('onTouchStartBegin');
1368            if (!isTouchEvent && !_this.isAndroid && formTagNames.indexOf(eventTarget.tagName.toLowerCase()) < 0) {
1369
1370                if (event.preventDefault) event.preventDefault();
1371                else event.returnValue = false;
1372            }
1373
1374            var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1375            var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1376
1377            //Start Touches to check the scrolling
1378            _this.touches.startX = _this.touches.currentX = pageX;
1379            _this.touches.startY = _this.touches.currentY = pageY;
1380
1381            _this.touches.start = _this.touches.current = isH ? pageX : pageY;
1382
1383            //Set Transition Time to 0
1384            _this.setWrapperTransition(0);
1385
1386            //Get Start Translate Position
1387            _this.positions.start = _this.positions.current = _this.getWrapperTranslate();
1388
1389            //Set Transform
1390            _this.setWrapperTranslate(_this.positions.start);
1391
1392            //TouchStartTime
1393            _this.times.start = (new Date()).getTime();
1394
1395            //Unset Scrolling
1396            isScrolling = undefined;
1397
1398            //Set Treshold
1399            if (params.moveStartThreshold > 0) {
1400                allowThresholdMove = false;
1401            }
1402
1403            //CallBack
1404            if (params.onTouchStart) _this.fireCallback(params.onTouchStart, _this, event);
1405            _this.callPlugins('onTouchStartEnd');
1406
1407        }
1408    }
1409    var velocityPrevPosition, velocityPrevTime;
1410    function onTouchMove(event) {
1411        // If slider is not touched - exit
1412        if (!_this.isTouched || params.onlyExternal) return;
1413        if (isTouchEvent && event.type === 'mousemove') return;
1414
1415        var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1416        var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1417
1418        //check for scrolling
1419        if (typeof isScrolling === 'undefined' && isH) {
1420            isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs(pageX - _this.touches.startX));
1421        }
1422        if (typeof isScrolling === 'undefined' && !isH) {
1423            isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs(pageX - _this.touches.startX));
1424        }
1425        if (isScrolling) {
1426            _this.isTouched = false;
1427            return;
1428        }
1429
1430        // One way swipes
1431        if (isH) {
1432            if ((!params.swipeToNext && pageX < _this.touches.startX) || ((!params.swipeToPrev && pageX > _this.touches.startX))) {
1433                return;
1434            }
1435        }
1436        else {
1437            if ((!params.swipeToNext && pageY < _this.touches.startY) || ((!params.swipeToPrev && pageY > _this.touches.startY))) {
1438                return;
1439            }
1440        }
1441
1442        //Check For Nested Swipers
1443        if (event.assignedToSwiper) {
1444            _this.isTouched = false;
1445            return;
1446        }
1447        event.assignedToSwiper = true;
1448
1449        //Block inner links
1450        if (params.preventLinks) {
1451            _this.allowLinks = false;
1452        }
1453        if (params.onSlideClick) {
1454            _this.allowSlideClick = false;
1455        }
1456
1457        //Stop AutoPlay if exist
1458        if (params.autoplay) {
1459            _this.stopAutoplay(true);
1460        }
1461        if (!isTouchEvent || event.touches.length === 1) {
1462
1463            //Moved Flag
1464            if (!_this.isMoved) {
1465                _this.callPlugins('onTouchMoveStart');
1466
1467                if (params.loop) {
1468                    _this.fixLoop();
1469                    _this.positions.start = _this.getWrapperTranslate();
1470                }
1471                if (params.onTouchMoveStart) _this.fireCallback(params.onTouchMoveStart, _this);
1472            }
1473            _this.isMoved = true;
1474
1475            // cancel event
1476            if (event.preventDefault) event.preventDefault();
1477            else event.returnValue = false;
1478
1479            _this.touches.current = isH ? pageX : pageY;
1480
1481            _this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start;
1482
1483            //Resistance Callbacks
1484            if (_this.positions.current > 0 && params.onResistanceBefore) {
1485                _this.fireCallback(params.onResistanceBefore, _this, _this.positions.current);
1486            }
1487            if (_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) {
1488                _this.fireCallback(params.onResistanceAfter, _this, Math.abs(_this.positions.current + maxWrapperPosition()));
1489            }
1490            //Resistance
1491            if (params.resistance && params.resistance !== '100%') {
1492                var resistance;
1493                //Resistance for Negative-Back sliding
1494                if (_this.positions.current > 0) {
1495                    resistance = 1 - _this.positions.current / containerSize / 2;
1496                    if (resistance < 0.5)
1497                        _this.positions.current = (containerSize / 2);
1498                    else
1499                        _this.positions.current = _this.positions.current * resistance;
1500                }
1501                //Resistance for After-End Sliding
1502                if (_this.positions.current < -maxWrapperPosition()) {
1503
1504                    var diff = (_this.touches.current - _this.touches.start) * params.touchRatio + (maxWrapperPosition() + _this.positions.start);
1505                    resistance = (containerSize + diff) / (containerSize);
1506                    var newPos = _this.positions.current - diff * (1 - resistance) / 2;
1507                    var stopPos = -maxWrapperPosition() - containerSize / 2;
1508
1509                    if (newPos < stopPos || resistance <= 0)
1510                        _this.positions.current = stopPos;
1511                    else
1512                        _this.positions.current = newPos;
1513                }
1514            }
1515            if (params.resistance && params.resistance === '100%') {
1516                //Resistance for Negative-Back sliding
1517                if (_this.positions.current > 0 && !(params.freeMode && !params.freeModeFluid)) {
1518                    _this.positions.current = 0;
1519                }
1520                //Resistance for After-End Sliding
1521                if (_this.positions.current < -maxWrapperPosition() && !(params.freeMode && !params.freeModeFluid)) {
1522                    _this.positions.current = -maxWrapperPosition();
1523                }
1524            }
1525            //Move Slides
1526            if (!params.followFinger) return;
1527
1528            if (!params.moveStartThreshold) {
1529                _this.setWrapperTranslate(_this.positions.current);
1530            }
1531            else {
1532                if (Math.abs(_this.touches.current - _this.touches.start) > params.moveStartThreshold || allowThresholdMove) {
1533                    if (!allowThresholdMove) {
1534                        allowThresholdMove = true;
1535                        _this.touches.start = _this.touches.current;
1536                        return;
1537                    }
1538                    _this.setWrapperTranslate(_this.positions.current);
1539                }
1540                else {
1541                    _this.positions.current = _this.positions.start;
1542                }
1543            }
1544
1545            if (params.freeMode || params.watchActiveIndex) {
1546                _this.updateActiveSlide(_this.positions.current);
1547            }
1548
1549            //Grab Cursor
1550            if (params.grabCursor) {
1551                _this.container.style.cursor = 'move';
1552                _this.container.style.cursor = 'grabbing';
1553                _this.container.style.cursor = '-moz-grabbin';
1554                _this.container.style.cursor = '-webkit-grabbing';
1555            }
1556            //Velocity
1557            if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current;
1558            if (!velocityPrevTime) velocityPrevTime = (new Date()).getTime();
1559            _this.velocity = (_this.touches.current - velocityPrevPosition) / ((new Date()).getTime() - velocityPrevTime) / 2;
1560            if (Math.abs(_this.touches.current - velocityPrevPosition) < 2) _this.velocity = 0;
1561            velocityPrevPosition = _this.touches.current;
1562            velocityPrevTime = (new Date()).getTime();
1563            //Callbacks
1564            _this.callPlugins('onTouchMoveEnd');
1565            if (params.onTouchMove) _this.fireCallback(params.onTouchMove, _this, event);
1566
1567            return false;
1568        }
1569    }
1570    function onTouchEnd(event) {
1571        //Check For scrolling
1572        if (isScrolling) {
1573            _this.swipeReset();
1574        }
1575        // If slider is not touched exit
1576        if (params.onlyExternal || !_this.isTouched) return;
1577        _this.isTouched = false;
1578
1579        //Return Grab Cursor
1580        if (params.grabCursor) {
1581            _this.container.style.cursor = 'move';
1582            _this.container.style.cursor = 'grab';
1583            _this.container.style.cursor = '-moz-grab';
1584            _this.container.style.cursor = '-webkit-grab';
1585        }
1586
1587        //Check for Current Position
1588        if (!_this.positions.current && _this.positions.current !== 0) {
1589            _this.positions.current = _this.positions.start;
1590        }
1591
1592        //For case if slider touched but not moved
1593        if (params.followFinger) {
1594            _this.setWrapperTranslate(_this.positions.current);
1595        }
1596
1597        // TouchEndTime
1598        _this.times.end = (new Date()).getTime();
1599
1600        //Difference
1601        _this.touches.diff = _this.touches.current - _this.touches.start;
1602        _this.touches.abs = Math.abs(_this.touches.diff);
1603
1604        _this.positions.diff = _this.positions.current - _this.positions.start;
1605        _this.positions.abs = Math.abs(_this.positions.diff);
1606
1607        var diff = _this.positions.diff;
1608        var diffAbs = _this.positions.abs;
1609        var timeDiff = _this.times.end - _this.times.start;
1610
1611        if (diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks === false) {
1612            if (!params.freeMode && diffAbs !== 0) _this.swipeReset();
1613            //Release inner links
1614            if (params.preventLinks) {
1615                _this.allowLinks = true;
1616            }
1617            if (params.onSlideClick) {
1618                _this.allowSlideClick = true;
1619            }
1620        }
1621
1622        setTimeout(function () {
1623            //Release inner links
1624            if (typeof _this === 'undefined' || _this === null) return;
1625            if (params.preventLinks) {
1626                _this.allowLinks = true;
1627            }
1628            if (params.onSlideClick) {
1629                _this.allowSlideClick = true;
1630            }
1631        }, 100);
1632
1633        var maxPosition = maxWrapperPosition();
1634
1635        //Not moved or Prevent Negative Back Sliding/After-End Sliding
1636        if (!_this.isMoved && params.freeMode) {
1637            _this.isMoved = false;
1638            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1639            _this.callPlugins('onTouchEnd');
1640            return;
1641        }
1642        if (!_this.isMoved || _this.positions.current > 0 || _this.positions.current < -maxPosition) {
1643            _this.swipeReset();
1644            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1645            _this.callPlugins('onTouchEnd');
1646            return;
1647        }
1648
1649        _this.isMoved = false;
1650
1651        //Free Mode
1652        if (params.freeMode) {
1653            if (params.freeModeFluid) {
1654                var momentumDuration = 1000 * params.momentumRatio;
1655                var momentumDistance = _this.velocity * momentumDuration;
1656                var newPosition = _this.positions.current + momentumDistance;
1657                var doBounce = false;
1658                var afterBouncePosition;
1659                var bounceAmount = Math.abs(_this.velocity) * 20 * params.momentumBounceRatio;
1660                if (newPosition < -maxPosition) {
1661                    if (params.momentumBounce && _this.support.transitions) {
1662                        if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition - bounceAmount;
1663                        afterBouncePosition = -maxPosition;
1664                        doBounce = true;
1665                        allowMomentumBounce = true;
1666                    }
1667                    else newPosition = -maxPosition;
1668                }
1669                if (newPosition > 0) {
1670                    if (params.momentumBounce && _this.support.transitions) {
1671                        if (newPosition > bounceAmount) newPosition = bounceAmount;
1672                        afterBouncePosition = 0;
1673                        doBounce = true;
1674                        allowMomentumBounce = true;
1675                    }
1676                    else newPosition = 0;
1677                }
1678                //Fix duration
1679                if (_this.velocity !== 0) momentumDuration = Math.abs((newPosition - _this.positions.current) / _this.velocity);
1680
1681                _this.setWrapperTranslate(newPosition);
1682
1683                _this.setWrapperTransition(momentumDuration);
1684
1685                if (params.momentumBounce && doBounce) {
1686                    _this.wrapperTransitionEnd(function () {
1687                        if (!allowMomentumBounce) return;
1688                        if (params.onMomentumBounce) _this.fireCallback(params.onMomentumBounce, _this);
1689                        _this.callPlugins('onMomentumBounce');
1690
1691                        _this.setWrapperTranslate(afterBouncePosition);
1692                        _this.setWrapperTransition(300);
1693                    });
1694                }
1695
1696                _this.updateActiveSlide(newPosition);
1697            }
1698            if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current);
1699
1700            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1701            _this.callPlugins('onTouchEnd');
1702            return;
1703        }
1704
1705        //Direction
1706        direction = diff < 0 ? 'toNext' : 'toPrev';
1707
1708        //Short Touches
1709        if (direction === 'toNext' && (timeDiff <= 300)) {
1710            if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
1711            else _this.swipeNext(true, true);
1712        }
1713
1714        if (direction === 'toPrev' && (timeDiff <= 300)) {
1715            if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
1716            else _this.swipePrev(true, true);
1717        }
1718
1719        //Long Touches
1720        var targetSlideSize = 0;
1721        if (params.slidesPerView === 'auto') {
1722            //Define current slide's width
1723            var currentPosition = Math.abs(_this.getWrapperTranslate());
1724            var slidesOffset = 0;
1725            var _slideSize;
1726            for (var i = 0; i < _this.slides.length; i++) {
1727                _slideSize = isH ? _this.slides[i].getWidth(true, params.roundLengths) : _this.slides[i].getHeight(true, params.roundLengths);
1728                slidesOffset += _slideSize;
1729                if (slidesOffset > currentPosition) {
1730                    targetSlideSize = _slideSize;
1731                    break;
1732                }
1733            }
1734            if (targetSlideSize > containerSize) targetSlideSize = containerSize;
1735        }
1736        else {
1737            targetSlideSize = slideSize * params.slidesPerView;
1738        }
1739        if (direction === 'toNext' && (timeDiff > 300)) {
1740            if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
1741                _this.swipeNext(true, true);
1742            }
1743            else {
1744                _this.swipeReset();
1745            }
1746        }
1747        if (direction === 'toPrev' && (timeDiff > 300)) {
1748            if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
1749                _this.swipePrev(true, true);
1750            }
1751            else {
1752                _this.swipeReset();
1753            }
1754        }
1755        if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1756        _this.callPlugins('onTouchEnd');
1757    }
1758
1759
1760    /*==================================================
1761        noSwiping Bubble Check by Isaac Strack
1762    ====================================================*/
1763    function noSwipingSlide(el) {
1764        /*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper.
1765        We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling.
1766        So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched
1767        check will never find it, and what was supposed to be noSwiping is able to be swiped.
1768        This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/
1769
1770        // First we create a truthy variable, which is that swiping is allowd (noSwiping = false)
1771        var noSwiping = false;
1772
1773        // Now we iterate up (parentElements) until we reach the node with the wrapperClass.
1774        do {
1775
1776            // Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass).
1777            if (el.className.indexOf(params.noSwipingClass) > -1)
1778            {
1779                noSwiping = true; // If there is, we set noSwiping = true;
1780            }
1781
1782            el = el.parentElement;  // now we iterate up (parent node)
1783
1784        } while (!noSwiping && el.parentElement && el.className.indexOf(params.wrapperClass) === -1); // also include el.parentElement truthy, just in case.
1785
1786        // because we didn't check the wrapper itself, we do so now, if noSwiping is false:
1787        if (!noSwiping && el.className.indexOf(params.wrapperClass) > -1 && el.className.indexOf(params.noSwipingClass) > -1)
1788            noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true;
1789
1790        return noSwiping;
1791    }
1792
1793    function addClassToHtmlString(klass, outerHtml) {
1794        var par = document.createElement('div');
1795        var child;
1796
1797        par.innerHTML = outerHtml;
1798        child = par.firstChild;
1799        child.className += ' ' + klass;
1800
1801        return child.outerHTML;
1802    }
1803
1804
1805    /*==================================================
1806        Swipe Functions
1807    ====================================================*/
1808    _this.swipeNext = function (runCallbacks, internal) {
1809        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1810        if (!internal && params.loop) _this.fixLoop();
1811        if (!internal && params.autoplay) _this.stopAutoplay(true);
1812        _this.callPlugins('onSwipeNext');
1813        var currentPosition = _this.getWrapperTranslate().toFixed(2);
1814        var newPosition = currentPosition;
1815        if (params.slidesPerView === 'auto') {
1816            for (var i = 0; i < _this.snapGrid.length; i++) {
1817                if (-currentPosition >= _this.snapGrid[i].toFixed(2) && -currentPosition < _this.snapGrid[i + 1].toFixed(2)) {
1818                    newPosition = -_this.snapGrid[i + 1];
1819                    break;
1820                }
1821            }
1822        }
1823        else {
1824            var groupSize = slideSize * params.slidesPerGroup;
1825            newPosition = -(Math.floor(Math.abs(currentPosition) / Math.floor(groupSize)) * groupSize + groupSize);
1826        }
1827        if (newPosition < -maxWrapperPosition()) {
1828            newPosition = -maxWrapperPosition();
1829        }
1830        if (newPosition === currentPosition) return false;
1831        swipeToPosition(newPosition, 'next', {runCallbacks: runCallbacks});
1832        return true;
1833    };
1834    _this.swipePrev = function (runCallbacks, internal) {
1835        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1836        if (!internal && params.loop) _this.fixLoop();
1837        if (!internal && params.autoplay) _this.stopAutoplay(true);
1838        _this.callPlugins('onSwipePrev');
1839
1840        var currentPosition = Math.ceil(_this.getWrapperTranslate());
1841        var newPosition;
1842        if (params.slidesPerView === 'auto') {
1843            newPosition = 0;
1844            for (var i = 1; i < _this.snapGrid.length; i++) {
1845                if (-currentPosition === _this.snapGrid[i]) {
1846                    newPosition = -_this.snapGrid[i - 1];
1847                    break;
1848                }
1849                if (-currentPosition > _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
1850                    newPosition = -_this.snapGrid[i];
1851                    break;
1852                }
1853            }
1854        }
1855        else {
1856            var groupSize = slideSize * params.slidesPerGroup;
1857            newPosition = -(Math.ceil(-currentPosition / groupSize) - 1) * groupSize;
1858        }
1859
1860        if (newPosition > 0) newPosition = 0;
1861
1862        if (newPosition === currentPosition) return false;
1863        swipeToPosition(newPosition, 'prev', {runCallbacks: runCallbacks});
1864        return true;
1865
1866    };
1867    _this.swipeReset = function (runCallbacks) {
1868        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1869        _this.callPlugins('onSwipeReset');
1870        var currentPosition = _this.getWrapperTranslate();
1871        var groupSize = slideSize * params.slidesPerGroup;
1872        var newPosition;
1873        var maxPosition = -maxWrapperPosition();
1874        if (params.slidesPerView === 'auto') {
1875            newPosition = 0;
1876            for (var i = 0; i < _this.snapGrid.length; i++) {
1877                if (-currentPosition === _this.snapGrid[i]) return;
1878                if (-currentPosition >= _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
1879                    if (_this.positions.diff > 0) newPosition = -_this.snapGrid[i + 1];
1880                    else newPosition = -_this.snapGrid[i];
1881                    break;
1882                }
1883            }
1884            if (-currentPosition >= _this.snapGrid[_this.snapGrid.length - 1]) newPosition = -_this.snapGrid[_this.snapGrid.length - 1];
1885            if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition();
1886        }
1887        else {
1888            newPosition = currentPosition < 0 ? Math.round(currentPosition / groupSize) * groupSize : 0;
1889            if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition();
1890        }
1891        if (params.scrollContainer)  {
1892            newPosition = currentPosition < 0 ? currentPosition : 0;
1893        }
1894        if (newPosition < -maxWrapperPosition()) {
1895            newPosition = -maxWrapperPosition();
1896        }
1897        if (params.scrollContainer && (containerSize > slideSize)) {
1898            newPosition = 0;
1899        }
1900
1901        if (newPosition === currentPosition) return false;
1902
1903        swipeToPosition(newPosition, 'reset', {runCallbacks: runCallbacks});
1904        return true;
1905    };
1906
1907    _this.swipeTo = function (index, speed, runCallbacks) {
1908        index = parseInt(index, 10);
1909        _this.callPlugins('onSwipeTo', {index: index, speed: speed});
1910        if (params.loop) index = index + _this.loopedSlides;
1911        var currentPosition = _this.getWrapperTranslate();
1912        if (index > (_this.slides.length - 1) || index < 0) return;
1913        var newPosition;
1914        if (params.slidesPerView === 'auto') {
1915            newPosition = -_this.slidesGrid[index];
1916        }
1917        else {
1918            newPosition = -index * slideSize;
1919        }
1920        if (newPosition < - maxWrapperPosition()) {
1921            newPosition = - maxWrapperPosition();
1922        }
1923
1924        if (newPosition === currentPosition) return false;
1925
1926        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1927        swipeToPosition(newPosition, 'to', {index: index, speed: speed, runCallbacks: runCallbacks});
1928        return true;
1929    };
1930
1931    function swipeToPosition(newPosition, action, toOptions) {
1932        var speed = (action === 'to' && toOptions.speed >= 0) ? toOptions.speed : params.speed;
1933        var timeOld = + new Date();
1934
1935        function anim() {
1936            var timeNew = + new Date();
1937            var time = timeNew - timeOld;
1938            currentPosition += animationStep * time / (1000 / 60);
1939            condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1940            if (condition) {
1941                _this.setWrapperTranslate(Math.ceil(currentPosition));
1942                _this._DOMAnimating = true;
1943                window.setTimeout(function () {
1944                    anim();
1945                }, 1000 / 60);
1946            }
1947            else {
1948                if (params.onSlideChangeEnd) {
1949                    if (action === 'to') {
1950                        if (toOptions.runCallbacks === true) _this.fireCallback(params.onSlideChangeEnd, _this, direction);
1951                    }
1952                    else {
1953                        _this.fireCallback(params.onSlideChangeEnd, _this, direction);
1954                    }
1955
1956                }
1957                _this.setWrapperTranslate(newPosition);
1958                _this._DOMAnimating = false;
1959            }
1960        }
1961
1962        if (_this.support.transitions || !params.DOMAnimation) {
1963            _this.setWrapperTranslate(newPosition);
1964            _this.setWrapperTransition(speed);
1965        }
1966        else {
1967            //Try the DOM animation
1968            var currentPosition = _this.getWrapperTranslate();
1969            var animationStep = Math.ceil((newPosition - currentPosition) / speed * (1000 / 60));
1970            var direction = currentPosition > newPosition ? 'toNext' : 'toPrev';
1971            var condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1972            if (_this._DOMAnimating) return;
1973
1974            anim();
1975        }
1976
1977        //Update Active Slide Index
1978        _this.updateActiveSlide(newPosition);
1979
1980        //Callbacks
1981        if (params.onSlideNext && action === 'next' && toOptions.runCallbacks === true) {
1982            _this.fireCallback(params.onSlideNext, _this, newPosition);
1983        }
1984        if (params.onSlidePrev && action === 'prev' && toOptions.runCallbacks === true) {
1985            _this.fireCallback(params.onSlidePrev, _this, newPosition);
1986        }
1987        //'Reset' Callback
1988        if (params.onSlideReset && action === 'reset' && toOptions.runCallbacks === true) {
1989            _this.fireCallback(params.onSlideReset, _this, newPosition);
1990        }
1991
1992        //'Next', 'Prev' and 'To' Callbacks
1993        if ((action === 'next' || action === 'prev' || action === 'to') && toOptions.runCallbacks === true)
1994            slideChangeCallbacks(action);
1995    }
1996    /*==================================================
1997        Transition Callbacks
1998    ====================================================*/
1999    //Prevent Multiple Callbacks
2000    _this._queueStartCallbacks = false;
2001    _this._queueEndCallbacks = false;
2002    function slideChangeCallbacks(direction) {
2003        //Transition Start Callback
2004        _this.callPlugins('onSlideChangeStart');
2005        if (params.onSlideChangeStart) {
2006            if (params.queueStartCallbacks && _this.support.transitions) {
2007                if (_this._queueStartCallbacks) return;
2008                _this._queueStartCallbacks = true;
2009                _this.fireCallback(params.onSlideChangeStart, _this, direction);
2010                _this.wrapperTransitionEnd(function () {
2011                    _this._queueStartCallbacks = false;
2012                });
2013            }
2014            else _this.fireCallback(params.onSlideChangeStart, _this, direction);
2015        }
2016        //Transition End Callback
2017        if (params.onSlideChangeEnd) {
2018            if (_this.support.transitions) {
2019                if (params.queueEndCallbacks) {
2020                    if (_this._queueEndCallbacks) return;
2021                    _this._queueEndCallbacks = true;
2022                    _this.wrapperTransitionEnd(function (swiper) {
2023                        _this.fireCallback(params.onSlideChangeEnd, swiper, direction);
2024                    });
2025                }
2026                else {
2027                    _this.wrapperTransitionEnd(function (swiper) {
2028                        _this.fireCallback(params.onSlideChangeEnd, swiper, direction);
2029                    });
2030                }
2031            }
2032            else {
2033                if (!params.DOMAnimation) {
2034                    setTimeout(function () {
2035                        _this.fireCallback(params.onSlideChangeEnd, _this, direction);
2036                    }, 10);
2037                }
2038            }
2039        }
2040    }
2041
2042    /*==================================================
2043        Update Active Slide Index
2044    ====================================================*/
2045    _this.updateActiveSlide = function (position) {
2046        if (!_this.initialized) return;
2047        if (_this.slides.length === 0) return;
2048        _this.previousIndex = _this.activeIndex;
2049        if (typeof position === 'undefined') position = _this.getWrapperTranslate();
2050        if (position > 0) position = 0;
2051        var i;
2052        if (params.slidesPerView === 'auto') {
2053            var slidesOffset = 0;
2054            _this.activeIndex = _this.slidesGrid.indexOf(-position);
2055            if (_this.activeIndex < 0) {
2056                for (i = 0; i < _this.slidesGrid.length - 1; i++) {
2057                    if (-position > _this.slidesGrid[i] && -position < _this.slidesGrid[i + 1]) {
2058                        break;
2059                    }
2060                }
2061                var leftDistance = Math.abs(_this.slidesGrid[i] + position);
2062                var rightDistance = Math.abs(_this.slidesGrid[i + 1] + position);
2063                if (leftDistance <= rightDistance) _this.activeIndex = i;
2064                else _this.activeIndex = i + 1;
2065            }
2066        }
2067        else {
2068            _this.activeIndex = Math[params.visibilityFullFit ? 'ceil' : 'round'](-position / slideSize);
2069        }
2070
2071        if (_this.activeIndex === _this.slides.length) _this.activeIndex = _this.slides.length - 1;
2072        if (_this.activeIndex < 0) _this.activeIndex = 0;
2073
2074        // Check for slide
2075        if (!_this.slides[_this.activeIndex]) return;
2076
2077        // Calc Visible slides
2078        _this.calcVisibleSlides(position);
2079
2080        // Mark visible and active slides with additonal classes
2081        if (_this.support.classList) {
2082            var slide;
2083            for (i = 0; i < _this.slides.length; i++) {
2084                slide = _this.slides[i];
2085                slide.classList.remove(params.slideActiveClass);
2086                if (_this.visibleSlides.indexOf(slide) >= 0) {
2087                    slide.classList.add(params.slideVisibleClass);
2088                } else {
2089                    slide.classList.remove(params.slideVisibleClass);
2090                }
2091            }
2092            _this.slides[_this.activeIndex].classList.add(params.slideActiveClass);
2093        } else {
2094            var activeClassRegexp = new RegExp('\\s*' + params.slideActiveClass);
2095            var inViewClassRegexp = new RegExp('\\s*' + params.slideVisibleClass);
2096
2097            for (i = 0; i < _this.slides.length; i++) {
2098                _this.slides[i].className = _this.slides[i].className.replace(activeClassRegexp, '').replace(inViewClassRegexp, '');
2099                if (_this.visibleSlides.indexOf(_this.slides[i]) >= 0) {
2100                    _this.slides[i].className += ' ' + params.slideVisibleClass;
2101                }
2102            }
2103            _this.slides[_this.activeIndex].className += ' ' + params.slideActiveClass;
2104        }
2105
2106        //Update loop index
2107        if (params.loop) {
2108            var ls = _this.loopedSlides;
2109            _this.activeLoopIndex = _this.activeIndex - ls;
2110            if (_this.activeLoopIndex >= _this.slides.length - ls * 2) {
2111                _this.activeLoopIndex = _this.slides.length - ls * 2 - _this.activeLoopIndex;
2112            }
2113            if (_this.activeLoopIndex < 0) {
2114                _this.activeLoopIndex = _this.slides.length - ls * 2 + _this.activeLoopIndex;
2115            }
2116            if (_this.activeLoopIndex < 0) _this.activeLoopIndex = 0;
2117        }
2118        else {
2119            _this.activeLoopIndex = _this.activeIndex;
2120        }
2121        //Update Pagination
2122        if (params.pagination) {
2123            _this.updatePagination(position);
2124        }
2125    };
2126    /*==================================================
2127        Pagination
2128    ====================================================*/
2129    _this.createPagination = function (firstInit) {
2130        if (params.paginationClickable && _this.paginationButtons) {
2131            removePaginationEvents();
2132        }
2133        _this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0];
2134        if (params.createPagination) {
2135            var paginationHTML = '';
2136            var numOfSlides = _this.slides.length;
2137            var numOfButtons = numOfSlides;
2138            if (params.loop) numOfButtons -= _this.loopedSlides * 2;
2139            for (var i = 0; i < numOfButtons; i++) {
2140                paginationHTML += '<' + params.paginationElement + ' class="' + params.paginationElementClass + '"></' + params.paginationElement + '>';
2141            }
2142            _this.paginationContainer.innerHTML = paginationHTML;
2143        }
2144        _this.paginationButtons = $$('.' + params.paginationElementClass, _this.paginationContainer);
2145        if (!firstInit) _this.updatePagination();
2146        _this.callPlugins('onCreatePagination');
2147        if (params.paginationClickable) {
2148            addPaginationEvents();
2149        }
2150    };
2151    function removePaginationEvents() {
2152        var pagers = _this.paginationButtons;
2153        if (pagers) {
2154            for (var i = 0; i < pagers.length; i++) {
2155                _this.h.removeEventListener(pagers[i], 'click', paginationClick);
2156            }
2157        }
2158    }
2159    function addPaginationEvents() {
2160        var pagers = _this.paginationButtons;
2161        if (pagers) {
2162            for (var i = 0; i < pagers.length; i++) {
2163                _this.h.addEventListener(pagers[i], 'click', paginationClick);
2164            }
2165        }
2166    }
2167    function paginationClick(e) {
2168        var index;
2169        var target = e.target || e.srcElement;
2170        var pagers = _this.paginationButtons;
2171        for (var i = 0; i < pagers.length; i++) {
2172            if (target === pagers[i]) index = i;
2173        }
2174        if (params.autoplay) _this.stopAutoplay(true);
2175        _this.swipeTo(index);
2176    }
2177    _this.updatePagination = function (position) {
2178        if (!params.pagination) return;
2179        if (_this.slides.length < 1) return;
2180        var activePagers = $$('.' + params.paginationActiveClass, _this.paginationContainer);
2181        if (!activePagers) return;
2182
2183        //Reset all Buttons' class to not active
2184        var pagers = _this.paginationButtons;
2185        if (pagers.length === 0) return;
2186        for (var i = 0; i < pagers.length; i++) {
2187            pagers[i].className = params.paginationElementClass;
2188        }
2189
2190        var indexOffset = params.loop ? _this.loopedSlides : 0;
2191        if (params.paginationAsRange) {
2192            if (!_this.visibleSlides) _this.calcVisibleSlides(position);
2193            //Get Visible Indexes
2194            var visibleIndexes = [];
2195            var j; // lopp index - avoid JSHint W004 / W038
2196            for (j = 0; j < _this.visibleSlides.length; j++) {
2197                var visIndex = _this.slides.indexOf(_this.visibleSlides[j]) - indexOffset;
2198
2199                if (params.loop && visIndex < 0) {
2200                    visIndex = _this.slides.length - _this.loopedSlides * 2 + visIndex;
2201                }
2202                if (params.loop && visIndex >= _this.slides.length - _this.loopedSlides * 2) {
2203                    visIndex = _this.slides.length - _this.loopedSlides * 2 - visIndex;
2204                    visIndex = Math.abs(visIndex);
2205                }
2206                visibleIndexes.push(visIndex);
2207            }
2208
2209            for (j = 0; j < visibleIndexes.length; j++) {
2210                if (pagers[visibleIndexes[j]]) pagers[visibleIndexes[j]].className += ' ' + params.paginationVisibleClass;
2211            }
2212
2213            if (params.loop) {
2214                if (pagers[_this.activeLoopIndex] !== undefined) {
2215                    pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass;
2216                }
2217            }
2218            else {
2219                if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass;
2220            }
2221        }
2222        else {
2223            if (params.loop) {
2224                if (pagers[_this.activeLoopIndex]) pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
2225            }
2226            else {
2227                if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
2228            }
2229        }
2230    };
2231    _this.calcVisibleSlides = function (position) {
2232        var visibleSlides = [];
2233        var _slideLeft = 0, _slideSize = 0, _slideRight = 0;
2234        if (isH && _this.wrapperLeft > 0) position = position + _this.wrapperLeft;
2235        if (!isH && _this.wrapperTop > 0) position = position + _this.wrapperTop;
2236
2237        for (var i = 0; i < _this.slides.length; i++) {
2238            _slideLeft += _slideSize;
2239            if (params.slidesPerView === 'auto')
2240                _slideSize  = isH ? _this.h.getWidth(_this.slides[i], true, params.roundLengths) : _this.h.getHeight(_this.slides[i], true, params.roundLengths);
2241            else _slideSize = slideSize;
2242
2243            _slideRight = _slideLeft + _slideSize;
2244            var isVisibile = false;
2245            if (params.visibilityFullFit) {
2246                if (_slideLeft >= -position && _slideRight <= -position + containerSize) isVisibile = true;
2247                if (_slideLeft <= -position && _slideRight >= -position + containerSize) isVisibile = true;
2248            }
2249            else {
2250                if (_slideRight > -position && _slideRight <= ((-position + containerSize))) isVisibile = true;
2251                if (_slideLeft >= -position && _slideLeft < ((-position + containerSize))) isVisibile = true;
2252                if (_slideLeft < -position && _slideRight > ((-position + containerSize))) isVisibile = true;
2253            }
2254
2255            if (isVisibile) visibleSlides.push(_this.slides[i]);
2256
2257        }
2258        if (visibleSlides.length === 0) visibleSlides = [_this.slides[_this.activeIndex]];
2259
2260        _this.visibleSlides = visibleSlides;
2261    };
2262
2263    /*==========================================
2264        Autoplay
2265    ============================================*/
2266    var autoplayTimeoutId, autoplayIntervalId;
2267    _this.startAutoplay = function () {
2268        if (_this.support.transitions) {
2269            if (typeof autoplayTimeoutId !== 'undefined') return false;
2270            if (!params.autoplay) return;
2271            _this.callPlugins('onAutoplayStart');
2272            if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this);
2273            autoplay();
2274        }
2275        else {
2276            if (typeof autoplayIntervalId !== 'undefined') return false;
2277            if (!params.autoplay) return;
2278            _this.callPlugins('onAutoplayStart');
2279            if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this);
2280            autoplayIntervalId = setInterval(function () {
2281                if (params.loop) {
2282                    _this.fixLoop();
2283                    _this.swipeNext(true, true);
2284                }
2285                else if (!_this.swipeNext(true, true)) {
2286                    if (!params.autoplayStopOnLast) _this.swipeTo(0);
2287                    else {
2288                        clearInterval(autoplayIntervalId);
2289                        autoplayIntervalId = undefined;
2290                    }
2291                }
2292            }, params.autoplay);
2293        }
2294    };
2295    _this.stopAutoplay = function (internal) {
2296        if (_this.support.transitions) {
2297            if (!autoplayTimeoutId) return;
2298            if (autoplayTimeoutId) clearTimeout(autoplayTimeoutId);
2299            autoplayTimeoutId = undefined;
2300            if (internal && !params.autoplayDisableOnInteraction) {
2301                _this.wrapperTransitionEnd(function () {
2302                    autoplay();
2303                });
2304            }
2305            _this.callPlugins('onAutoplayStop');
2306            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
2307        }
2308        else {
2309            if (autoplayIntervalId) clearInterval(autoplayIntervalId);
2310            autoplayIntervalId = undefined;
2311            _this.callPlugins('onAutoplayStop');
2312            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
2313        }
2314    };
2315    function autoplay() {
2316        autoplayTimeoutId = setTimeout(function () {
2317            if (params.loop) {
2318                _this.fixLoop();
2319                _this.swipeNext(true, true);
2320            }
2321            else if (!_this.swipeNext(true, true)) {
2322                if (!params.autoplayStopOnLast) _this.swipeTo(0);
2323                else {
2324                    clearTimeout(autoplayTimeoutId);
2325                    autoplayTimeoutId = undefined;
2326                }
2327            }
2328            _this.wrapperTransitionEnd(function () {
2329                if (typeof autoplayTimeoutId !== 'undefined') autoplay();
2330            });
2331        }, params.autoplay);
2332    }
2333    /*==================================================
2334        Loop
2335    ====================================================*/
2336    _this.loopCreated = false;
2337    _this.removeLoopedSlides = function () {
2338        if (_this.loopCreated) {
2339            for (var i = 0; i < _this.slides.length; i++) {
2340                if (_this.slides[i].getData('looped') === true) _this.wrapper.removeChild(_this.slides[i]);
2341            }
2342        }
2343    };
2344
2345    _this.createLoop = function () {
2346        if (_this.slides.length === 0) return;
2347        if (params.slidesPerView === 'auto') {
2348            _this.loopedSlides = params.loopedSlides || 1;
2349        }
2350        else {
2351            _this.loopedSlides = params.slidesPerView + params.loopAdditionalSlides;
2352        }
2353
2354        if (_this.loopedSlides > _this.slides.length) {
2355            _this.loopedSlides = _this.slides.length;
2356        }
2357
2358        var slideFirstHTML = '',
2359            slideLastHTML = '',
2360            i;
2361        var slidesSetFullHTML = '';
2362        /**
2363                loopedSlides is too large if loopAdditionalSlides are set.
2364                Need to divide the slides by maximum number of slides existing.
2365
2366                @author        Tomaz Lovrec <[email protected]>
2367        */
2368        var numSlides = _this.slides.length;
2369        var fullSlideSets = Math.floor(_this.loopedSlides / numSlides);
2370        var remainderSlides = _this.loopedSlides % numSlides;
2371        // assemble full sets of slides
2372        for (i = 0; i < (fullSlideSets * numSlides); i++) {
2373            var j = i;
2374            if (i >= numSlides) {
2375                var over = Math.floor(i / numSlides);
2376                j = i - (numSlides * over);
2377            }
2378            slidesSetFullHTML += _this.slides[j].outerHTML;
2379        }
2380        // assemble remainder slides
2381        // assemble remainder appended to existing slides
2382        for (i = 0; i < remainderSlides;i++) {
2383            slideLastHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
2384        }
2385        // assemble slides that get preppended to existing slides
2386        for (i = numSlides - remainderSlides; i < numSlides;i++) {
2387            slideFirstHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
2388        }
2389        // assemble all slides
2390        var slides = slideFirstHTML + slidesSetFullHTML + wrapper.innerHTML + slidesSetFullHTML + slideLastHTML;
2391        // set the slides
2392        wrapper.innerHTML = slides;
2393
2394        _this.loopCreated = true;
2395        _this.calcSlides();
2396
2397        //Update Looped Slides with special class
2398        for (i = 0; i < _this.slides.length; i++) {
2399            if (i < _this.loopedSlides || i >= _this.slides.length - _this.loopedSlides) _this.slides[i].setData('looped', true);
2400        }
2401        _this.callPlugins('onCreateLoop');
2402
2403    };
2404
2405    _this.fixLoop = function () {
2406        var newIndex;
2407        //Fix For Negative Oversliding
2408        if (_this.activeIndex < _this.loopedSlides) {
2409            newIndex = _this.slides.length - _this.loopedSlides * 3 + _this.activeIndex;
2410            _this.swipeTo(newIndex, 0, false);
2411        }
2412        //Fix For Positive Oversliding
2413        else if ((params.slidesPerView === 'auto' && _this.activeIndex >= _this.loopedSlides * 2) || (_this.activeIndex > _this.slides.length - params.slidesPerView * 2)) {
2414            newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides;
2415            _this.swipeTo(newIndex, 0, false);
2416        }
2417    };
2418
2419    /*==================================================
2420        Slides Loader
2421    ====================================================*/
2422    _this.loadSlides = function () {
2423        var slidesHTML = '';
2424        _this.activeLoaderIndex = 0;
2425        var slides = params.loader.slides;
2426        var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView * (1 + params.loader.surroundGroups);
2427        for (var i = 0; i < slidesToLoad; i++) {
2428            if (params.loader.slidesHTMLType === 'outer') slidesHTML += slides[i];
2429            else {
2430                slidesHTML += '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
2431            }
2432        }
2433        _this.wrapper.innerHTML = slidesHTML;
2434        _this.calcSlides(true);
2435        //Add permanent transitionEnd callback
2436        if (!params.loader.loadAllSlides) {
2437            _this.wrapperTransitionEnd(_this.reloadSlides, true);
2438        }
2439    };
2440
2441    _this.reloadSlides = function () {
2442        var slides = params.loader.slides;
2443        var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'), 10);
2444        if (newActiveIndex < 0 || newActiveIndex > slides.length - 1) return; //<-- Exit
2445        _this.activeLoaderIndex = newActiveIndex;
2446        var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView * params.loader.surroundGroups);
2447        var lastIndex = Math.min(newActiveIndex + params.slidesPerView * (1 + params.loader.surroundGroups) - 1, slides.length - 1);
2448        //Update Transforms
2449        if (newActiveIndex > 0) {
2450            var newTransform = -slideSize * (newActiveIndex - firstIndex);
2451            _this.setWrapperTranslate(newTransform);
2452            _this.setWrapperTransition(0);
2453        }
2454        var i; // loop index
2455        //New Slides
2456        if (params.loader.logic === 'reload') {
2457            _this.wrapper.innerHTML = '';
2458            var slidesHTML = '';
2459            for (i = firstIndex; i <= lastIndex; i++) {
2460                slidesHTML += params.loader.slidesHTMLType === 'outer' ? slides[i] : '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
2461            }
2462            _this.wrapper.innerHTML = slidesHTML;
2463        }
2464        else {
2465            var minExistIndex = 1000;
2466            var maxExistIndex = 0;
2467
2468            for (i = 0; i < _this.slides.length; i++) {
2469                var index = _this.slides[i].data('swiperindex');
2470                if (index < firstIndex || index > lastIndex) {
2471                    _this.wrapper.removeChild(_this.slides[i]);
2472                }
2473                else {
2474                    minExistIndex = Math.min(index, minExistIndex);
2475                    maxExistIndex = Math.max(index, maxExistIndex);
2476                }
2477            }
2478            for (i = firstIndex; i <= lastIndex; i++) {
2479                var newSlide;
2480                if (i < minExistIndex) {
2481                    newSlide = document.createElement(params.slideElement);
2482                    newSlide.className = params.slideClass;
2483                    newSlide.setAttribute('data-swiperindex', i);
2484                    newSlide.innerHTML = slides[i];
2485                    _this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild);
2486                }
2487                if (i > maxExistIndex) {
2488                    newSlide = document.createElement(params.slideElement);
2489                    newSlide.className = params.slideClass;
2490                    newSlide.setAttribute('data-swiperindex', i);
2491                    newSlide.innerHTML = slides[i];
2492                    _this.wrapper.appendChild(newSlide);
2493                }
2494            }
2495        }
2496        //reInit
2497        _this.reInit(true);
2498    };
2499
2500    /*==================================================
2501        Make Swiper
2502    ====================================================*/
2503    function makeSwiper() {
2504        _this.calcSlides();
2505        if (params.loader.slides.length > 0 && _this.slides.length === 0) {
2506            _this.loadSlides();
2507        }
2508        if (params.loop) {
2509            _this.createLoop();
2510        }
2511        _this.init();
2512        initEvents();
2513        if (params.pagination) {
2514            _this.createPagination(true);
2515        }
2516
2517        if (params.loop || params.initialSlide > 0) {
2518            _this.swipeTo(params.initialSlide, 0, false);
2519        }
2520        else {
2521            _this.updateActiveSlide(0);
2522        }
2523        if (params.autoplay) {
2524            _this.startAutoplay();
2525        }
2526        /**
2527         * Set center slide index.
2528         *
2529         * @author        Tomaz Lovrec <[email protected]>
2530         */
2531        _this.centerIndex = _this.activeIndex;
2532
2533        // Callbacks
2534        if (params.onSwiperCreated) _this.fireCallback(params.onSwiperCreated, _this);
2535        _this.callPlugins('onSwiperCreated');
2536    }
2537
2538    makeSwiper();
2539};
2540
2541Swiper.prototype = {
2542    plugins : {},
2543
2544    /*==================================================
2545        Wrapper Operations
2546    ====================================================*/
2547    wrapperTransitionEnd : function (callback, permanent) {
2548        'use strict';
2549        var a = this,
2550            el = a.wrapper,
2551            events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
2552            i;
2553
2554        function fireCallBack(e) {
2555            if (e.target !== el) return;
2556            callback(a);
2557            if (a.params.queueEndCallbacks) a._queueEndCallbacks = false;
2558            if (!permanent) {
2559                for (i = 0; i < events.length; i++) {
2560                    a.h.removeEventListener(el, events[i], fireCallBack);
2561                }
2562            }
2563        }
2564
2565        if (callback) {
2566            for (i = 0; i < events.length; i++) {
2567                a.h.addEventListener(el, events[i], fireCallBack);
2568            }
2569        }
2570    },
2571
2572    getWrapperTranslate : function (axis) {
2573        'use strict';
2574        var el = this.wrapper,
2575            matrix, curTransform, curStyle, transformMatrix;
2576
2577        // automatic axis detection
2578        if (typeof axis === 'undefined') {
2579            axis = this.params.mode === 'horizontal' ? 'x' : 'y';
2580        }
2581
2582        if (this.support.transforms && this.params.useCSS3Transforms) {
2583            curStyle = window.getComputedStyle(el, null);
2584            if (window.WebKitCSSMatrix) {
2585                // Some old versions of Webkit choke when 'none' is passed; pass
2586                // empty string instead in this case
2587                transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);
2588            }
2589            else {
2590                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2591                matrix = transformMatrix.toString().split(',');
2592            }
2593
2594            if (axis === 'x') {
2595                //Latest Chrome and webkits Fix
2596                if (window.WebKitCSSMatrix)
2597                    curTransform = transformMatrix.m41;
2598                //Crazy IE10 Matrix
2599                else if (matrix.length === 16)
2600                    curTransform = parseFloat(matrix[12]);
2601                //Normal Browsers
2602                else
2603                    curTransform = parseFloat(matrix[4]);
2604            }
2605            if (axis === 'y') {
2606                //Latest Chrome and webkits Fix
2607                if (window.WebKitCSSMatrix)
2608                    curTransform = transformMatrix.m42;
2609                //Crazy IE10 Matrix
2610                else if (matrix.length === 16)
2611                    curTransform = parseFloat(matrix[13]);
2612                //Normal Browsers
2613                else
2614                    curTransform = parseFloat(matrix[5]);
2615            }
2616        }
2617        else {
2618            if (axis === 'x') curTransform = parseFloat(el.style.left, 10) || 0;
2619            if (axis === 'y') curTransform = parseFloat(el.style.top, 10) || 0;
2620        }
2621        return curTransform || 0;
2622    },
2623
2624    setWrapperTranslate : function (x, y, z) {
2625        'use strict';
2626        var es = this.wrapper.style,
2627            coords = {x: 0, y: 0, z: 0},
2628            translate;
2629
2630        // passed all coordinates
2631        if (arguments.length === 3) {
2632            coords.x = x;
2633            coords.y = y;
2634            coords.z = z;
2635        }
2636
2637        // passed one coordinate and optional axis
2638        else {
2639            if (typeof y === 'undefined') {
2640                y = this.params.mode === 'horizontal' ? 'x' : 'y';
2641            }
2642            coords[y] = x;
2643        }
2644
2645        if (this.support.transforms && this.params.useCSS3Transforms) {
2646            translate = this.support.transforms3d ? 'translate3d(' + coords.x + 'px, ' + coords.y + 'px, ' + coords.z + 'px)' : 'translate(' + coords.x + 'px, ' + coords.y + 'px)';
2647            es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = translate;
2648        }
2649        else {
2650            es.left = coords.x + 'px';
2651            es.top  = coords.y + 'px';
2652        }
2653        this.callPlugins('onSetWrapperTransform', coords);
2654        if (this.params.onSetWrapperTransform) this.fireCallback(this.params.onSetWrapperTransform, this, coords);
2655    },
2656
2657    setWrapperTransition : function (duration) {
2658        'use strict';
2659        var es = this.wrapper.style;
2660        es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = (duration / 1000) + 's';
2661        this.callPlugins('onSetWrapperTransition', {duration: duration});
2662        if (this.params.onSetWrapperTransition) this.fireCallback(this.params.onSetWrapperTransition, this, duration);
2663
2664    },
2665
2666    /*==================================================
2667        Helpers
2668    ====================================================*/
2669    h : {
2670        getWidth: function (el, outer, round) {
2671            'use strict';
2672            var width = window.getComputedStyle(el, null).getPropertyValue('width');
2673            var returnWidth = parseFloat(width);
2674            //IE Fixes
2675            if (isNaN(returnWidth) || width.indexOf('%') > 0 || returnWidth < 0) {
2676                returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
2677            }
2678            if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
2679            if (round) return Math.ceil(returnWidth);
2680            else return returnWidth;
2681        },
2682        getHeight: function (el, outer, round) {
2683            'use strict';
2684            if (outer) return el.offsetHeight;
2685
2686            var height = window.getComputedStyle(el, null).getPropertyValue('height');
2687            var returnHeight = parseFloat(height);
2688            //IE Fixes
2689            if (isNaN(returnHeight) || height.indexOf('%') > 0 || returnHeight < 0) {
2690                returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
2691            }
2692            if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
2693            if (round) return Math.ceil(returnHeight);
2694            else return returnHeight;
2695        },
2696        getOffset: function (el) {
2697            'use strict';
2698            var box = el.getBoundingClientRect();
2699            var body = document.body;
2700            var clientTop  = el.clientTop  || body.clientTop  || 0;
2701            var clientLeft = el.clientLeft || body.clientLeft || 0;
2702            var scrollTop  = window.pageYOffset || el.scrollTop;
2703            var scrollLeft = window.pageXOffset || el.scrollLeft;
2704            if (document.documentElement && !window.pageYOffset) {
2705                //IE7-8
2706                scrollTop  = document.documentElement.scrollTop;
2707                scrollLeft = document.documentElement.scrollLeft;
2708            }
2709            return {
2710                top: box.top  + scrollTop  - clientTop,
2711                left: box.left + scrollLeft - clientLeft
2712            };
2713        },
2714        windowWidth : function () {
2715            'use strict';
2716            if (window.innerWidth) return window.innerWidth;
2717            else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
2718        },
2719        windowHeight : function () {
2720            'use strict';
2721            if (window.innerHeight) return window.innerHeight;
2722            else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
2723        },
2724        windowScroll : function () {
2725            'use strict';
2726            if (typeof pageYOffset !== 'undefined') {
2727                return {
2728                    left: window.pageXOffset,
2729                    top: window.pageYOffset
2730                };
2731            }
2732            else if (document.documentElement) {
2733                return {
2734                    left: document.documentElement.scrollLeft,
2735                    top: document.documentElement.scrollTop
2736                };
2737            }
2738        },
2739
2740        addEventListener : function (el, event, listener, useCapture) {
2741            'use strict';
2742            if (typeof useCapture === 'undefined') {
2743                useCapture = false;
2744            }
2745
2746            if (el.addEventListener) {
2747                el.addEventListener(event, listener, useCapture);
2748            }
2749            else if (el.attachEvent) {
2750                el.attachEvent('on' + event, listener);
2751            }
2752        },
2753
2754        removeEventListener : function (el, event, listener, useCapture) {
2755            'use strict';
2756            if (typeof useCapture === 'undefined') {
2757                useCapture = false;
2758            }
2759
2760            if (el.removeEventListener) {
2761                el.removeEventListener(event, listener, useCapture);
2762            }
2763            else if (el.detachEvent) {
2764                el.detachEvent('on' + event, listener);
2765            }
2766        }
2767    },
2768    setTransform : function (el, transform) {
2769        'use strict';
2770        var es = el.style;
2771        es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform;
2772    },
2773    setTranslate : function (el, translate) {
2774        'use strict';
2775        var es = el.style;
2776        var pos = {
2777            x : translate.x || 0,
2778            y : translate.y || 0,
2779            z : translate.z || 0
2780        };
2781        var transformString = this.support.transforms3d ? 'translate3d(' + (pos.x) + 'px,' + (pos.y) + 'px,' + (pos.z) + 'px)' : 'translate(' + (pos.x) + 'px,' + (pos.y) + 'px)';
2782        es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
2783        if (!this.support.transforms) {
2784            es.left = pos.x + 'px';
2785            es.top = pos.y + 'px';
2786        }
2787    },
2788    setTransition : function (el, duration) {
2789        'use strict';
2790        var es = el.style;
2791        es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration + 'ms';
2792    },
2793    /*==================================================
2794        Feature Detection
2795    ====================================================*/
2796    support: {
2797
2798        touch : (window.Modernizr && Modernizr.touch === true) || (function () {
2799            'use strict';
2800            return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
2801        })(),
2802
2803        transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
2804            'use strict';
2805            var div = document.createElement('div').style;
2806            return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
2807        })(),
2808
2809        transforms : (window.Modernizr && Modernizr.csstransforms === true) || (function () {
2810            'use strict';
2811            var div = document.createElement('div').style;
2812            return ('transform' in div || 'WebkitTransform' in div || 'MozTransform' in div || 'msTransform' in div || 'MsTransform' in div || 'OTransform' in div);
2813        })(),
2814
2815        transitions : (window.Modernizr && Modernizr.csstransitions === true) || (function () {
2816            'use strict';
2817            var div = document.createElement('div').style;
2818            return ('transition' in div || 'WebkitTransition' in div || 'MozTransition' in div || 'msTransition' in div || 'MsTransition' in div || 'OTransition' in div);
2819        })(),
2820
2821        classList : (function () {
2822            'use strict';
2823            var div = document.createElement('div');
2824            return 'classList' in div;
2825        })()
2826    },
2827
2828    browser : {
2829
2830        ie8 : (function () {
2831            'use strict';
2832            var rv = -1; // Return value assumes failure.
2833            if (navigator.appName === 'Microsoft Internet Explorer') {
2834                var ua = navigator.userAgent;
2835                var re = new RegExp(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
2836                if (re.exec(ua) !== null)
2837                    rv = parseFloat(RegExp.$1);
2838            }
2839            return rv !== -1 && rv < 9;
2840        })(),
2841
2842        ie10 : window.navigator.msPointerEnabled,
2843        ie11 : window.navigator.pointerEnabled
2844    }
2845};
2846
2847/*=========================
2848  jQuery & Zepto Plugins
2849  ===========================*/
2850if (window.jQuery || window.Zepto) {
2851    (function ($) {
2852        'use strict';
2853        $.fn.swiper = function (params) {
2854            var firstInstance;
2855            this.each(function (i) {
2856                var that = $(this);
2857                var s = new Swiper(that[0], params);
2858                if (!i) firstInstance = s;
2859                that.data('swiper', s);
2860            });
2861            return firstInstance;
2862        };
2863    })(window.jQuery || window.Zepto);
2864}
2865
2866// component
2867if (typeof(module) !== 'undefined')
2868{
2869    module.exports = Swiper;
2870}
2871
2872// requirejs support
2873if (typeof define === 'function' && define.amd) {
2874    define([], function () {
2875        'use strict';
2876        return Swiper;
2877    });
2878}

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.