PageSourceSearch

http://www.turismoitalianews.it/modules/mod_sj_k2_extra_slider/assets/js/owl.carousel.js

js turismoitalianews.it collected 2026-09-26 14:48:46 UTC 96,787 bytes, 3,115 lines download raw bytes

1/**
2 * Owl carousel
3 * @version 2.0.0
4 * @author Bartosz Wojciechowski
5 * @license The MIT License (MIT)
6 * @todo Lazy Load Icon
7 * @todo prevent animationend bubling
8 * @todo itemsScaleUp
9 * @todo Test Zepto
10 * @todo stagePadding calculate wrong active classes
11 */
12;
13(function ($, window, document, undefined) {
14
15    var drag, state, e;
16
17    /**
18     * Template for status information about drag and touch events.
19     * @private
20     */
21    drag = {
22        start: 0,
23        startX: 0,
24        startY: 0,
25        current: 0,
26        currentX: 0,
27        currentY: 0,
28        offsetX: 0,
29        offsetY: 0,
30        distance: null,
31        startTime: 0,
32        endTime: 0,
33        updatedX: 0,
34        targetEl: null
35    };
36
37    /**
38     * Template for some status informations.
39     * @private
40     */
41    state = {
42        isTouch: false,
43        isScrolling: false,
44        isSwiping: false,
45        direction: false,
46        inMotion: false
47    };
48
49    /**
50     * Event functions references.
51     * @private
52     */
53    e = {
54        _onDragStart: null,
55        _onDragMove: null,
56        _onDragEnd: null,
57        _transitionEnd: null,
58        _resizer: null,
59        _responsiveCall: null,
60        _goToLoop: null,
61        _checkVisibile: null
62    };
63
64    /**
65     * Creates a carousel.
66     * @class The Owl Carousel.
67     * @public
68     * @param {HTMLElement|jQuery} element - The element to create the carousel for.
69     * @param {Object} [options] - The options
70     */
71    function Owl(element, options) {
72
73        /**
74         * Current settings for the carousel.
75         * @public
76         */
77        this.settings = null;
78
79        /**
80         * Current options set by the caller including defaults.
81         * @public
82         */
83        this.options = $.extend({}, Owl.Defaults, options);
84
85        /**
86         * Plugin element.
87         * @public
88         */
89        this.$element = $(element);
90
91        /**
92         * Caches informations about drag and touch events.
93         */
94        this.drag = $.extend({}, drag);
95
96        /**
97         * Caches some status informations.
98         * @protected
99         */
100        this.state = $.extend({}, state);
101
102        /**
103         * @protected
104         * @todo Must be documented
105         */
106        this.e = $.extend({}, e);
107
108        /**
109         * References to the running plugins of this carousel.
110         * @protected
111         */
112        this._plugins = {};
113
114        /**
115         * Currently suppressed events to prevent them from beeing retriggered.
116         * @protected
117         */
118        this._supress = {};
119
120        /**
121         * Absolute current position.
122         * @protected
123         */
124        this._current = null;
125
126        /**
127         * Animation speed in milliseconds.
128         * @protected
129         */
130        this._speed = null;
131
132        /**
133         * Coordinates of all items in pixel.
134         * @todo The name of this member is missleading.
135         * @protected
136         */
137        this._coordinates = [];
138
139        /**
140         * Current breakpoint.
141         * @todo Real media queries would be nice.
142         * @protected
143         */
144        this._breakpoint = null;
145
146        /**
147         * Current width of the plugin element.
148         */
149        this._width = null;
150
151        /**
152         * All real items.
153         * @protected
154         */
155        this._items = [];
156
157        /**
158         * All cloned items.
159         * @protected
160         */
161        this._clones = [];
162
163        /**
164         * Merge values of all items.
165         * @todo Maybe this could be part of a plugin.
166         * @protected
167         */
168        this._mergers = [];
169
170        /**
171         * Invalidated parts within the update process.
172         * @protected
173         */
174        this._invalidated = {};
175
176        /**
177         * Ordered list of workers for the update process.
178         * @protected
179         */
180        this._pipe = [];
181
182        $.each(Owl.Plugins, $.proxy(function (key, plugin) {
183            this._plugins[key[0].toLowerCase() + key.slice(1)]
184                = new plugin(this);
185        }, this));
186
187        $.each(Owl.Pipe, $.proxy(function (priority, worker) {
188            this._pipe.push({
189                'filter': worker.filter,
190                'run': $.proxy(worker.run, this)
191            });
192        }, this));
193
194        this.setup();
195        this.initialize();
196    }
197
198    /**
199     * Default options for the carousel.
200     * @public
201     */
202    Owl.Defaults = {
203        items: 3,
204        loop: false,
205        center: false,
206
207        mouseDrag: true,
208        touchDrag: true,
209        pullDrag: true,
210        freeDrag: false,
211
212        margin: 0,
213        stagePadding: 0,
214
215        merge: false,
216        mergeFit: true,
217        autoWidth: false,
218
219        startPosition: 0,
220        rtl: false,
221
222        smartSpeed: 250,
223        fluidSpeed: false,
224        dragEndSpeed: false,
225
226        responsive: {},
227        responsiveRefreshRate: 200,
228        responsiveBaseElement: window,
229        responsiveClass: false,
230
231        fallbackEasing: 'swing',
232
233        info: false,
234
235        nestedItemSelector: false,
236        itemElement: 'div',
237        stageElement: 'div',
238
239        // Classes and Names
240        themeClass: 'owl-theme',
241        baseClass: 'owl-carousel',
242        itemClass: 'owl-item',
243        centerClass: 'center',
244        activeClass: 'active'
245    };
246
247    /**
248     * Enumeration for width.
249     * @public
250     * @readonly
251     * @enum {String}
252     */
253    Owl.Width = {
254        Default: 'default',
255        Inner: 'inner',
256        Outer: 'outer'
257    };
258
259    /**
260     * Contains all registered plugins.
261     * @public
262     */
263    Owl.Plugins = {};
264
265    /**
266     * Update pipe.
267     */
268    Owl.Pipe = [
269        {
270            filter: [ 'width', 'items', 'settings' ],
271            run: function (cache) {
272                cache.current = this._items && this._items[this.relative(this._current)];
273            }
274        },
275        {
276            filter: [ 'items', 'settings' ],
277            run: function () {
278                var cached = this._clones,
279                    clones = this.$stage.children('.cloned');
280
281                if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) {
282                    this.$stage.children('.cloned').remove();
283                    this._clones = [];
284                }
285            }
286        },
287        {
288            filter: [ 'items', 'settings' ],
289            run: function () {
290                var i, n,
291                    clones = this._clones,
292                    items = this._items,
293                    delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0;
294
295                if(items.length <=1 )
296                    return;
297                for (i = 0, n = Math.abs(delta / 2); i < n; i++) {
298                    if (delta > 0) {
299                        this.$stage.children().eq(items.length + clones.length - 1).remove();
300                        clones.pop();
301                        this.$stage.children().eq(0).remove();
302                        clones.pop();
303                    } else {
304                        clones.push(clones.length / 2);
305                        this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned'));
306                        clones.push(items.length - 1 - (clones.length - 1) / 2);
307                        this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned'));
308                    }
309                }
310            }
311        },
312        {
313            filter: [ 'width', 'items', 'settings' ],
314            run: function () {
315                var rtl = (this.settings.rtl ? 1 : -1),
316                    width = (this.width() / this.settings.items).toFixed(3),
317                    coordinate = 0, merge, i, n;
318
319                this._coordinates = [];
320                for (i = 0, n = this._clones.length + this._items.length; i < n; i++) {
321                    merge = this._mergers[this.relative(i)];
322                    merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge;
323                    coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl;
324
325                    this._coordinates.push(coordinate);
326                }
327            }
328        },
329        {
330            filter: [ 'width', 'items', 'settings' ],
331            run: function () {
332                var i, n, width = (this.width() / this.settings.items).toFixed(3), css = {
333                    'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2,
334                    'padding-left': this.settings.stagePadding || '',
335                    'padding-right': this.settings.stagePadding || ''
336                };
337
338                this.$stage.css(css);
339
340                css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin };
341                css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin;
342
343                if (!this.settings.autoWidth && $.grep(this._mergers,function (v) {
344                    return v > 1
345                }).length > 0) {
346                    for (i = 0, n = this._coordinates.length; i < n; i++) {
347                        css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin;
348                        this.$stage.children().eq(i).css(css);
349                    }
350                } else {
351                    this.$stage.children().css(css);
352                }
353            }
354        },
355        {
356            filter: [ 'width', 'items', 'settings' ],
357            run: function (cache) {
358                cache.current && this.reset(this.$stage.children().index(cache.current));
359            }
360        },
361        {
362            filter: [ 'position' ],
363            run: function () {
364                this.animate(this.coordinates(this._current));
365            }
366        },
367        {
368            filter: [ 'width', 'position', 'items', 'settings' ],
369            run: function () {
370                var rtl = this.settings.rtl ? 1 : -1,
371                    padding = this.settings.stagePadding * 2,
372                    begin = this.coordinates(this.current()) + padding,
373                    end = begin + this.width() * rtl,
374                    inner, outer, matches = [], i, n;
375
376                for (i = 0, n = this._coordinates.length; i < n; i++) {
377                    inner = this._coordinates[i - 1] || 0;
378                    outer = Math.abs(this._coordinates[i]) + padding * rtl;
379
380                    if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
381                        || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
382                        matches.push(i);
383                    }
384                }
385
386                this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass);
387                this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass);
388
389                if (this.settings.center) {
390                    this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass);
391                    this.$stage.children().eq(this.current()).addClass(this.settings.centerClass);
392                }
393            }
394        }
395    ];
396
397    /**
398     * Initializes the carousel.
399     * @protected
400     */
401    Owl.prototype.initialize = function () {
402        this.trigger('initialize');
403
404        this.$element
405            .addClass(this.settings.baseClass)
406            .addClass(this.settings.themeClass)
407            .toggleClass('owl-rtl', this.settings.rtl);
408
409        // check support
410        this.browserSupport();
411
412        if (this.settings.autoWidth && this.state.imagesLoaded !== true) {
413            var imgs, nestedSelector, width;
414            imgs = this.$element.find('img');
415            nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
416            width = this.$element.children(nestedSelector).width();
417
418            if (imgs.length && width <= 0) {
419                this.preloadAutoWidthImages(imgs);
420                return false;
421            }
422        }
423
424        this.$element.addClass('owl-loading');
425
426        // create stage
427        this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>')
428            .wrap('<div class="owl-stage-outer">');
429
430        // append stage
431        this.$element.append(this.$stage.parent());
432
433        // append content
434        this.replace(this.$element.children().not(this.$stage.parent()));
435
436        // set view width
437        this._width = this.$element.width();
438
439        // update view
440        this.refresh();
441
442        this.$element.removeClass('owl-loading').addClass('owl-loaded');
443
444        // attach generic events
445        this.eventsCall();
446
447        // attach generic events
448        this.internalEvents();
449
450        // attach custom control events
451        this.addTriggerableEvents();
452
453        this.trigger('initialized');
454    };
455
456    /**
457     * Setups the current settings.
458     * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
459     * @todo Support for media queries by using `matchMedia` would be nice.
460     * @public
461     */
462    Owl.prototype.setup = function () {
463        var viewport = this.viewport(),
464            overwrites = this.options.responsive,
465            match = -1,
466            settings = null;
467
468        if (!overwrites) {
469            settings = $.extend({}, this.options);
470        } else {
471            $.each(overwrites, function (breakpoint) {
472                if (breakpoint <= viewport && breakpoint > match) {
473                    match = Number(breakpoint);
474                }
475            });
476
477            settings = $.extend({}, this.options, overwrites[match]);
478            delete settings.responsive;
479
480            // responsive class
481            if (settings.responsiveClass) {
482                this.$element.attr('class',function (i, c) {
483                    return c.replace(/\b owl-responsive-\S+/g, '');
484                }).addClass('owl-responsive-' + match);
485            }
486        }
487
488        if (this.settings === null || this._breakpoint !== match) {
489            this.trigger('change', { property: { name: 'settings', value: settings } });
490            this._breakpoint = match;
491            this.settings = settings;
492            this.invalidate('settings');
493            this.trigger('changed', { property: { name: 'settings', value: this.settings } });
494        }
495    };
496
497    /**
498     * Updates option logic if necessery.
499     * @protected
500     */
501    Owl.prototype.optionsLogic = function () {
502        // Toggle Center class
503        this.$element.toggleClass('owl-center', this.settings.center);
504
505        // if items number is less than in body
506        if (this.settings.loop && this._items.length < this.settings.items) {
507            this.settings.loop = false;
508        }
509
510        if (this.settings.autoWidth) {
511            this.settings.stagePadding = false;
512            this.settings.merge = false;
513        }
514    };
515
516    /**
517     * Prepares an item before add.
518     * @todo Rename event parameter `content` to `item`.
519     * @protected
520     * @returns {jQuery|HTMLElement} - The item container.
521     */
522    Owl.prototype.prepare = function (item) {
523        var event = this.trigger('prepare', { content: item });
524
525        if (!event.data) {
526            event.data = $('<' + this.settings.itemElement + '/>')
527                .addClass(this.settings.itemClass).append(item)
528        }
529
530        this.trigger('prepared', { content: event.data });
531
532        return event.data;
533    };
534
535    /**
536     * Updates the view.
537     * @public
538     */
539    Owl.prototype.update = function () {
540        var i = 0,
541            n = this._pipe.length,
542            filter = $.proxy(function (p) {
543                return this[p]
544            }, this._invalidated),
545            cache = {};
546
547        while (i < n) {
548            if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
549                this._pipe[i].run(cache);
550            }
551            i++;
552        }
553
554        this._invalidated = {};
555    };
556
557    /**
558     * Gets the width of the view.
559     * @public
560     * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
561     * @returns {Number} - The width of the view in pixel.
562     */
563    Owl.prototype.width = function (dimension) {
564        dimension = dimension || Owl.Width.Default;
565        switch (dimension) {
566            case Owl.Width.Inner:
567            case Owl.Width.Outer:
568                return this._width;
569            default:
570                return this._width - this.settings.stagePadding * 2 + this.settings.margin;
571        }
572    };
573
574    /**
575     * Refreshes the carousel primarily for adaptive purposes.
576     * @public
577     */
578    Owl.prototype.refresh = function () {
579        if (this._items.length === 0) {
580            return false;
581        }
582
583        var start = new Date().getTime();
584
585        this.trigger('refresh');
586
587        this.setup();
588
589        this.optionsLogic();
590
591        // hide and show methods helps here to set a proper widths,
592        // this prevents scrollbar to be calculated in stage width
593        this.$stage.addClass('owl-refresh');
594
595        this.update();
596
597        this.$stage.removeClass('owl-refresh');
598
599        this.state.orientation = window.orientation;
600
601        this.watchVisibility();
602
603        this.trigger('refreshed');
604    };
605
606    /**
607     * Save internal event references and add event based functions.
608     * @protected
609     */
610    Owl.prototype.eventsCall = function () {
611        // Save events references
612        this.e._onDragStart = $.proxy(function (e) {
613            this.onDragStart(e);
614        }, this);
615        this.e._onDragMove = $.proxy(function (e) {
616            this.onDragMove(e);
617        }, this);
618        this.e._onDragEnd = $.proxy(function (e) {
619            this.onDragEnd(e);
620        }, this);
621        this.e._onResize = $.proxy(function (e) {
622            this.onResize(e);
623        }, this);
624        this.e._transitionEnd = $.proxy(function (e) {
625            this.transitionEnd(e);
626        }, this);
627        this.e._preventClick = $.proxy(function (e) {
628            this.preventClick(e);
629        }, this);
630    };
631
632    /**
633     * Checks window `resize` event.
634     * @protected
635     */
636    Owl.prototype.onThrottledResize = function () {
637        window.clearTimeout(this.resizeTimer);
638        this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate);
639    };
640
641    /**
642     * Checks window `resize` event.
643     * @protected
644     */
645    Owl.prototype.onResize = function () {
646        if (!this._items.length) {
647            return false;
648        }
649
650        if (this._width === this.$element.width()) {
651            return false;
652        }
653
654        if (this.trigger('resize').isDefaultPrevented()) {
655            return false;
656        }
657
658        this._width = this.$element.width();
659
660        this.invalidate('width');
661
662        this.refresh();
663
664        this.trigger('resized');
665    };
666
667    /**
668     * Checks for touch/mouse drag event type and add run event handlers.
669     * @protected
670     */
671    Owl.prototype.eventsRouter = function (event) {
672        var type = event.type;
673
674        if (type === "mousedown" || type === "touchstart") {
675            this.onDragStart(event);
676        } else if (type === "mousemove" || type === "touchmove") {
677            this.onDragMove(event);
678        } else if (type === "mouseup" || type === "touchend") {
679            this.onDragEnd(event);
680        } else if (type === "touchcancel") {
681            this.onDragEnd(event);
682        }
683    };
684
685    /**
686     * Checks for touch/mouse drag options and add necessery event handlers.
687     * @protected
688     */
689    Owl.prototype.internalEvents = function () {
690        var isTouch = isTouchSupport(),
691            isTouchIE = isTouchSupportIE();
692
693        if (this.settings.mouseDrag) {
694            this.$stage.on('mousedown', $.proxy(function (event) {
695                this.eventsRouter(event)
696            }, this));
697            this.$stage.on('dragstart', function () {
698                return false
699            });
700            this.$stage.get(0).onselectstart = function () {
701                return false
702            };
703        } else {
704            this.$element.addClass('owl-text-select-on');
705        }
706
707        if (this.settings.touchDrag && !isTouchIE) {
708            this.$stage.on('touchstart touchcancel', $.proxy(function (event) {
709                this.eventsRouter(event)
710            }, this));
711        }
712
713        // catch transitionEnd event
714        if (this.transitionEndVendor) {
715            this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false);
716        }
717
718        // responsive
719        if (this.settings.responsive !== false) {
720            this.on(window, 'resize', $.proxy(this.onThrottledResize, this));
721        }
722    };
723
724    /**
725     * Handles touchstart/mousedown event.
726     * @protected
727     * @param {Event} event - The event arguments.
728     */
729    Owl.prototype.onDragStart = function (event) {
730        var ev, isTouchEvent, pageX, pageY, animatedPos;
731
732        ev = event.originalEvent || event || window.event;
733
734        // prevent right click
735        if (ev.which === 3 || this.state.isTouch) {
736            return false;
737        }
738
739        if (ev.type === 'mousedown') {
740            this.$stage.addClass('owl-grab');
741        }
742
743        this.trigger('drag');
744        this.drag.startTime = new Date().getTime();
745        this.speed(0);
746        this.state.isTouch = true;
747        this.state.isScrolling = false;
748        this.state.isSwiping = false;
749        this.drag.distance = 0;
750
751        pageX = getTouches(ev).x;
752        pageY = getTouches(ev).y;
753
754        // get stage position left
755        this.drag.offsetX = this.$stage.position().left;
756        this.drag.offsetY = this.$stage.position().top;
757
758        if (this.settings.rtl) {
759            this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width()
760                + this.settings.margin;
761        }
762
763        // catch position // ie to fix
764        if (this.state.inMotion && this.support3d) {
765            animatedPos = this.getTransformProperty();
766            this.drag.offsetX = animatedPos;
767            this.animate(animatedPos);
768            this.state.inMotion = true;
769        } else if (this.state.inMotion && !this.support3d) {
770            this.state.inMotion = false;
771            return false;
772        }
773
774        this.drag.startX = pageX - this.drag.offsetX;
775        this.drag.startY = pageY - this.drag.offsetY;
776
777        this.drag.start = pageX - this.drag.startX;
778        this.drag.targetEl = ev.target || ev.srcElement;
779        this.drag.updatedX = this.drag.start;
780
781        // to do/check
782        // prevent links and images dragging;
783        if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") {
784            this.drag.targetEl.draggable = false;
785        }
786
787        $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function (event) {
788            this.eventsRouter(event)
789        }, this));
790    };
791
792    /**
793     * Handles the touchmove/mousemove events.
794     * @todo Simplify
795     * @protected
796     * @param {Event} event - The event arguments.
797     */
798    Owl.prototype.onDragMove = function (event) {
799        var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull;
800
801        if (!this.state.isTouch) {
802            return;
803        }
804
805        if (this.state.isScrolling) {
806            return;
807        }
808
809        ev = event.originalEvent || event || window.event;
810
811        pageX = getTouches(ev).x;
812        pageY = getTouches(ev).y;
813
814        // Drag Direction
815        this.drag.currentX = pageX - this.drag.startX;
816        this.drag.currentY = pageY - this.drag.startY;
817        this.drag.distance = this.drag.currentX - this.drag.offsetX;
818
819        // Check move direction
820        if (this.drag.distance < 0) {
821            this.state.direction = this.settings.rtl ? 'right' : 'left';
822        } else if (this.drag.distance > 0) {
823            this.state.direction = this.settings.rtl ? 'left' : 'right';
824        }
825        // Loop
826        if (this.settings.loop) {
827            if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') {
828                this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
829            } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') {
830                this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
831            }
832        } else {
833            // pull
834            minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
835            maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
836            pull = this.settings.pullDrag ? this.drag.distance / 5 : 0;
837            this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull);
838        }
839
840        // Lock browser if swiping horizontal
841
842        if ((this.drag.distance > 8 || this.drag.distance < -8)) {
843            if (ev.preventDefault !== undefined) {
844                ev.preventDefault();
845            } else {
846                ev.returnValue = false;
847            }
848            this.state.isSwiping = true;
849        }
850
851        this.drag.updatedX = this.drag.currentX;
852
853        // Lock Owl if scrolling
854        if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) {
855            this.state.isScrolling = true;
856            this.drag.updatedX = this.drag.start;
857        }
858
859        this.animate(this.drag.updatedX);
860    };
861
862    /**
863     * Handles the touchend/mouseup events.
864     * @protected
865     */
866    Owl.prototype.onDragEnd = function (event) {
867        var compareTimes, distanceAbs, closest;
868
869        if (!this.state.isTouch) {
870            return;
871        }
872
873        if (event.type === 'mouseup') {
874            this.$stage.removeClass('owl-grab');
875        }
876
877        this.trigger('dragged');
878
879        // prevent links and images dragging;
880        this.drag.targetEl.removeAttribute("draggable");
881
882        // remove drag event listeners
883
884        this.state.isTouch = false;
885        this.state.isScrolling = false;
886        this.state.isSwiping = false;
887
888        // to check
889        if (this.drag.distance === 0 && this.state.inMotion !== true) {
890            this.state.inMotion = false;
891            return false;
892        }
893
894        // prevent clicks while scrolling
895
896        this.drag.endTime = new Date().getTime();
897        compareTimes = this.drag.endTime - this.drag.startTime;
898        distanceAbs = Math.abs(this.drag.distance);
899
900        // to test
901        if (distanceAbs > 3 || compareTimes > 300) {
902            this.removeClick(this.drag.targetEl);
903        }
904
905        closest = this.closest(this.drag.updatedX);
906
907        this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
908        this.current(closest);
909        this.invalidate('position');
910        this.update();
911
912        // if pullDrag is off then fire transitionEnd event manually when stick
913        // to border
914        if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) {
915            this.transitionEnd();
916        }
917
918        this.drag.distance = 0;
919
920        $(document).off('.owl.dragEvents');
921    };
922
923    /**
924     * Attaches `preventClick` to disable link while swipping.
925     * @protected
926     * @param {HTMLElement} [target] - The target of the `click` event.
927     */
928    Owl.prototype.removeClick = function (target) {
929        this.drag.targetEl = target;
930        $(target).on('click.preventClick', this.e._preventClick);
931        // to make sure click is removed:
932        window.setTimeout(function () {
933            $(target).off('click.preventClick');
934        }, 300);
935    };
936
937    /**
938     * Suppresses click event.
939     * @protected
940     * @param {Event} ev - The event arguments.
941     */
942    Owl.prototype.preventClick = function (ev) {
943        if (ev.preventDefault) {
944            ev.preventDefault();
945        } else {
946            ev.returnValue = false;
947        }
948        if (ev.stopPropagation) {
949            ev.stopPropagation();
950        }
951        $(ev.target).off('click.preventClick');
952    };
953
954    /**
955     * Catches stage position while animate (only CSS3).
956     * @protected
957     * @returns
958     */
959    Owl.prototype.getTransformProperty = function () {
960        var transform, matrix3d;
961
962        transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform');
963        // var transform = this.$stage.css(this.vendorName + 'transform')
964        transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(',');
965        matrix3d = transform.length === 16;
966
967        return matrix3d !== true ? transform[4] : transform[12];
968    };
969
970    /**
971     * Gets absolute position of the closest item for a coordinate.
972     * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
973     * @protected
974     * @param {Number} coordinate - The coordinate in pixel.
975     * @return {Number} - The absolute position of the closest item.
976     */
977    Owl.prototype.closest = function (coordinate) {
978        var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates();
979
980        if (!this.settings.freeDrag) {
981            // check closest item
982            $.each(coordinates, $.proxy(function (index, value) {
983                if (coordinate > value - pull && coordinate < value + pull) {
984                    position = index;
985                } else if (this.op(coordinate, '<', value)
986                    && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
987                    position = this.state.direction === 'left' ? index + 1 : index;
988                }
989                return position === -1;
990            }, this));
991        }
992
993        if (!this.settings.loop) {
994            // non loop boundries
995            if (this.op(coordinate, '>', coordinates[this.minimum()])) {
996                position = coordinate = this.minimum();
997            } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
998                position = coordinate = this.maximum();
999            }
1000        }
1001
1002        return position;
1003    };
1004
1005    /**
1006     * Animates the stage.
1007     * @public
1008     * @param {Number} coordinate - The coordinate in pixels.
1009     */
1010    Owl.prototype.animate = function (coordinate) {
1011        this.trigger('translate');
1012        this.state.inMotion = this.speed() > 0;
1013
1014        if (this.support3d) {
1015            this.$stage.css({
1016                transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)',
1017                transition: (this.speed() / 1000) + 's'
1018            });
1019        } else if (this.state.isTouch) {
1020            this.$stage.css({
1021                left: coordinate + 'px'
1022            });
1023        } else {
1024            this.$stage.animate({
1025                left: coordinate
1026            }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function () {
1027                if (this.state.inMotion) {
1028                    this.transitionEnd();
1029                }
1030            }, this));
1031        }
1032    };
1033
1034    /**
1035     * Sets the absolute position of the current item.
1036     * @public
1037     * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
1038     * @returns {Number} - The absolute position of the current item.
1039     */
1040    Owl.prototype.current = function (position) {
1041        if (position === undefined) {
1042            return this._current;
1043        }
1044
1045        if (this._items.length === 0) {
1046            return undefined;
1047        }
1048
1049        position = this.normalize(position);
1050
1051        if (this._current !== position) {
1052            var event = this.trigger('change', { property: { name: 'position', value: position } });
1053
1054            if (event.data !== undefined) {
1055                position = this.normalize(event.data);
1056            }
1057
1058            this._current = position;
1059
1060            this.invalidate('position');
1061
1062            this.trigger('changed', { property: { name: 'position', value: this._current } });
1063        }
1064
1065        return this._current;
1066    };
1067
1068    /**
1069     * Invalidates the given part of the update routine.
1070     * @param {String}
1070 part - The part to invalidate.
1071     */
1072    Owl.prototype.invalidate = function (part) {
1073        this._invalidated[part] = true;
1074    }
1075
1076    /**
1077     * Resets the absolute position of the current item.
1078     * @public
1079     * @param {Number} position - The absolute position of the new item.
1080     */
1081    Owl.prototype.reset = function (position) {
1082        position = this.normalize(position);
1083
1084        if (position === undefined) {
1085            return;
1086        }
1087
1088        this._speed = 0;
1089        this._current = position;
1090
1091        this.suppress([ 'translate', 'translated' ]);
1092
1093        this.animate(this.coordinates(position));
1094
1095        this.release([ 'translate', 'translated' ]);
1096    };
1097
1098    /**
1099     * Normalizes an absolute or a relative position for an item.
1100     * @public
1101     * @param {Number} position - The absolute or relative position to normalize.
1102     * @param {Boolean} [relative=false] - Whether the given position is relative or not.
1103     * @returns {Number} - The normalized position.
1104     */
1105    Owl.prototype.normalize = function (position, relative) {
1106        var n = (relative ? this._items.length : this._items.length + this._clones.length);
1107
1108        if (!$.isNumeric(position) || n < 1) {
1109            return undefined;
1110        }
1111
1112        if (this._clones.length) {
1113            position = ((position % n) + n) % n;
1114        } else {
1115            position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position));
1116        }
1117
1118        return position;
1119    };
1120
1121    /**
1122     * Converts an absolute position for an item into a relative position.
1123     * @public
1124     * @param {Number} position - The absolute position to convert.
1125     * @returns {Number} - The converted position.
1126     */
1127    Owl.prototype.relative = function (position) {
1128        position = this.normalize(position);
1129        position = position - this._clones.length / 2;
1130        return this.normalize(position, true);
1131    };
1132
1133    /**
1134     * Gets the maximum position for an item.
1135     * @public
1136     * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1137     * @returns {Number}
1138     */
1139    Owl.prototype.maximum = function (relative) {
1140        var maximum, width, i = 0, coordinate,
1141            settings = this.settings;
1142
1143        if (relative) {
1144            return this._items.length - 1;
1145        }
1146
1147        if (!settings.loop && settings.center) {
1148            maximum = this._items.length - 1;
1149        } else if (!settings.loop && !settings.center) {
1150            maximum = this._items.length - settings.items;
1151        } else if (settings.loop || settings.center) {
1152            maximum = this._items.length + settings.items;
1153        } else if (settings.autoWidth || settings.merge) {
1154            revert = settings.rtl ? 1 : -1;
1155            width = this.$stage.width() - this.$element.width();
1156            while (coordinate = this.coordinates(i)) {
1157                if (coordinate * revert >= width) {
1158                    break;
1159                }
1160                maximum = ++i;
1161            }
1162        } else {
1163            throw 'Can not detect maximum absolute position.'
1164        }
1165
1166        return maximum;
1167    };
1168
1169    /**
1170     * Gets the minimum position for an item.
1171     * @public
1172     * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1173     * @returns {Number}
1174     */
1175    Owl.prototype.minimum = function (relative) {
1176        if (relative) {
1177            return 0;
1178        }
1179
1180        return this._clones.length / 2;
1181    };
1182
1183    /**
1184     * Gets an item at the specified relative position.
1185     * @public
1186     * @param {Number} [position] - The relative position of the item.
1187     * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1188     */
1189    Owl.prototype.items = function (position) {
1190        if (position === undefined) {
1191            return this._items.slice();
1192        }
1193
1194        position = this.normalize(position, true);
1195        return this._items[position];
1196    };
1197
1198    /**
1199     * Gets an item at the specified relative position.
1200     * @public
1201     * @param {Number} [position] - The relative position of the item.
1202     * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1203     */
1204    Owl.prototype.mergers = function (position) {
1205        if (position === undefined) {
1206            return this._mergers.slice();
1207        }
1208
1209        position = this.normalize(position, true);
1210        return this._mergers[position];
1211    };
1212
1213    /**
1214     * Gets the absolute positions of clones for an item.
1215     * @public
1216     * @param {Number} [position] - The relative position of the item.
1217     * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
1218     */
1219    Owl.prototype.clones = function (position) {
1220        var odd = this._clones.length / 2,
1221            even = odd + this._items.length,
1222            map = function (index) {
1223                return index % 2 === 0 ? even + index / 2 : odd 
1223- (index + 1) / 2
1224            };
1225
1226        if (position === undefined) {
1227            return $.map(this._clones, function (v, i) {
1228                return map(i)
1229            });
1230        }
1231
1232        return $.map(this._clones, function (v, i) {
1233            return v === position ? map(i) : null
1234        });
1235    };
1236
1237    /**
1238     * Sets the current animation speed.
1239     * @public
1240     * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
1241     * @returns {Number} - The current animation speed in milliseconds.
1242     */
1243    Owl.prototype.speed = function (speed) {
1244        if (speed !== undefined) {
1245            this._speed = speed;
1246        }
1247
1248        return this._speed;
1249    };
1250
1251    /**
1252     * Gets the coordinate of an item.
1253     * @todo The name of this method is missleanding.
1254     * @public
1255     * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
1256     * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
1257     */
1258    Owl.prototype.coordinates = function (position) {
1259        var coordinate = null;
1260
1261        if (position === undefined) {
1262            return $.map(this._coordinates, $.proxy(function (coordinate, index) {
1263                return this.coordinates(index);
1264            }, this));
1265        }
1266
1267        if (this.settings.center) {
1268            coordinate = this._coordinates[position];
1269            coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
1270        } else {
1271            coordinate = this._coordinates[position - 1] || 0;
1272        }
1273
1274        return coordinate;
1275    };
1276
1277    /**
1278     * Calculates the speed for a translation.
1279     * @protected
1280     * @param {Number} from - The absolute position of the start item.
1281     * @param {Number} to - The absolute position of the target item.
1282     * @param {Number} [factor=undefined] - The time factor in milliseconds.
1283     * @returns {Number} - The time in milliseconds for the translation.
1284     */
1285    Owl.prototype.duration = function (from, to, factor) {
1286        return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
1287    };
1288
1289    /**
1290     * Slides to the specified item.
1291     * @public
1292     * @param {Number} position - The position of the item.
1293     * @param {Number} [speed] - The time in milliseconds for the transition.
1294     */
1295    Owl.prototype.to = function (position, speed) {
1296        if (this.settings.loop) {
1297            var distance = position - this.relative(this.current()),
1298                revert = this.current(),
1299                before = this.current(),
1300                after = this.current() + distance,
1301                direction = before - after < 0 ? true : false,
1302                items = this._clones.length + this._items.length;
1303
1304            if (after < this.settings.items && direction === false) {
1305                revert = before + this._items.length;
1306                this.reset(revert);
1307            } else if (after >= items - this.settings.items && direction === true) {
1308                revert = before - this._items.length;
1309                this.reset(revert);
1310            }
1311            window.clearTimeout(this.e._goToLoop);
1312            this.e._goToLoop = window.setTimeout($.proxy(function () {
1313                this.speed(this.duration(this.current(), revert + distance, speed));
1314                this.current(revert + distance);
1315                this.update();
1316            }, this), 30);
1317        } else {
1318            this.speed(this.duration(this.current(), position, speed));
1319            this.current(position);
1320            this.update();
1321        }
1322    };
1323
1324    /**
1325     * Slides to the next item.
1326     * @public
1327     * @param {Number} [speed] - The time in milliseconds for the transition.
1328     */
1329    Owl.prototype.next = function (speed) {
1330        speed = speed || false;
1331        this.to(this.relative(this.current()) + 1, speed);
1332    };
1333
1334    /**
1335     * Slides to the previous item.
1336     * @public
1337     * @param {Number} [speed] - The time in milliseconds for the transition.
1338     */
1339    Owl.prototype.prev = function (speed) {
1340        speed = speed || false;
1341        this.to(this.relative(this.current()) - 1, speed);
1342    };
1343
1344    /**
1345     * Handles the end of an animation.
1346     * @protected
1347     * @param {Event} event - The event arguments.
1348     */
1349    Owl.prototype.transitionEnd = function (event) {
1350
1351        // if css2 animation then event object is undefined
1352        if (event !== undefined) {
1353            event.stopPropagation();
1354
1355            // Catch only owl-stage transitionEnd event
1356            if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
1357                return false;
1358            }
1359        }
1360
1361        this.state.inMotion = false;
1362        this.trigger('translated');
1363    };
1364
1365    /**
1366     * Gets viewport width.
1367     * @protected
1368     * @return {Number} - The width in pixel.
1369     */
1370    Owl.prototype.viewport = function () {
1371        var width;
1372        if (this.options.responsiveBaseElement !== window) {
1373            width = $(this.options.responsiveBaseElement).width();
1374        } else if (window.innerWidth) {
1375            width = window.innerWidth;
1376        } else if (document.documentElement && document.documentElement.clientWidth) {
1377            width = document.documentElement.clientWidth;
1378        } else {
1379            throw 'Can not detect viewport width.';
1380        }
1381        return width;
1382    };
1383
1384    /**
1385     * Replaces the current content.
1386     * @public
1387     * @param {HTMLElement|jQuery|String} content - The new content.
1388     */
1389    Owl.prototype.replace = function (content) {
1390        this.$stage.empty();
1391        this._items = [];
1392
1393        if (content) {
1394            content = (content instanceof jQuery) ? content : $(content);
1395        }
1396
1397        if (this.settings.nestedItemSelector) {
1398            content = content.find('.' + this.settings.nestedItemSelector);
1399        }
1400
1401        content.filter(function () {
1402            return this.nodeType === 1;
1403        }).each($.proxy(function (index, item) {
1404                item = this.prepare(item);
1405                this.$stage.append(item);
1406                this._items.push(item);
1407                this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
1408            }, this));
1409
1410        this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
1411
1412        this.invalidate('items');
1413    };
1414
1415    /**
1416     * Adds an item.
1417     * @todo Use `item` instead of `content` for the event arguments.
1418     * @public
1419     * @param {HTMLElement|jQuery|String} content - The item content to add.
1420     * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
1421     */
1422    Owl.prototype.add = function (content, position) {
1423        position = position === undefined ? this._items.length : this.normalize(position, true);
1424
1425        this.trigger('add', { content: content, position: position });
1426
1427        if (this._items.length === 0 || position === this._items.length) {
1428            this.$stage.append(content);
1429            this._items.push(content);
1430            this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
1431        } else {
1432            this._items[position].before(content);
1433            this._items.splice(position, 0, content);
1434            this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
1435        }
1436
1437        this.invalidate('items');
1438
1439        this.trigger('added', { content: content, position: position });
1440    };
1441
1442    /**
1443     * Removes an item by its position.
1444     * @todo Use `item` instead of `content` for the event arguments.
1445     * @public
1446     * @param {Number} position - The relative position of the item to remove.
1447     */
1448    Owl.prototype.remove = function (position) {
1449        position = this.normalize(position, true);
1450
1451        if (position === undefined) {
1452            return;
1453        }
1454
1455        this.trigger('remove', { content: this._items[position], position: position });
1456
1457        this._items[position].remove();
1458        this._items.splice(position, 1);
1459        this._mergers.splice(position, 1);
1460
1461        this.invalidate('items');
1462
1463        this.trigger('removed', { content: null, position: position });
1464    };
1465
1466    /**
1467     * Adds triggerable events.
1468     * @protected
1469     */
1470    Owl.prototype.addTriggerableEvents = function () {
1471        var handler = $.proxy(function (callback, event) {
1472            return $.proxy(function (e) {
1473                if (e.relatedTarget !== this) {
1474                    this.suppress([ event ]);
1475                    callback.apply(this, [].slice.call(arguments, 1));
1476                    this.release([ event ]);
1477                }
1478            }, this);
1479        }, this);
1480
1481        $.each({
1482            'next': this.next,
1483            'prev': this.prev,
1484            'to': this.to,
1485            'destroy': this.destroy,
1486            'refresh': this.refresh,
1487            'replace': this.replace,
1488            'add': this.add,
1489            'remove': this.remove
1490        }, $.proxy(function (event, callback) {
1491            this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel'));
1492        }, this));
1493
1494    };
1495
1496    /**
1497     * Watches the visibility of the carousel element.
1498     * @protected
1499     */
1500    Owl.prototype.watchVisibility = function () {
1501
1502        // test on zepto
1503        if (!isElVisible(this.$element.get(0))) {
1504            this.$element.addClass('owl-hidden');
1505            window.clearInterval(this.e._checkVisibile);
1506            this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500);
1507        }
1508
1509        function isElVisible(el) {
1510            return el.offsetWidth > 0 && el.offsetHeight > 0;
1511        }
1512
1513        function checkVisible() {
1514            if (isElVisible(this.$element.get(0))) {
1515                this.$element.removeClass('owl-hidden');
1516                this.refresh();
1517                window.clearInterval(this.e._checkVisibile);
1518            }
1519        }
1520    };
1521
1522    /**
1523     * Preloads images with auto width.
1524     * @protected
1525     * @todo Still to test
1526     */
1527    Owl.prototype.preloadAutoWidthImages = function (imgs) {
1528        var loaded, that, $el, img;
1529
1530        loaded = 0;
1531        that = this;
1532        imgs.each(function (i, el) {
1533            $el = $(el);
1534            img = new Image();
1535
1536            img.onload = function () {
1537                loaded++;
1538                $el.attr('src', img.src);
1539                $el.css('opacity', 1);
1540                if (loaded >= imgs.length) {
1541                    that.state.imagesLoaded = true;
1542                    that.initialize();
1543                }
1544            };
1545
1546            img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina');
1547        });
1548    };
1549
1550    /**
1551     * Destroys the carousel.
1552     * @public
1553     */
1554    Owl.prototype.destroy = function () {
1555
1556        if (this.$element.hasClass(this.settings.themeClass)) {
1557            this.$element.removeClass(this.settings.themeClass);
1558        }
1559
1560        if (this.settings.responsive !== false) {
1561            $(window).off('resize.owl.carousel');
1562        }
1563
1564        if (this.transitionEndVendor) {
1565            this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd);
1566        }
1567
1568        for (var i in this._plugins) {
1569            this._plugins[i].destroy();
1570        }
1571
1572        if (this.settings.mouseDrag || this.settings.touchDrag) {
1573            this.$stage.off('mousedown touchstart touchcancel');
1574            $(document).off('.owl.dragEvents');
1575            this.$stage.get(0).onselectstart = function () {
1576            };
1577            this.$stage.off('dragstart', function () {
1578                return false
1579            });
1580        }
1581
1582        // remove event handlers in the ".owl.carousel" namespace
1583        this.$element.off('.owl');
1584
1585        this.$stage.children('.cloned').remove();
1586        this.e = null;
1587        this.$element.removeData('owlCarousel');
1588
1589        this.$stage.children().contents().unwrap();
1590        this.$stage.children().unwrap();
1591        this.$stage.unwrap();
1592    };
1593
1594    /**
1595     * Operators to calculate right-to-left and left-to-right.
1596     * @protected
1597     * @param {Number} [a] - The left side operand.
1598     * @param {String} [o] - The operator.
1599     * @param {Number} [b] - The right side operand.
1600     */
1601    Owl.prototype.op = function (a, o, b) {
1602        var rtl = this.settings.rtl;
1603        switch (o) {
1604            case '<':
1605                return rtl ? a > b : a < b;
1606            case '>':
1607                return rtl ? a < b : a > b;
1608            case '>=':
1609                return rtl ? a <= b : a >= b;
1610            case '<=':
1611                return rtl ? a >= b : a <= b;
1612            default:
1613                break;
1614        }
1615    };
1616
1617    /**
1618     * Attaches to an internal event.
1619     * @protected
1620     * @param {HTMLElement} element - The event source.
1621     * @param {String} event - The event name.
1622     * @param {Function} listener - The event handler to attach.
1623     * @param {Boolean} capture - Wether the event should be handled at the capturing p
1623hase or not.
1624     */
1625    Owl.prototype.on = function (element, event, listener, capture) {
1626        if (element.addEventListener) {
1627            element.addEventListener(event, listener, capture);
1628        } else if (element.attachEvent) {
1629            element.attachEvent('on' + event, listener);
1630        }
1631    };
1632
1633    /**
1634     * Detaches from an internal event.
1635     * @protected
1636     * @param {HTMLElement} element - The event source.
1637     * @param {String} event - The event name.
1638     * @param {Function} listener - The attached event handler to detach.
1639     * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
1640     */
1641    Owl.prototype.off = function (element, event, listener, capture) {
1642        if (element.removeEventListener) {
1643            element.removeEventListener(event, listener, capture);
1644        } else if (element.detachEvent) {
1645            element.detachEvent('on' + event, listener);
1646        }
1647    };
1648
1649    /**
1650     * Triggers an public event.
1651     * @protected
1652     * @param {String} name - The event name.
1653     * @param {*} [data=null] - The event data.
1654     * @param {String} [namespace=.owl.carousel] - The event namespace.
1655     * @returns {Event} - The event arguments.
1656     */
1657    Owl.prototype.trigger = function (name, data, namespace) {
1658        var status = {
1659            item: { count: this._items.length, index: this.current() }
1660        }, handler = $.camelCase(
1661            $.grep([ 'on', name, namespace ], function (v) {
1662                return v
1663            })
1664                .join('-').toLowerCase()
1665        ), event = $.Event(
1666            [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
1667            $.extend({ relatedTarget: this }, status, data)
1668        );
1669
1670        if (!this._supress[name]) {
1671            $.each(this._plugins, function (name, plugin) {
1672                if (plugin.onTrigger) {
1673                    plugin.onTrigger(event);
1674                }
1675            });
1676
1677            this.$element.trigger(event);
1678
1679            if (this.settings && typeof this.settings[handler] === 'function') {
1680                this.settings[handler].apply(this, event);
1681            }
1682        }
1683
1684        return event;
1685    };
1686
1687    /**
1688     * Suppresses events.
1689     * @protected
1690     * @param {Array.<String>} events - The events to suppress.
1691     */
1692    Owl.prototype.suppress = function (events) {
1693        $.each(events, $.proxy(function (index, event) {
1694            this._supress[event] = true;
1695        }, this));
1696    }
1697
1698    /**
1699     * Releases suppressed events.
1700     * @protected
1701     * @param {Array.<String>} events - The events to release.
1702     */
1703    Owl.prototype.release = function (events) {
1704        $.each(events, $.proxy(function (index, event) {
1705            delete this._supress[event];
1706        }, this));
1707    }
1708
1709    /**
1710     * Checks the availability of some browser features.
1711     * @protected
1712     */
1713    Owl.prototype.browserSupport = function () {
1714        this.support3d = isPerspective();
1715
1716        if (this.support3d) {
1717            this.transformVendor = isTransform();
1718
1719            // take transitionend event name by detecting transition
1720            var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ];
1721            this.transitionEndVendor = endVendors[isTransition()];
1722
1723            // take vendor name from transform name
1724            this.vendorName = this.transformVendor.replace(/Transform/i, '');
1725            this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : '';
1726        }
1727
1728        this.state.orientation = window.orientation;
1729    };
1730
1731    /**
1732     * Get touch/drag coordinats.
1733     * @private
1734     * @param {event} - mousedown/touchstart event
1735     * @returns {object} - Contains X and Y of current mouse/touch position
1736     */
1737
1738    function getTouches(event) {
1739        if (event.touches !== undefined) {
1740            return {
1741                x: event.touches[0].pageX,
1742                y: event.touches[0].pageY
1743            };
1744        }
1745
1746        if (event.touches === undefined) {
1747            if (event.pageX !== undefined) {
1748                return {
1749                    x: event.pageX,
1750                    y: event.pageY
1751                };
1752            }
1753
1754            if (event.pageX === undefined) {
1755                return {
1756                    x: event.clientX,
1757                    y: event.clientY
1758                };
1759            }
1760        }
1761    }
1762
1763    /**
1764     * Checks for CSS support.
1765     * @private
1766     * @param {Array} array - The CSS properties to check for.
1767     * @returns {Array} - Contains the supported CSS property name and its index or `false`.
1768     */
1769    function isStyleSupported(array) {
1770        var p, s, fake = document.createElement('div'), list = array;
1771        for (p in list) {
1772            s = list[p];
1773            if (typeof fake.style[s] !== 'undefined') {
1774                fake = null;
1775                return [ s, p ];
1776            }
1777        }
1778        return [ false ];
1779    }
1780
1781    /**
1782     * Checks for CSS transition support.
1783     * @private
1784     * @todo Realy bad design
1785     * @returns {Number}
1786     */
1787    function isTransition() {
1788        return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1];
1789    }
1790
1791    /**
1792     * Checks for CSS transform support.
1793     * @private
1794     * @returns {String} The supported property name or false.
1795     */
1796    function isTransform() {
1797        return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0];
1798    }
1799
1800    /**
1801     * Checks for CSS perspective support.
1802     * @private
1803     * @returns {String} The supported property name or false.
1804     */
1805    function isPerspective() {
1806        return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0];
1807    }
1808
1809    /**
1810     * Checks wether touch is supported or not.
1811     * @private
1812     * @returns {Boolean}
1813     */
1814    function isTouchSupport() {
1815        return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);
1816    }
1817
1818    /**
1819     * Checks wether touch is supported or not for IE.
1820     * @private
1821     * @returns {Boolean}
1822     */
1823    function isTouchSupportIE() {
1824        return window.navigator.msPointerEnabled;
1825    }
1826
1827    /**
1828     * The jQuery Plugin for the Owl Carousel
vendor: 12,397 bytes, lines 1829-2241
1829     * @public
1830     */
1831    $.fn.owlCarousel = function (options) {
1832        return this.each(function () {
1833            if (!$(this).data('owlCarousel')) {
1834                $(this).data('owlCarousel', new Owl(this, options));
1835            }
1836        });
1837    };
1838
1839    /**
1840     * The constructor for the jQuery Plugin
1841     * @public
1842     */
1843    $.fn.owlCarousel.Constructor = Owl;
1844
1845})(window.Zepto || window.jQuery, window, document);
1846
1847/**
1848 * Lazy Plugin
1849 * @version 2.0.0
1850 * @author Bartosz Wojciechowski
1851 * @license The MIT License (MIT)
1852 */
1853;
1854(function ($, window, document, undefined) {
1855
1856    /**
1857     * Creates the lazy plugin.
1858     * @class The Lazy Plugin
1859     * @param {Owl} carousel - The Owl Carousel
1860     */
1861    var Lazy = function (carousel) {
1862
1863        /**
1864         * Reference to the core.
1865         * @protected
1866         * @type {Owl}
1867         */
1868        this._core = carousel;
1869
1870        /**
1871         * Already loaded items.
1872         * @protected
1873         * @type {Array.<jQuery>}
1874         */
1875        this._loaded = [];
1876
1877        /**
1878         * Event handlers.
1879         * @protected
1880         * @type {Object}
1881         */
1882        this._handlers = {
1883            'initialized.owl.carousel change.owl.carousel': $.proxy(function (e) {
1884                if (!e.namespace) {
1885                    return;
1886                }
1887
1888                if (!this._core.settings || !this._core.settings.lazyLoad) {
1889                    return;
1890                }
1891
1892                if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
1893                    var settings = this._core.settings,
1894                        n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
1895                        i = ((settings.center && n * -1) || 0),
1896                        position = ((e.property && e.property.value) || this._core.current()) + i,
1897                        clones = this._core.clones().length,
1898                        load = $.proxy(function (i, v) {
1899                            this.load(v)
1900                        }, this);
1901
1902                    while (i++ < n) {
1903                        this.load(clones / 2 + this._core.relative(position));
1904                        clones && $.each(this._core.clones(this._core.relative(position++)), load);
1905                    }
1906                }
1907            }, this)
1908        };
1909
1910        // set the default options
1911        this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
1912
1913        // register event handler
1914        this._core.$element.on(this._handlers);
1915    }
1916
1917    /**
1918     * Default options.
1919     * @public
1920     */
1921    Lazy.Defaults = {
1922        lazyLoad: false
1923    }
1924
1925    /**
1926     * Loads all resources of an item at the specified position.
1927     * @param {Number} position - The absolute position of the item.
1928     * @protected
1929     */
1930    Lazy.prototype.load = function (position) {
1931        var $item = this._core.$stage.children().eq(position),
1932            $elements = $item && $item.find('.owl-lazy');
1933
1934        if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
1935            return;
1936        }
1937
1938        $elements.each($.proxy(function (index, element) {
1939            var $element = $(element), image,
1940                url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
1941
1942            this._core.trigger('load', { element: $element, url: url }, 'lazy');
1943
1944            if ($element.is('img')) {
1945                $element.one('load.owl.lazy', $.proxy(function () {
1946                    $element.css('opacity', 1);
1947                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1948                }, this)).attr('src', url);
1949            } else {
1950                image = new Image();
1951                image.onload = $.proxy(function () {
1952                    $element.css({
1953                        'background-image': 'url(' + url + ')',
1954                        'opacity': '1'
1955                    });
1956                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1957                }, this);
1958                image.src = url;
1959            }
1960        }, this));
1961
1962        this._loaded.push($item.get(0));
1963    }
1964
1965    /**
1966     * Destroys the plugin.
1967     * @public
1968     */
1969    Lazy.prototype.destroy = function () {
1970        var handler, property;
1971
1972        for (handler in this.handlers) {
1973            this._core.$element.off(handler, this.handlers[handler]);
1974        }
1975        for (property in Object.getOwnPropertyNames(this)) {
1976            typeof this[property] != 'function' && (this[property] = null);
1977        }
1978    }
1979
1980    $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
1981
1982})(window.Zepto || window.jQuery, window, document);
1983
1984/**
1985 * AutoHeight Plugin
1986 * @version 2.0.0
1987 * @author Bartosz Wojciechowski
1988 * @license The MIT License (MIT)
1989 */
1990;
1991(function ($, window, document, undefined) {
1992
1993    /**
1994     * Creates the auto height plugin.
1995     * @class The Auto Height Plugin
1996     * @param {Owl} carousel - The Owl Carousel
1997     */
1998    var AutoHeight = function (carousel) {
1999        /**
2000         * Reference to the core.
2001         * @protected
2002         * @type {Owl}
2003         */
2004        this._core = carousel;
2005
2006        /**
2007         * All event handlers.
2008         * @protected
2009         * @type {Object}
2010         */
2011        this._handlers = {
2012            'initialized.owl.carousel': $.proxy(function () {
2013                if (this._core.settings.autoHeight) {
2014                    this.update();
2015                }
2016            }, this),
2017            'changed.owl.carousel': $.proxy(function (e) {
2018                if (this._core.settings.autoHeight && e.property.name == 'position') {
2019                    this.update();
2020                }
2021            }, this),
2022            'loaded.owl.lazy': $.proxy(function (e) {
2023                if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass)
2024                    === this._core.$stage.children().eq(this._core.current())) {
2025                    this.update();
2026                }
2027            }, this)
2028        };
2029
2030        // set default options
2031        this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
2032
2033        // register event handlers
2034        this._core.$element.on(this._handlers);
2035    };
2036
2037    /**
2038     * Default options.
2039     * @public
2040     */
2041    AutoHeight.Defaults = {
2042        autoHeight: false,
2043        autoHeightClass: 'owl-height'
2044    };
2045
2046    /**
2047     * Updates the view.
2048     */
2049    AutoHeight.prototype.update = function () {
2050        this._core.$stage.parent()
2051            .height(this._core.$stage.children().eq(this._core.current()).height())
2052            .addClass(this._core.settings.autoHeightClass);
2053    };
2054
2055    AutoHeight.prototype.destroy = function () {
2056        var handler, property;
2057
2058        for (handler in this._handlers) {
2059            this._core.$element.off(handler, this._handlers[handler]);
2060        }
2061        for (property in Object.getOwnPropertyNames(this)) {
2062            typeof this[property] != 'function' && (this[property] = null);
2063        }
2064    };
2065
2066    $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
2067
2068})(window.Zepto || window.jQuery, window, document);
2069
2070/**
2071 * Video Plugin
2072 * @version 2.0.0
2073 * @author Bartosz Wojciechowski
2074 * @license The MIT License (MIT)
2075 */
2076;
2077(function ($, window, document, undefined) {
2078
2079    /**
2080     * Creates the video plugin.
2081     * @class The Video Plugin
2082     * @param {Owl} carousel - The Owl Carousel
2083     */
2084    var Video = function (carousel) {
2085        /**
2086         * Reference to the core.
2087         * @protected
2088         * @type {Owl}
2089         */
2090        this._core = carousel;
2091
2092        /**
2093         * Cache all video URLs.
2094         * @protected
2095         * @type {Object}
2096         */
2097        this._videos = {};
2098
2099        /**
2100         * Current playing item.
2101         * @protected
2102         * @type {jQuery}
2103         */
2104        this._playing = null;
2105
2106        /**
2107         * Whether this is in fullscreen or not.
2108         * @protected
2109         * @type {Boolean}
2110         */
2111        this._fullscreen = false;
2112
2113        /**
2114         * All event handlers.
2115         * @protected
2116         * @type {Object}
2117         */
2118        this._handlers = {
2119            'resize.owl.carousel': $.proxy(function (e) {
2120                if (this._core.settings.video && !this.isInFullScreen()) {
2121                    e.preventDefault();
2122                }
2123            }, this),
2124            'refresh.owl.carousel changed.owl.carousel': $.proxy(function (e) {
2125                if (this._playing) {
2126                    this.stop();
2127                }
2128            }, this),
2129            'prepared.owl.carousel': $.proxy(function (e) {
2130                var $element = $(e.content).find('.owl-video');
2131                if ($element.length) {
2132                    $element.css('display', 'none');
2133                    this.fetch($element, $(e.content));
2134                }
2135            }, this)
2136        };
2137
2138        // set default options
2139        this._core.options = $.extend({}, Video.Defaults, this._core.options);
2140
2141        // register event handlers
2142        this._core.$element.on(this._handlers);
2143
2144        this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function (e) {
2145            this.play(e);
2146        }, this));
2147    };
2148
2149    /**
2150     * Default options.
2151     * @public
2152     */
2153    Video.Defaults = {
2154        video: false,
2155        videoHeight: false,
2156        videoWidth: false
2157    };
2158
2159    /**
2160     * Gets the video ID and the type (YouTube/Vimeo only).
2161     * @protected
2162     * @param {jQuery} target - The target containing the video data.
2163     * @param {jQuery} item - The item containing the video.
2164     */
2165    Video.prototype.fetch = function (target, item) {
2166
2167        var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
2168            id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
2169            width = target.attr('data-width') || this._core.settings.videoWidth,
2170            height = target.attr('data-height') || this._core.settings.videoHeight,
2171            url = target.attr('href');
2172
2173        if (url) {
2174            id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
2175
2176            if (id[3].indexOf('youtu') > -1) {
2177                type = 'youtube';
2178            } else if (id[3].indexOf('vimeo') > -1) {
2179                type = 'vimeo';
2180            } else {
2181                throw new Error('Video URL not supported.');
2182            }
2183            id = id[6];
2184        } else {
2185            throw new Error('Missing video URL.');
2186        }
2187
2188        this._videos[url] = {
2189            type: type,
2190            id: id,
2191            width: width,
2192            height: height
2193        };
2194
2195        item.attr('data-video', url);
2196
2197        this.thumbnail(target, this._videos[url]);
2198    };
2199
2200    /**
2201     * Creates video thumbnail.
2202     * @protected
2203     * @param {jQuery} target - The target containing the video data.
2204     * @param {Object} info - The video info object.
2205     * @see `fetch`
2206     */
2207    Video.prototype.thumbnail = function (target, video) {
2208
2209        var tnLink,
2210            icon,
2211            path,
2212            dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
2213            customTn = target.find('img'),
2214            srcType = 'src',
2215            lazyClass = '',
2216            settings = this._core.settings,
2217            create = function (path) {
2218                icon = '<div class="owl-video-play-icon"></div>';
2219
2220                if (settings.lazyLoad) {
2221                    tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
2222                } else {
2223                    tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
2224                }
2225                target.after(tnLink);
2226                target.after(icon);
2227            };
2228
2229        // wrap video content into owl-video-wrapper div
2230        target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
2231
2232        if (this._core.settings.lazyLoad) {
2233            srcType = 'data-src';
2234            lazyClass = 'owl-lazy';
2235        }
2236
2237        // custom thumbnail
2238        if (customTn.length) {
2239            create(customTn.attr(srcType));
2240            customTn.remove();
2241            return false;
2242        }
2243
2244        if (video.type === 'youtube') {
2245            path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
2246            create(path);
2247        } else if (video.type === 'vimeo') {
2248            $.ajax({
2249                type: 'GET',
2250                url: 'http://vimeo.com/api/v2/video/' + video.id + '.json',
2251                jsonp: 'callback',
2252                dataType: 'jsonp',
2253                success: function (data) {
2254                    path = data[0].thumbnail_large;
2255                    create(path);
2256                }
2257            });
2258        }
2259    };
2260
2261    /**
2262     * Stops the current video.
2263     * @public
2264     */
2265    Video.prototype.stop = function () {
2266        this._core.trigger('stop', null, 'video');
2267        this._playing.find('.owl-video-frame').remove();
2268        this._playing.removeClass('owl-video-playing');
2269        this._playing = null;
2270    };
2271
2272    /**
2273     * Starts the current video.
2274     * @public
2275     * @param {Event} ev - The event arguments.
2276     */
2277    Video.prototype.play = function (ev) {
2278        this._core.trigger('play', null, 'video');
2279
2280        if (this._playing) {
2281            this.stop();
2282        }
2283
2284        var target = $(ev.target || ev.srcElement),
2285            item = target.closest('.' + this._core.settings.itemClass),
2286            video = this._videos[item.attr('data-video')],
2287            width = video.width || '100%',
2288            height = video.height || this._core.$stage.height(),
2289            html, wrap;
2290
2291        if (video.type === 'youtube') {
2292            html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/'
2293                + video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
2294        } else if (video.type === 'vimeo') {
2295            html = '<iframe src="http://player.vimeo.com/video/' + video.id + '?autoplay=1" width="' + width
2296                + '" height="' + height
2297                + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
2298        }
2299
2300        item.addClass('owl-video-playing');
2301        this._playing = item;
2302
2303        wrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">'
2304            + html + '</div>');
2305        target.after(wrap);
2306    };
2307
2308    /**
2309     * Checks whether an video is currently in full screen mode or not.
2310     * @todo Bad style because looks like a readonly method but changes members.
2311     * @protected
2312     * @returns {Boolean}
2313     */
2314    Video.prototype.isInFullScreen = function () {
2315
2316        // if Vimeo Fullscreen mode
2317        var element = document.fullscreenElement || document.mozFullScreenElement
2318            || document.webkitFullscreenElement;
2319
2320        if (element && $(element).parent().hasClass('owl-video-frame')) {
2321            this._core.speed(0);
2322            this._fullscreen = true;
2323        }
2324
2325        if (element && this._fullscreen && this._playing) {
2326            return false;
2327        }
2328
2329        // comming back from fullscreen
2330        if (this._fullscreen) {
2331            this._fullscreen = false;
2332            return false;
2333        }
2334
2335        // check full screen mode and window orientation
2336        if (this._playing) {
2337            if (this._core.state.orientation !== window.orientation) {
2338                this._core.state.orientation = window.orientation;
2339                return false;
2340            }
2341        }
2342
2343        return true;
2344    };
2345
2346    /**
2347     * Destroys the plugin.
2348     */
2349    Video.prototype.destroy = function () {
2350        var handler, property;
2351
2352        this._core.$element.off('click.owl.video');
2353
2354        for (handler in this._handlers) {
2355            this._core.$element.off(handler, this._handlers[handler]);
2356        }
2357        for (property in Object.getOwnPropertyNames(this)) {
2358            typeof this[property] != 'function' && (this[property] = null);
2359        }
2360    };
2361
2362    $.fn.owlCarousel.Constructor.Plugins.Video = Video;
2363
2364})(window.Zepto || window.jQuery, window, document);
2365
2366/**
2367 * Animate Plugin
2368 * @version 2.0.0
2369 * @author Bartosz Wojciechowski
2370 * @license The MIT License (MIT)
2371 */
2372;
2373(function ($, window, document, undefined) {
2374
2375    /**
2376     * Creates the animate plugin.
2377     * @class The Navigation Plugin
2378     * @param {Owl} scope - The Owl Carousel
2379     */
2380    var Animate = function (scope) {
2381        this.core = scope;
2382        this.core.options = $.extend({}, Animate.Defaults, this.core.options);
2383        this.swapping = true;
2384        this.previous = undefined;
2385        this.next = undefined;
2386
2387        this.handlers = {
2388            'change.owl.carousel': $.proxy(function (e) {
2389                if (e.property.name == 'position') {
2390                    this.previous = this.core.current();
2391                    this.next = e.property.value;
2392                }
2393            }, this),
2394            'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function (e) {
2395                this.swapping = e.type == 'translated';
2396            }, this),
2397            'translate.owl.carousel': $.proxy(function (e) {
2398                if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
2399                    this.swap();
2400                }
2401            }, this)
2402        };
2403
2404        this.core.$element.on(this.handlers);
2405    };
2406
2407    /**
2408     * Default options.
2409     * @public
2410     */
2411    Animate.Defaults = {
2412        animateOut: false,
2413        animateIn: false
2414    };
2415
2416    /**
2417     * Toggles the animation classes whenever an translations starts.
2418     * @protected
2419     * @returns {Boolean|undefined}
2420     */
2421    Animate.prototype.swap = function () {
2422
2423        if (this.core.settings.items !== 1 || !this.core.support3d) {
2424            return;
2425        }
2426
2427        this.core.speed(0);
2428
2429        var left,
2430            clear = $.proxy(this.clear, this),
2431            previous = this.core.$stage.children().eq(this.previous),
2432            next = this.core.$stage.children().eq(this.next),
2433            incoming = this.core.settings.animateIn,
2434            outgoing = this.core.settings.animateOut;
2435
2436        if (this.core.current() === this.previous) {
2437            return;
2438        }
2439
2440        if (outgoing) {
2441            left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
2442            previous.css({ 'left': left + 'px' })
2443                .addClass('animated owl-animated-out')
2444                .addClass(outgoing)
2445                .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
2446        }
2447
2448        if (incoming) {
2449            next.addClass('animated owl-animated-in')
2450                .addClass(incoming)
2451                .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
2452        }
2453    };
2454
2455    Animate.prototype.clear = function (e) {
2456        $(e.target).css({ 'left': '' })
2457            .removeClass('animated owl-animated-out owl-animated-in')
2458            .removeClass(this.core.settings.animateIn)
2459            .removeClass(this.core.settings.animateOut);
2460        this.core.transitionEnd();
2461    }
2462
2463    /**
2464     * Destroys the plugin.
2465     * @public
2466     */
2467    Animate.prototype.destroy = function () {
2468        var handler, property;
2469
2470        for (handler in this.handlers) {
2471            this.core.$element.off(handler, this.handlers[handler]);
2472        }
2473        for (property in Object.getOwnPropertyNames(this)) {
2474            typeof this[property] != 'function' && (this[property] = null);
2475        }
2476    };
2477
2478    $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
2479
2480})(window.Zepto || window.jQuery, window, document);
2481
2482/**
2483 * Autoplay Plugin
2484 * @version 2.0.0
2485 * @author Bartosz Wojciechowski
2486 * @license The MIT License (MIT)
2487 */
2488;
2489(function ($, window, document, undefined) {
2490
2491    /**
2492     * Creates the autoplay plugin.
2493     * @class The Autoplay Plugin
2494     * @param {Owl} scope - The Owl Carousel
2495     */
2496    var Autoplay = function (scope) {
2497        this.core = scope;
2498        this.core.options = $.extend({}, Autoplay.Defaults, this.core.options);
2499
2500        this.handlers = {
2501            'translated.owl.carousel refreshed.owl.carousel': $.proxy(function () {
2502                this.autoplay();
2503            }, this),
2504            'play.owl.autoplay': $.proxy(function (e, t, s) {
2505                this.play(t, s);
2506            }, this),
2507            'stop.owl.autoplay': $.proxy(function () {
2508                this.stop();
2509            }, this),
2510            'mouseover.owl.autoplay': $.proxy(function () {
2511                if (this.core.settings.autoplayHoverPause) {
2512                    this.pause();
2513                }
2514            }, this),
2515            'mouseleave.owl.autoplay': $.proxy(function () {
2516                if (this.core.settings.autoplayHoverPause) {
2517                    this.autoplay();
2518                }
2519            }, this)
2520        };
2521
2522        this.core.$element.on(this.handlers);
2523    };
2524
2525    /**
2526     * Default options.
2527     * @public
2528     */
2529    Autoplay.Defaults = {
2530        autoplay: false,
2531        autoplayTimeout: 5000,
2532        autoplayHoverPause: false,
2533        autoplaySpeed: false
2534    };
2535
2536    /**
2537     * @protected
2538     * @todo Must be documented.
2539     */
2540    Autoplay.prototype.autoplay = function () {
2541        if (this.core.settings.autoplay && !this.core.state.videoPlay) {
2542            window.clearInterval(this.interval);
2543
2544            this.interval = window.setInterval($.proxy(function () {
2545                this.play();
2546            }, this), this.core.settings.autoplayTimeout);
2547        } else {
2548            window.clearInterval(this.interval);
2549        }
2550    };
2551
2552    /**
2553     * Starts the autoplay.
2554     * @public
2555     * @param {Number} [timeout] - ...
2556     * @param {Number}
2556 [speed] - ...
2557     * @returns {Boolean|undefined} - ...
2558     * @todo Must be documented.
2559     */
2560    Autoplay.prototype.play = function (timeout, speed) {
2561        // if tab is inactive - doesnt work in <IE10
2562        if (document.hidden === true) {
2563            return;
2564        }
2565
2566        if (this.core.state.isTouch || this.core.state.isScrolling
2567            || this.core.state.isSwiping || this.core.state.inMotion) {
2568            return;
2569        }
2570
2571        if (this.core.settings.autoplay === false) {
2572            window.clearInterval(this.interval);
2573            return;
2574        }
2575
2576        this.core.next(this.core.settings.autoplaySpeed);
2577    };
2578
2579    /**
2580     * Stops the autoplay.
2581     * @public
2582     */
2583    Autoplay.prototype.stop = function () {
2584        window.clearInterval(this.interval);
2585    };
2586
2587    /**
2588     * Pauses the autoplay.
2589     * @public
2590     */
2591    Autoplay.prototype.pause = function () {
2592        window.clearInterval(this.interval);
2593    };
2594
2595    /**
2596     * Destroys the plugin.
2597     */
2598    Autoplay.prototype.destroy = function () {
2599        var handler, property;
2600
2601        window.clearInterval(this.interval);
2602
2603        for (handler in this.handlers) {
2604            this.core.$element.off(handler, this.handlers[handler]);
2605        }
2606        for (property in Object.getOwnPropertyNames(this)) {
2607            typeof this[property] != 'function' && (this[property] = null);
2608        }
2609    };
2610
2611    $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
2612
2613})(window.Zepto || window.jQuery, window, document);
2614
2615/**
2616 * Navigation Plugin
2617 * @version 2.0.0
2618 * @author Artus Kolanowski
2619 * @license The MIT License (MIT)
2620 */
2621;
2622(function ($, window, document, undefined) {
2623    'use strict';
2624
2625    /**
2626     * Creates the navigation plugin.
2627     * @class The Navigation Plugin
2628     * @param {Owl} carousel - The Owl Carousel.
2629     */
2630    var Navigation = function (carousel) {
2631        /**
2632         * Reference to the core.
2633         * @protected
2634         * @type {Owl}
2635         */
2636        this._core = carousel;
2637
2638        /**
2639         * Indicates whether the plugin is initialized or not.
2640         * @protected
2641         * @type {Boolean}
2642         */
2643        this._initialized = false;
2644
2645        /**
2646         * The current paging indexes.
2647         * @protected
2648         * @type {Array}
2649         */
2650        this._pages = [];
2651
2652        /**
2653         * All DOM elements of the user interface.
2654         * @protected
2655         * @type {Object}
2656         */
2657        this._controls = {};
2658
2659        /**
2660         * Markup for an indicator.
2661         * @protected
2662         * @type {Array.<String>}
2663         */
2664        this._templates = [];
2665
2666        /**
2667         * The carousel element.
2668         * @type {jQuery}
2669         */
2670        this.$element = this._core.$element;
2671
2672        /**
2673         * Overridden methods of the carousel.
2674         * @protected
2675         * @type {Object}
2676         */
2677        this._overrides = {
2678            next: this._core.next,
2679            prev: this._core.prev,
2680            to: this._core.to
2681        };
2682
2683        /**
2684         * All event handlers.
2685         * @protected
2686         * @type {Object}
2687         */
2688        this._handlers = {
2689            'prepared.owl.carousel': $.proxy(function (e) {
2690                if (this._core.settings.dotsData) {
2691                    this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
2692                }
2693            }, this),
2694            'add.owl.carousel': $.proxy(function (e) {
2695                if (this._core.settings.dotsData) {
2696                    this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
2697                }
2698            }, this),
2699            'remove.owl.carousel prepared.owl.carousel': $.proxy(function (e) {
2700                if (this._core.settings.dotsData) {
2701                    this._templates.splice(e.position, 1);
2702                }
2703            }, this),
2704            'change.owl.carousel': $.proxy(function (e) {
2705                if (e.property.name == 'position') {
2706                    if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) {
2707                        var current = this._core.current(),
2708                            maximum = this._core.maximum(),
2709                            minimum = this._core.minimum();
2710                        e.data = e.property.value > maximum
2711                            ? current >= maximum ? minimum : maximum
2712                            : e.property.value < minimum ? maximum : e.property.value;
2713                    }
2714                }
2715            }, this),
2716            'changed.owl.carousel': $.proxy(function (e) {
2717                if (e.property.name == 'position') {
2718                    this.draw();
2719                }
2720            }, this),
2721            'refreshed.owl.carousel': $.proxy(function () {
2722                if (!this._initialized) {
2723                    this.initialize();
2724                    this._initialized = true;
2725                }
2726                this._core.trigger('refresh', null, 'navigation');
2727                this.update();
2728                this.draw();
2729                this._core.trigger('refreshed', null, 'navigation');
2730            }, this)
2731        };
2732
2733        // set default options
2734        this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
2735
2736        // register event handlers
2737        this.$element.on(this._handlers);
2738    }
2739
2740    /**
2741     * Default options.
2742     * @public
2743     * @todo Rename `slideBy` to `navBy`
2744     */
2745    Navigation.Defaults = {
2746        nav: false,
2747        navRewind: true,
2748        navText: [ 'prev', 'next' ],
2749        navSpeed: false,
2750        navElement: 'div',
2751        navContainer: false,
2752        navContainerClass: 'owl-nav',
2753        navClass: [ 'owl-prev', 'owl-next' ],
2754        slideBy: 1,
2755        dotClass: 'owl-dot',
2756        dotsClass: 'owl-dots',
2757        dots: true,
2758        dotsEach: false,
2759        dotData: false,
2760        dotsSpeed: false,
2761        dotsContainer: false,
2762        controlsClass: 'owl-controls'
2763    }
2764
2765    /**
2766     * Initializes the layout of the plugin and extends the carousel.
2767     * @protected
2768     */
2769    Navigation.prototype.initialize = function () {
2770        var $container, override,
2771            options = this._core.settings;
2772
2773        // create the indicator template
2774        if (!options.dotsData) {
2775            this._templates = [ $('<div>')
2776                .addClass(options.dotClass)
2777                .append($('<span>'))
2778                .prop('outerHTML') ];
2779        }
2780
2781        // create controls container if needed
2782        if (!options.navContainer || !options.dotsContainer) {
2783            this._controls.$container = $('<div>')
2784                .addClass(options.controlsClass)
2785                .appendTo(this.$element);
2786        }
2787
2788        // create DOM structure for absolute navigation
2789        this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer)
2790            : $('<div>').hide().addClass(options.dotsClass).appendTo(this._controls.$container);
2791
2792        this._controls.$indicators.on('click', 'div', $.proxy(function (e) {
2793            var index = $(e.target).parent().is(this._controls.$indicators)
2794                ? $(e.target).index() : $(e.target).parent().index();
2795
2796            e.preventDefault();
2797
2798            this.to(index, options.dotsSpeed);
2799        }, this));
2800
2801        // create DOM structure for relative navigation
2802        $container = options.navContainer ? $(options.navContainer)
2803            : $('<div>').addClass(options.navContainerClass).prependTo(this._controls.$container);
2804
2805        this._controls.$next = $('<' + options.navElement + '>');
2806        this._controls.$previous = this._controls.$next.clone();
2807
2808        this._controls.$previous
2809            .addClass(options.navClass[0])
2810            .html(options.navText[0])
2811            .hide()
2812            .prependTo($container)
2813            .on('click', $.proxy(function (e) {
2814                this.prev(options.navSpeed);
2815            }, this));
2816        this._controls.$next
2817            .addClass(options.navClass[1])
2818            .html(options.navText[1])
2819            .hide()
2820            .appendTo($container)
2821            .on('click', $.proxy(function (e) {
2822                this.next(options.navSpeed);
2823            }, this));
2824
2825        // override public methods of the carousel
2826        for (override in this._overrides) {
2827            this._core[override] = $.proxy(this[override], this);
2828        }
2829    }
2830
2831    /**
2832     * Destroys the plugin.
2833     * @protected
2834     */
2835    Navigation.prototype.destroy = function () {
2836        var handler, control, property, override;
2837
2838        for (handler in this._handlers) {
2839            this.$element.off(handler, this._handlers[handler]);
2840        }
2841        for (control in this._controls) {
2842            this._controls[control].remove();
2843        }
2844        for (override in this.overides) {
2845            this._core[override] = this._overrides[override];
2846        }
2847        for (property in Object.getOwnPropertyNames(this)) {
2848            typeof this[property] != 'function' && (this[property] = null);
2849        }
2850    }
2851
2852    /**
2853     * Updates the internal state.
2854     * @protected
2855     */
2856    Navigation.prototype.update = function () {
2857        var i, j, k,
2858            options = this._core.settings,
2859            lower = this._core.clones().length / 2,
2860            upper = lower + this._core.items().length,
2861            size = options.center || options.autoWidth || options.dotData
2862                ? 1 : options.dotsEach || options.items;
2863
2864        if (options.slideBy !== 'page') {
2865            options.slideBy = Math.min(options.slideBy, options.items);
2866        }
2867
2868        if (options.dots || options.slideBy == 'page') {
2869            this._pages = [];
2870
2871            for (i = lower, j = 0, k = 0; i < upper; i++) {
2872                if (j >= size || j === 0) {
2873                    this._pages.push({
2874                        start: i - lower,
2875                        end: i - lower + size - 1
2876                    });
2877                    j = 0, ++k;
2878                }
2879                j += this._core.mergers(this._core.relative(i));
2880            }
2881        }
2882    }
2883
2884    /**
2885     * Draws the user interface.
2886     * @todo The option `dotData` wont work.
2887     * @protected
2888     */
2889    Navigation.prototype.draw = function () {
2890        var difference, i, html = '',
2891            options = this._core.settings,
2892            $items = this._core.$stage.children(),
2893            index = this._core.relative(this._core.current());
2894
2895        if (options.nav && !options.loop && !options.navRewind) {
2896            this._controls.$previous.toggleClass('disabled', index <= 0);
2897            this._controls.$next.toggleClass('disabled', index >= this._core.maximum());
2898        }
2899
2900        this._controls.$previous.toggle(options.nav);
2901        this._controls.$next.toggle(options.nav);
2902
2903        if (options.dots) {
2904            difference = this._pages.length - this._controls.$indicators.children().length;
2905
2906            if (options.dotData && difference !== 0) {
2907                for (i = 0; i < this._controls.$indicators.children().length; i++) {
2908                    html += this._templates[this._core.relative(i)];
2909                }
2910                this._controls.$indicators.html(html);
2911            } else if (difference > 0) {
2912                html = new Array(difference + 1).join(this._templates[0]);
2913                this._controls.$indicators.append(html);
2914            } else if (difference < 0) {
2915                this._controls.$indicators.children().slice(difference).remove();
2916            }
2917
2918            this._controls.$indicators.find('.active').removeClass('active');
2919            this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active');
2920        }
2921
2922        this._controls.$indicators.toggle(options.dots);
2923    }
2924
2925    /**
2926     * Extends event data.
2927     * @protected
2928     * @param {Event} event - The event object which gets thrown.
2929     */
2930    Navigation.prototype.onTrigger = function (event) {
2931        var settings = this._core.settings;
2932
2933        event.page = {
2934            index: $.inArray(this.current(), this._pages),
2935            count: this._pages.length,
2936            size: settings && (settings.center || settings.autoWidth || settings.dotData
2937                ? 1 : settings.dotsEach || settings.items)
2938        };
2939    }
2940
2941    /**
2942     * Gets the current page position of the carousel.
2943     * @protected
2944     * @returns {Number}
2945     */
2946    Navigation.prototype.current = function () {
2947        var index = this._core.relative(this._core.current());
2948        return $.grep(this._pages,function (o) {
2949            return o.start <= index && o.end >= index;
2950        }).pop();
2951    }
2952
2953    /**
2954     * Gets the current succesor/predecessor position.
2955     * @protected
2956     * @returns {Number}
2957     */
2958    Navigation.prototype.getPosition = function (successor) {
2959        var position, length,
2960            options = this._core.settings;
2961
2962        if (options.slideBy == 'page') {
2963            position = $.inArray(this.current(), this._pages);
2964            length = this._pages.length;
2965            successor ? ++position : --position;
2966            position = this._pages[((position % length) + length) % length].start;
2967        } else {
2968            position = this._core.relative(this._core.current());
2969            length = this._core.items().length;
2970            successor ? position += options.slideBy : position -= options.slideBy;
2971        }
2972        return position;
2973    }
2974
2975    /**
2976     * Slides to the next item or page.
2977     * @public
2978     * @param {Number} [speed=false] - The time in milliseconds for the transition.
2979     */
2980    Navigation.prototype.next = function (speed) {
2981        $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
2982    }
2983
2984    /**
2985     * Slides to the previous item or page.
2986     * @public
2987     * @param {Number} [speed=false] - The time in milliseconds for the transition.
2988     */
2989    Navigation.prototype.prev = function (speed) {
2990        $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
2991    }
2992
2993    /**
2994     * Slides to the specified item or page.
2995     * @public
2996     * @param {Number} position - The position of the item or page.
2997     * @param {Number} [speed] - The time in milliseconds for the transition.
2998     * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
2999     */
3000    Navigation.prototype.to = function (position, speed, standard) {
3001        var length;
3002
3003        if (!standard) {
3004            length = this._pages.length;
3005            $.proxy(this._overrides.to, this._core)(this._pages[((
3005position % length) + length) % length].start, speed);
3006        } else {
3007            $.proxy(this._overrides.to, this._core)(position, speed);
3008        }
3009    }
3010
3011    $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
3012
3013})(window.Zepto || window.jQuery, window, document);
3014
3015/**
3016 * Hash Plugin
3017 * @version 2.0.0
3018 * @author Artus Kolanowski
3019 * @license The MIT License (MIT)
3020 */
3021;
3022(function ($, window, document, undefined) {
3023    'use strict';
3024
3025    /**
3026     * Creates the hash plugin.
3027     * @class The Hash Plugin
3028     * @param {Owl} carousel - The Owl Carousel
3029     */
3030    var Hash = function (carousel) {
3031        /**
3032         * Reference to the core.
3033         * @protected
3034         * @type {Owl}
3035         */
3036        this._core = carousel;
3037
3038        /**
3039         * Hash table for the hashes.
3040         * @protected
3041         * @type {Object}
3042         */
3043        this._hashes = {};
3044
3045        /**
3046         * The carousel element.
3047         * @type {jQuery}
3048         */
3049        this.$element = this._core.$element;
3050
3051        /**
3052         * All event handlers.
3053         * @protected
3054         * @type {Object}
3055         */
3056        this._handlers = {
3057            'initialized.owl.carousel': $.proxy(function () {
3058                if (this._core.settings.startPosition == 'URLHash') {
3059                    $(window).trigger('hashchange.owl.navigation');
3060                }
3061            }, this),
3062            'prepared.owl.carousel': $.proxy(function (e) {
3063                var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash');
3064                this._hashes[hash] = e.content;
3065            }, this)
3066        };
3067
3068        // set default options
3069        this._core.options = $.extend({}, Hash.Defaults, this._core.options);
3070
3071        // register the event handlers
3072        this.$element.on(this._handlers);
3073
3074        // register event listener for hash navigation
3075        $(window).on('hashchange.owl.navigation', $.proxy(function () {
3076            var hash = window.location.hash.substring(1),
3077                items = this._core.$stage.children(),
3078                position = this._hashes[hash] && items.index(this._hashes[hash]) || 0;
3079
3080            if (!hash) {
3081                return false;
3082            }
3083
3084            this._core.to(position, false, true);
3085        }, this));
3086    }
3087
3088    /**
3089     * Default options.
3090     * @public
3091     */
3092    Hash.Defaults = {
3093        URLhashListener: false
3094    }
3095
3096    /**
3097     * Destroys the plugin.
3098     * @public
3099     */
3100    Hash.prototype.destroy = function () {
3101        var handler, property;
3102
3103        $(window).off('hashchange.owl.navigation');
3104
3105        for (handler in this._handlers) {
3106            this._core.$element.off(handler, this._handlers[handler]);
3107        }
3108        for (property in Object.getOwnPropertyNames(this)) {
3109            typeof this[property] != 'function' && (this[property] = null);
3110        }
3111    }
3112
3113    $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
3114
3115})(window.Zepto || window.jQuery, window, document);

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.