owlcarousel2 2.2.0.pre.4.pre.g22132e0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +53 -0
  7. data/Rakefile +13 -0
  8. data/lib/owlcarousel2.rb +9 -0
  9. data/lib/owlcarousel2/engine.rb +5 -0
  10. data/lib/owlcarousel2/version.rb +3 -0
  11. data/owlcarousel2.gemspec +25 -0
  12. data/vendor/assets/images/owlcarousel2/ajax-loader.gif +0 -0
  13. data/vendor/assets/images/owlcarousel2/owl.video.play.png +0 -0
  14. data/vendor/assets/javascripts/owlcarousel2/owl.animate.js +121 -0
  15. data/vendor/assets/javascripts/owlcarousel2/owl.autoheight.js +97 -0
  16. data/vendor/assets/javascripts/owlcarousel2/owl.autoplay.js +199 -0
  17. data/vendor/assets/javascripts/owlcarousel2/owl.autorefresh.js +111 -0
  18. data/vendor/assets/javascripts/owlcarousel2/owl.carousel.js +1692 -0
  19. data/vendor/assets/javascripts/owlcarousel2/owl.hash.js +122 -0
  20. data/vendor/assets/javascripts/owlcarousel2/owl.lazyload.js +135 -0
  21. data/vendor/assets/javascripts/owlcarousel2/owl.navigation.js +382 -0
  22. data/vendor/assets/javascripts/owlcarousel2/owl.support.js +83 -0
  23. data/vendor/assets/javascripts/owlcarousel2/owl.support.modernizr.js +66 -0
  24. data/vendor/assets/javascripts/owlcarousel2/owl.video.js +319 -0
  25. data/vendor/assets/stylesheets/owlcarousel2/_animate.scss +28 -0
  26. data/vendor/assets/stylesheets/owlcarousel2/_autoheight.scss +7 -0
  27. data/vendor/assets/stylesheets/owlcarousel2/_core.scss +114 -0
  28. data/vendor/assets/stylesheets/owlcarousel2/_lazyload.scss +17 -0
  29. data/vendor/assets/stylesheets/owlcarousel2/_theme.default.scss +30 -0
  30. data/vendor/assets/stylesheets/owlcarousel2/_theme.green.scss +30 -0
  31. data/vendor/assets/stylesheets/owlcarousel2/_theme.scss +64 -0
  32. data/vendor/assets/stylesheets/owlcarousel2/_video.scss +51 -0
  33. data/vendor/assets/stylesheets/owlcarousel2/owl.carousel.scss +5 -0
  34. data/vendor/assets/stylesheets/owlcarousel2/owl.theme.default.scss +1 -0
  35. data/vendor/assets/stylesheets/owlcarousel2/owl.theme.green.scss +1 -0
  36. metadata +93 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * AutoRefresh Plugin
3
+ * @version 2.1.0
4
+ * @author Artus Kolanowski
5
+ * @author David Deutsch
6
+ * @license The MIT License (MIT)
7
+ */
8
+ ;(function($, window, document, undefined) {
9
+
10
+ /**
11
+ * Creates the auto refresh plugin.
12
+ * @class The Auto Refresh Plugin
13
+ * @param {Owl} carousel - The Owl Carousel
14
+ */
15
+ var AutoRefresh = function(carousel) {
16
+ /**
17
+ * Reference to the core.
18
+ * @protected
19
+ * @type {Owl}
20
+ */
21
+ this._core = carousel;
22
+
23
+ /**
24
+ * Refresh interval.
25
+ * @protected
26
+ * @type {number}
27
+ */
28
+ this._interval = null;
29
+
30
+ /**
31
+ * Whether the element is currently visible or not.
32
+ * @protected
33
+ * @type {Boolean}
34
+ */
35
+ this._visible = null;
36
+
37
+ /**
38
+ * All event handlers.
39
+ * @protected
40
+ * @type {Object}
41
+ */
42
+ this._handlers = {
43
+ 'initialized.owl.carousel': $.proxy(function(e) {
44
+ if (e.namespace && this._core.settings.autoRefresh) {
45
+ this.watch();
46
+ }
47
+ }, this)
48
+ };
49
+
50
+ // set default options
51
+ this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
52
+
53
+ // register event handlers
54
+ this._core.$element.on(this._handlers);
55
+ };
56
+
57
+ /**
58
+ * Default options.
59
+ * @public
60
+ */
61
+ AutoRefresh.Defaults = {
62
+ autoRefresh: true,
63
+ autoRefreshInterval: 500
64
+ };
65
+
66
+ /**
67
+ * Watches the element.
68
+ */
69
+ AutoRefresh.prototype.watch = function() {
70
+ if (this._interval) {
71
+ return;
72
+ }
73
+
74
+ this._visible = this._core.$element.is(':visible');
75
+ this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
76
+ };
77
+
78
+ /**
79
+ * Refreshes the element.
80
+ */
81
+ AutoRefresh.prototype.refresh = function() {
82
+ if (this._core.$element.is(':visible') === this._visible) {
83
+ return;
84
+ }
85
+
86
+ this._visible = !this._visible;
87
+
88
+ this._core.$element.toggleClass('owl-hidden', !this._visible);
89
+
90
+ this._visible && (this._core.invalidate('width') && this._core.refresh());
91
+ };
92
+
93
+ /**
94
+ * Destroys the plugin.
95
+ */
96
+ AutoRefresh.prototype.destroy = function() {
97
+ var handler, property;
98
+
99
+ window.clearInterval(this._interval);
100
+
101
+ for (handler in this._handlers) {
102
+ this._core.$element.off(handler, this._handlers[handler]);
103
+ }
104
+ for (property in Object.getOwnPropertyNames(this)) {
105
+ typeof this[property] != 'function' && (this[property] = null);
106
+ }
107
+ };
108
+
109
+ $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
110
+
111
+ })(window.Zepto || window.jQuery, window, document);
@@ -0,0 +1,1692 @@
1
+ /**
2
+ * Owl carousel
3
+ * @version 2.1.6
4
+ * @author Bartosz Wojciechowski
5
+ * @author David Deutsch
6
+ * @license The MIT License (MIT)
7
+ * @todo Lazy Load Icon
8
+ * @todo prevent animationend bubling
9
+ * @todo itemsScaleUp
10
+ * @todo Test Zepto
11
+ * @todo stagePadding calculate wrong active classes
12
+ */
13
+ ;(function($, window, document, undefined) {
14
+
15
+ /**
16
+ * Creates a carousel.
17
+ * @class The Owl Carousel.
18
+ * @public
19
+ * @param {HTMLElement|jQuery} element - The element to create the carousel for.
20
+ * @param {Object} [options] - The options
21
+ */
22
+ function Owl(element, options) {
23
+
24
+ /**
25
+ * Current settings for the carousel.
26
+ * @public
27
+ */
28
+ this.settings = null;
29
+
30
+ /**
31
+ * Current options set by the caller including defaults.
32
+ * @public
33
+ */
34
+ this.options = $.extend({}, Owl.Defaults, options);
35
+
36
+ /**
37
+ * Plugin element.
38
+ * @public
39
+ */
40
+ this.$element = $(element);
41
+
42
+ /**
43
+ * Proxied event handlers.
44
+ * @protected
45
+ */
46
+ this._handlers = {};
47
+
48
+ /**
49
+ * References to the running plugins of this carousel.
50
+ * @protected
51
+ */
52
+ this._plugins = {};
53
+
54
+ /**
55
+ * Currently suppressed events to prevent them from beeing retriggered.
56
+ * @protected
57
+ */
58
+ this._supress = {};
59
+
60
+ /**
61
+ * Absolute current position.
62
+ * @protected
63
+ */
64
+ this._current = null;
65
+
66
+ /**
67
+ * Animation speed in milliseconds.
68
+ * @protected
69
+ */
70
+ this._speed = null;
71
+
72
+ /**
73
+ * Coordinates of all items in pixel.
74
+ * @todo The name of this member is missleading.
75
+ * @protected
76
+ */
77
+ this._coordinates = [];
78
+
79
+ /**
80
+ * Current breakpoint.
81
+ * @todo Real media queries would be nice.
82
+ * @protected
83
+ */
84
+ this._breakpoint = null;
85
+
86
+ /**
87
+ * Current width of the plugin element.
88
+ */
89
+ this._width = null;
90
+
91
+ /**
92
+ * All real items.
93
+ * @protected
94
+ */
95
+ this._items = [];
96
+
97
+ /**
98
+ * All cloned items.
99
+ * @protected
100
+ */
101
+ this._clones = [];
102
+
103
+ /**
104
+ * Merge values of all items.
105
+ * @todo Maybe this could be part of a plugin.
106
+ * @protected
107
+ */
108
+ this._mergers = [];
109
+
110
+ /**
111
+ * Widths of all items.
112
+ */
113
+ this._widths = [];
114
+
115
+ /**
116
+ * Invalidated parts within the update process.
117
+ * @protected
118
+ */
119
+ this._invalidated = {};
120
+
121
+ /**
122
+ * Ordered list of workers for the update process.
123
+ * @protected
124
+ */
125
+ this._pipe = [];
126
+
127
+ /**
128
+ * Current state information for the drag operation.
129
+ * @todo #261
130
+ * @protected
131
+ */
132
+ this._drag = {
133
+ time: null,
134
+ target: null,
135
+ pointer: null,
136
+ stage: {
137
+ start: null,
138
+ current: null
139
+ },
140
+ direction: null
141
+ };
142
+
143
+ /**
144
+ * Current state information and their tags.
145
+ * @type {Object}
146
+ * @protected
147
+ */
148
+ this._states = {
149
+ current: {},
150
+ tags: {
151
+ 'initializing': [ 'busy' ],
152
+ 'animating': [ 'busy' ],
153
+ 'dragging': [ 'interacting' ]
154
+ }
155
+ };
156
+
157
+ $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
158
+ this._handlers[handler] = $.proxy(this[handler], this);
159
+ }, this));
160
+
161
+ $.each(Owl.Plugins, $.proxy(function(key, plugin) {
162
+ this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
163
+ = new plugin(this);
164
+ }, this));
165
+
166
+ $.each(Owl.Workers, $.proxy(function(priority, worker) {
167
+ this._pipe.push({
168
+ 'filter': worker.filter,
169
+ 'run': $.proxy(worker.run, this)
170
+ });
171
+ }, this));
172
+
173
+ this.setup();
174
+ this.initialize();
175
+ }
176
+
177
+ /**
178
+ * Default options for the carousel.
179
+ * @public
180
+ */
181
+ Owl.Defaults = {
182
+ items: 3,
183
+ loop: false,
184
+ center: false,
185
+ rewind: false,
186
+
187
+ mouseDrag: true,
188
+ touchDrag: true,
189
+ pullDrag: true,
190
+ freeDrag: false,
191
+
192
+ margin: 0,
193
+ stagePadding: 0,
194
+
195
+ merge: false,
196
+ mergeFit: true,
197
+ autoWidth: false,
198
+
199
+ startPosition: 0,
200
+ rtl: false,
201
+
202
+ smartSpeed: 250,
203
+ fluidSpeed: false,
204
+ dragEndSpeed: false,
205
+
206
+ responsive: {},
207
+ responsiveRefreshRate: 200,
208
+ responsiveBaseElement: window,
209
+
210
+ fallbackEasing: 'swing',
211
+
212
+ info: false,
213
+
214
+ nestedItemSelector: false,
215
+ itemElement: 'div',
216
+ stageElement: 'div',
217
+
218
+ refreshClass: 'owl-refresh',
219
+ loadedClass: 'owl-loaded',
220
+ loadingClass: 'owl-loading',
221
+ rtlClass: 'owl-rtl',
222
+ responsiveClass: 'owl-responsive',
223
+ dragClass: 'owl-drag',
224
+ itemClass: 'owl-item',
225
+ stageClass: 'owl-stage',
226
+ stageOuterClass: 'owl-stage-outer',
227
+ grabClass: 'owl-grab'
228
+ };
229
+
230
+ /**
231
+ * Enumeration for width.
232
+ * @public
233
+ * @readonly
234
+ * @enum {String}
235
+ */
236
+ Owl.Width = {
237
+ Default: 'default',
238
+ Inner: 'inner',
239
+ Outer: 'outer'
240
+ };
241
+
242
+ /**
243
+ * Enumeration for types.
244
+ * @public
245
+ * @readonly
246
+ * @enum {String}
247
+ */
248
+ Owl.Type = {
249
+ Event: 'event',
250
+ State: 'state'
251
+ };
252
+
253
+ /**
254
+ * Contains all registered plugins.
255
+ * @public
256
+ */
257
+ Owl.Plugins = {};
258
+
259
+ /**
260
+ * List of workers involved in the update process.
261
+ */
262
+ Owl.Workers = [ {
263
+ filter: [ 'width', 'settings' ],
264
+ run: function() {
265
+ this._width = this.$element.width();
266
+ }
267
+ }, {
268
+ filter: [ 'width', 'items', 'settings' ],
269
+ run: function(cache) {
270
+ cache.current = this._items && this._items[this.relative(this._current)];
271
+ }
272
+ }, {
273
+ filter: [ 'items', 'settings' ],
274
+ run: function() {
275
+ this.$stage.children('.cloned').remove();
276
+ }
277
+ }, {
278
+ filter: [ 'width', 'items', 'settings' ],
279
+ run: function(cache) {
280
+ var margin = this.settings.margin || '',
281
+ grid = !this.settings.autoWidth,
282
+ rtl = this.settings.rtl,
283
+ css = {
284
+ 'width': 'auto',
285
+ 'margin-left': rtl ? margin : '',
286
+ 'margin-right': rtl ? '' : margin
287
+ };
288
+
289
+ !grid && this.$stage.children().css(css);
290
+
291
+ cache.css = css;
292
+ }
293
+ }, {
294
+ filter: [ 'width', 'items', 'settings' ],
295
+ run: function(cache) {
296
+ var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
297
+ merge = null,
298
+ iterator = this._items.length,
299
+ grid = !this.settings.autoWidth,
300
+ widths = [];
301
+
302
+ cache.items = {
303
+ merge: false,
304
+ width: width
305
+ };
306
+
307
+ while (iterator--) {
308
+ merge = this._mergers[iterator];
309
+ merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
310
+
311
+ cache.items.merge = merge > 1 || cache.items.merge;
312
+
313
+ widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
314
+ }
315
+
316
+ this._widths = widths;
317
+ }
318
+ }, {
319
+ filter: [ 'items', 'settings' ],
320
+ run: function() {
321
+ var clones = [],
322
+ items = this._items,
323
+ settings = this.settings,
324
+ // TODO: Should be computed from number of min width items in stage
325
+ view = Math.max(settings.items * 2, 4),
326
+ size = Math.ceil(items.length / 2) * 2,
327
+ repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
328
+ append = '',
329
+ prepend = '';
330
+
331
+ repeat /= 2;
332
+
333
+ while (repeat--) {
334
+ // Switch to only using appended clones
335
+ clones.push(this.normalize(clones.length / 2, true));
336
+ append = append + items[clones[clones.length - 1]][0].outerHTML;
337
+ clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
338
+ prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
339
+ }
340
+
341
+ this._clones = clones;
342
+
343
+ $(append).addClass('cloned').appendTo(this.$stage);
344
+ $(prepend).addClass('cloned').prependTo(this.$stage);
345
+ }
346
+ }, {
347
+ filter: [ 'width', 'items', 'settings' ],
348
+ run: function() {
349
+ var rtl = this.settings.rtl ? 1 : -1,
350
+ size = this._clones.length + this._items.length,
351
+ iterator = -1,
352
+ previous = 0,
353
+ current = 0,
354
+ coordinates = [];
355
+
356
+ while (++iterator < size) {
357
+ previous = coordinates[iterator - 1] || 0;
358
+ current = this._widths[this.relative(iterator)] + this.settings.margin;
359
+ coordinates.push(previous + current * rtl);
360
+ }
361
+
362
+ this._coordinates = coordinates;
363
+ }
364
+ }, {
365
+ filter: [ 'width', 'items', 'settings' ],
366
+ run: function() {
367
+ var padding = this.settings.stagePadding,
368
+ coordinates = this._coordinates,
369
+ css = {
370
+ 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
371
+ 'padding-left': padding || '',
372
+ 'padding-right': padding || ''
373
+ };
374
+
375
+ this.$stage.css(css);
376
+ }
377
+ }, {
378
+ filter: [ 'width', 'items', 'settings' ],
379
+ run: function(cache) {
380
+ var iterator = this._coordinates.length,
381
+ grid = !this.settings.autoWidth,
382
+ items = this.$stage.children();
383
+
384
+ if (grid && cache.items.merge) {
385
+ while (iterator--) {
386
+ cache.css.width = this._widths[this.relative(iterator)];
387
+ items.eq(iterator).css(cache.css);
388
+ }
389
+ } else if (grid) {
390
+ cache.css.width = cache.items.width;
391
+ items.css(cache.css);
392
+ }
393
+ }
394
+ }, {
395
+ filter: [ 'items' ],
396
+ run: function() {
397
+ this._coordinates.length < 1 && this.$stage.removeAttr('style');
398
+ }
399
+ }, {
400
+ filter: [ 'width', 'items', 'settings' ],
401
+ run: function(cache) {
402
+ cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
403
+ cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
404
+ this.reset(cache.current);
405
+ }
406
+ }, {
407
+ filter: [ 'position' ],
408
+ run: function() {
409
+ this.animate(this.coordinates(this._current));
410
+ }
411
+ }, {
412
+ filter: [ 'width', 'position', 'items', 'settings' ],
413
+ run: function() {
414
+ var rtl = this.settings.rtl ? 1 : -1,
415
+ padding = this.settings.stagePadding * 2,
416
+ begin = this.coordinates(this.current()) + padding,
417
+ end = begin + this.width() * rtl,
418
+ inner, outer, matches = [], i, n;
419
+
420
+ for (i = 0, n = this._coordinates.length; i < n; i++) {
421
+ inner = this._coordinates[i - 1] || 0;
422
+ outer = Math.abs(this._coordinates[i]) + padding * rtl;
423
+
424
+ if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
425
+ || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
426
+ matches.push(i);
427
+ }
428
+ }
429
+
430
+ this.$stage.children('.active').removeClass('active');
431
+ this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
432
+
433
+ if (this.settings.center) {
434
+ this.$stage.children('.center').removeClass('center');
435
+ this.$stage.children().eq(this.current()).addClass('center');
436
+ }
437
+ }
438
+ } ];
439
+
440
+ /**
441
+ * Initializes the carousel.
442
+ * @protected
443
+ */
444
+ Owl.prototype.initialize = function() {
445
+ this.enter('initializing');
446
+ this.trigger('initialize');
447
+
448
+ this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
449
+
450
+ if (this.settings.autoWidth && !this.is('pre-loading')) {
451
+ var imgs, nestedSelector, width;
452
+ imgs = this.$element.find('img');
453
+ nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
454
+ width = this.$element.children(nestedSelector).width();
455
+
456
+ if (imgs.length && width <= 0) {
457
+ this.preloadAutoWidthImages(imgs);
458
+ }
459
+ }
460
+
461
+ this.$element.addClass(this.options.loadingClass);
462
+
463
+ // create stage
464
+ this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
465
+ .wrap('<div class="' + this.settings.stageOuterClass + '"/>');
466
+
467
+ // append stage
468
+ this.$element.append(this.$stage.parent());
469
+
470
+ // append content
471
+ this.replace(this.$element.children().not(this.$stage.parent()));
472
+
473
+ // check visibility
474
+ if (this.$element.is(':visible')) {
475
+ // update view
476
+ this.refresh();
477
+ } else {
478
+ // invalidate width
479
+ this.invalidate('width');
480
+ }
481
+
482
+ this.$element
483
+ .removeClass(this.options.loadingClass)
484
+ .addClass(this.options.loadedClass);
485
+
486
+ // register event handlers
487
+ this.registerEventHandlers();
488
+
489
+ this.leave('initializing');
490
+ this.trigger('initialized');
491
+ };
492
+
493
+ /**
494
+ * Setups the current settings.
495
+ * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
496
+ * @todo Support for media queries by using `matchMedia` would be nice.
497
+ * @public
498
+ */
499
+ Owl.prototype.setup = function() {
500
+ var viewport = this.viewport(),
501
+ overwrites = this.options.responsive,
502
+ match = -1,
503
+ settings = null;
504
+
505
+ if (!overwrites) {
506
+ settings = $.extend({}, this.options);
507
+ } else {
508
+ $.each(overwrites, function(breakpoint) {
509
+ if (breakpoint <= viewport && breakpoint > match) {
510
+ match = Number(breakpoint);
511
+ }
512
+ });
513
+
514
+ settings = $.extend({}, this.options, overwrites[match]);
515
+ if (typeof settings.stagePadding === 'function') {
516
+ settings.stagePadding = settings.stagePadding();
517
+ }
518
+ delete settings.responsive;
519
+
520
+ // responsive class
521
+ if (settings.responsiveClass) {
522
+ this.$element.attr('class',
523
+ this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
524
+ );
525
+ }
526
+ }
527
+
528
+ this.trigger('change', { property: { name: 'settings', value: settings } });
529
+ this._breakpoint = match;
530
+ this.settings = settings;
531
+ this.invalidate('settings');
532
+ this.trigger('changed', { property: { name: 'settings', value: this.settings } });
533
+ };
534
+
535
+ /**
536
+ * Updates option logic if necessery.
537
+ * @protected
538
+ */
539
+ Owl.prototype.optionsLogic = function() {
540
+ if (this.settings.autoWidth) {
541
+ this.settings.stagePadding = false;
542
+ this.settings.merge = false;
543
+ }
544
+ };
545
+
546
+ /**
547
+ * Prepares an item before add.
548
+ * @todo Rename event parameter `content` to `item`.
549
+ * @protected
550
+ * @returns {jQuery|HTMLElement} - The item container.
551
+ */
552
+ Owl.prototype.prepare = function(item) {
553
+ var event = this.trigger('prepare', { content: item });
554
+
555
+ if (!event.data) {
556
+ event.data = $('<' + this.settings.itemElement + '/>')
557
+ .addClass(this.options.itemClass).append(item)
558
+ }
559
+
560
+ this.trigger('prepared', { content: event.data });
561
+
562
+ return event.data;
563
+ };
564
+
565
+ /**
566
+ * Updates the view.
567
+ * @public
568
+ */
569
+ Owl.prototype.update = function() {
570
+ var i = 0,
571
+ n = this._pipe.length,
572
+ filter = $.proxy(function(p) { return this[p] }, this._invalidated),
573
+ cache = {};
574
+
575
+ while (i < n) {
576
+ if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
577
+ this._pipe[i].run(cache);
578
+ }
579
+ i++;
580
+ }
581
+
582
+ this._invalidated = {};
583
+
584
+ !this.is('valid') && this.enter('valid');
585
+ };
586
+
587
+ /**
588
+ * Gets the width of the view.
589
+ * @public
590
+ * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
591
+ * @returns {Number} - The width of the view in pixel.
592
+ */
593
+ Owl.prototype.width = function(dimension) {
594
+ dimension = dimension || Owl.Width.Default;
595
+ switch (dimension) {
596
+ case Owl.Width.Inner:
597
+ case Owl.Width.Outer:
598
+ return this._width;
599
+ default:
600
+ return this._width - this.settings.stagePadding * 2 + this.settings.margin;
601
+ }
602
+ };
603
+
604
+ /**
605
+ * Refreshes the carousel primarily for adaptive purposes.
606
+ * @public
607
+ */
608
+ Owl.prototype.refresh = function() {
609
+ this.enter('refreshing');
610
+ this.trigger('refresh');
611
+
612
+ this.setup();
613
+
614
+ this.optionsLogic();
615
+
616
+ this.$element.addClass(this.options.refreshClass);
617
+
618
+ this.update();
619
+
620
+ this.$element.removeClass(this.options.refreshClass);
621
+
622
+ this.leave('refreshing');
623
+ this.trigger('refreshed');
624
+ };
625
+
626
+ /**
627
+ * Checks window `resize` event.
628
+ * @protected
629
+ */
630
+ Owl.prototype.onThrottledResize = function() {
631
+ window.clearTimeout(this.resizeTimer);
632
+ this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
633
+ };
634
+
635
+ /**
636
+ * Checks window `resize` event.
637
+ * @protected
638
+ */
639
+ Owl.prototype.onResize = function() {
640
+ if (!this._items.length) {
641
+ return false;
642
+ }
643
+
644
+ if (this._width === this.$element.width()) {
645
+ return false;
646
+ }
647
+
648
+ if (!this.$element.is(':visible')) {
649
+ return false;
650
+ }
651
+
652
+ this.enter('resizing');
653
+
654
+ if (this.trigger('resize').isDefaultPrevented()) {
655
+ this.leave('resizing');
656
+ return false;
657
+ }
658
+
659
+ this.invalidate('width');
660
+
661
+ this.refresh();
662
+
663
+ this.leave('resizing');
664
+ this.trigger('resized');
665
+ };
666
+
667
+ /**
668
+ * Registers event handlers.
669
+ * @todo Check `msPointerEnabled`
670
+ * @todo #261
671
+ * @protected
672
+ */
673
+ Owl.prototype.registerEventHandlers = function() {
674
+ if ($.support.transition) {
675
+ this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
676
+ }
677
+
678
+ if (this.settings.responsive !== false) {
679
+ this.on(window, 'resize', this._handlers.onThrottledResize);
680
+ }
681
+
682
+ if (this.settings.mouseDrag) {
683
+ this.$element.addClass(this.options.dragClass);
684
+ this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
685
+ this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
686
+ }
687
+
688
+ if (this.settings.touchDrag){
689
+ this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
690
+ this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
691
+ }
692
+ };
693
+
694
+ /**
695
+ * Handles `touchstart` and `mousedown` events.
696
+ * @todo Horizontal swipe threshold as option
697
+ * @todo #261
698
+ * @protected
699
+ * @param {Event} event - The event arguments.
700
+ */
701
+ Owl.prototype.onDragStart = function(event) {
702
+ var stage = null;
703
+
704
+ if (event.which === 3) {
705
+ return;
706
+ }
707
+
708
+ if ($.support.transform) {
709
+ stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
710
+ stage = {
711
+ x: stage[stage.length === 16 ? 12 : 4],
712
+ y: stage[stage.length === 16 ? 13 : 5]
713
+ };
714
+ } else {
715
+ stage = this.$stage.position();
716
+ stage = {
717
+ x: this.settings.rtl ?
718
+ stage.left + this.$stage.width() - this.width() + this.settings.margin :
719
+ stage.left,
720
+ y: stage.top
721
+ };
722
+ }
723
+
724
+ if (this.is('animating')) {
725
+ $.support.transform ? this.animate(stage.x) : this.$stage.stop()
726
+ this.invalidate('position');
727
+ }
728
+
729
+ this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
730
+
731
+ this.speed(0);
732
+
733
+ this._drag.time = new Date().getTime();
734
+ this._drag.target = $(event.target);
735
+ this._drag.stage.start = stage;
736
+ this._drag.stage.current = stage;
737
+ this._drag.pointer = this.pointer(event);
738
+
739
+ $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
740
+
741
+ $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
742
+ var delta = this.difference(this._drag.pointer, this.pointer(event));
743
+
744
+ $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
745
+
746
+ if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
747
+ return;
748
+ }
749
+
750
+ event.preventDefault();
751
+
752
+ this.enter('dragging');
753
+ this.trigger('drag');
754
+ }, this));
755
+ };
756
+
757
+ /**
758
+ * Handles the `touchmove` and `mousemove` events.
759
+ * @todo #261
760
+ * @protected
761
+ * @param {Event} event - The event arguments.
762
+ */
763
+ Owl.prototype.onDragMove = function(event) {
764
+ var minimum = null,
765
+ maximum = null,
766
+ pull = null,
767
+ delta = this.difference(this._drag.pointer, this.pointer(event)),
768
+ stage = this.difference(this._drag.stage.start, delta);
769
+
770
+ if (!this.is('dragging')) {
771
+ return;
772
+ }
773
+
774
+ event.preventDefault();
775
+
776
+ if (this.settings.loop) {
777
+ minimum = this.coordinates(this.minimum());
778
+ maximum = this.coordinates(this.maximum() + 1) - minimum;
779
+ stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
780
+ } else {
781
+ minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
782
+ maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
783
+ pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
784
+ stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
785
+ }
786
+
787
+ this._drag.stage.current = stage;
788
+
789
+ this.animate(stage.x);
790
+ };
791
+
792
+ /**
793
+ * Handles the `touchend` and `mouseup` events.
794
+ * @todo #261
795
+ * @todo Threshold for click event
796
+ * @protected
797
+ * @param {Event} event - The event arguments.
798
+ */
799
+ Owl.prototype.onDragEnd = function(event) {
800
+ var delta = this.difference(this._drag.pointer, this.pointer(event)),
801
+ stage = this._drag.stage.current,
802
+ direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
803
+
804
+ $(document).off('.owl.core');
805
+
806
+ this.$element.removeClass(this.options.grabClass);
807
+
808
+ if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
809
+ this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
810
+ this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
811
+ this.invalidate('position');
812
+ this.update();
813
+
814
+ this._drag.direction = direction;
815
+
816
+ if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
817
+ this._drag.target.one('click.owl.core', function() { return false; });
818
+ }
819
+ }
820
+
821
+ if (!this.is('dragging')) {
822
+ return;
823
+ }
824
+
825
+ this.leave('dragging');
826
+ this.trigger('dragged');
827
+ };
828
+
829
+ /**
830
+ * Gets absolute position of the closest item for a coordinate.
831
+ * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
832
+ * @protected
833
+ * @param {Number} coordinate - The coordinate in pixel.
834
+ * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
835
+ * @return {Number} - The absolute position of the closest item.
836
+ */
837
+ Owl.prototype.closest = function(coordinate, direction) {
838
+ var position = -1,
839
+ pull = 30,
840
+ width = this.width(),
841
+ coordinates = this.coordinates();
842
+
843
+ if (!this.settings.freeDrag) {
844
+ // check closest item
845
+ $.each(coordinates, $.proxy(function(index, value) {
846
+ // on a left pull, check on current index
847
+ if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
848
+ position = index;
849
+ // on a right pull, check on previous index
850
+ // to do so, subtract width from value and set position = index + 1
851
+ } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
852
+ position = index + 1;
853
+ } else if (this.op(coordinate, '<', value)
854
+ && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
855
+ position = direction === 'left' ? index + 1 : index;
856
+ }
857
+ return position === -1;
858
+ }, this));
859
+ }
860
+
861
+ if (!this.settings.loop) {
862
+ // non loop boundries
863
+ if (this.op(coordinate, '>', coordinates[this.minimum()])) {
864
+ position = coordinate = this.minimum();
865
+ } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
866
+ position = coordinate = this.maximum();
867
+ }
868
+ }
869
+
870
+ return position;
871
+ };
872
+
873
+ /**
874
+ * Animates the stage.
875
+ * @todo #270
876
+ * @public
877
+ * @param {Number} coordinate - The coordinate in pixels.
878
+ */
879
+ Owl.prototype.animate = function(coordinate) {
880
+ var animate = this.speed() > 0;
881
+
882
+ this.is('animating') && this.onTransitionEnd();
883
+
884
+ if (animate) {
885
+ this.enter('animating');
886
+ this.trigger('translate');
887
+ }
888
+
889
+ if ($.support.transform3d && $.support.transition) {
890
+ this.$stage.css({
891
+ transform: 'translate3d(' + coordinate + 'px,0px,0px)',
892
+ transition: (this.speed() / 1000) + 's'
893
+ });
894
+ } else if (animate) {
895
+ this.$stage.animate({
896
+ left: coordinate + 'px'
897
+ }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
898
+ } else {
899
+ this.$stage.css({
900
+ left: coordinate + 'px'
901
+ });
902
+ }
903
+ };
904
+
905
+ /**
906
+ * Checks whether the carousel is in a specific state or not.
907
+ * @param {String} state - The state to check.
908
+ * @returns {Boolean} - The flag which indicates if the carousel is busy.
909
+ */
910
+ Owl.prototype.is = function(state) {
911
+ return this._states.current[state] && this._states.current[state] > 0;
912
+ };
913
+
914
+ /**
915
+ * Sets the absolute position of the current item.
916
+ * @public
917
+ * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
918
+ * @returns {Number} - The absolute position of the current item.
919
+ */
920
+ Owl.prototype.current = function(position) {
921
+ if (position === undefined) {
922
+ return this._current;
923
+ }
924
+
925
+ if (this._items.length === 0) {
926
+ return undefined;
927
+ }
928
+
929
+ position = this.normalize(position);
930
+
931
+ if (this._current !== position) {
932
+ var event = this.trigger('change', { property: { name: 'position', value: position } });
933
+
934
+ if (event.data !== undefined) {
935
+ position = this.normalize(event.data);
936
+ }
937
+
938
+ this._current = position;
939
+
940
+ this.invalidate('position');
941
+
942
+ this.trigger('changed', { property: { name: 'position', value: this._current } });
943
+ }
944
+
945
+ return this._current;
946
+ };
947
+
948
+ /**
949
+ * Invalidates the given part of the update routine.
950
+ * @param {String} [part] - The part to invalidate.
951
+ * @returns {Array.<String>} - The invalidated parts.
952
+ */
953
+ Owl.prototype.invalidate = function(part) {
954
+ if ($.type(part) === 'string') {
955
+ this._invalidated[part] = true;
956
+ this.is('valid') && this.leave('valid');
957
+ }
958
+ return $.map(this._invalidated, function(v, i) { return i });
959
+ };
960
+
961
+ /**
962
+ * Resets the absolute position of the current item.
963
+ * @public
964
+ * @param {Number} position - The absolute position of the new item.
965
+ */
966
+ Owl.prototype.reset = function(position) {
967
+ position = this.normalize(position);
968
+
969
+ if (position === undefined) {
970
+ return;
971
+ }
972
+
973
+ this._speed = 0;
974
+ this._current = position;
975
+
976
+ this.suppress([ 'translate', 'translated' ]);
977
+
978
+ this.animate(this.coordinates(position));
979
+
980
+ this.release([ 'translate', 'translated' ]);
981
+ };
982
+
983
+ /**
984
+ * Normalizes an absolute or a relative position of an item.
985
+ * @public
986
+ * @param {Number} position - The absolute or relative position to normalize.
987
+ * @param {Boolean} [relative=false] - Whether the given position is relative or not.
988
+ * @returns {Number} - The normalized position.
989
+ */
990
+ Owl.prototype.normalize = function(position, relative) {
991
+ var n = this._items.length,
992
+ m = relative ? 0 : this._clones.length;
993
+
994
+ if (!this.isNumeric(position) || n < 1) {
995
+ position = undefined;
996
+ } else if (position < 0 || position >= n + m) {
997
+ position = ((position - m / 2) % n + n) % n + m / 2;
998
+ }
999
+
1000
+ return position;
1001
+ };
1002
+
1003
+ /**
1004
+ * Converts an absolute position of an item into a relative one.
1005
+ * @public
1006
+ * @param {Number} position - The absolute position to convert.
1007
+ * @returns {Number} - The converted position.
1008
+ */
1009
+ Owl.prototype.relative = function(position) {
1010
+ position -= this._clones.length / 2;
1011
+ return this.normalize(position, true);
1012
+ };
1013
+
1014
+ /**
1015
+ * Gets the maximum position for the current item.
1016
+ * @public
1017
+ * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1018
+ * @returns {Number}
1019
+ */
1020
+ Owl.prototype.maximum = function(relative) {
1021
+ var settings = this.settings,
1022
+ maximum = this._coordinates.length,
1023
+ iterator,
1024
+ reciprocalItemsWidth,
1025
+ elementWidth;
1026
+
1027
+ if (settings.loop) {
1028
+ maximum = this._clones.length / 2 + this._items.length - 1;
1029
+ } else if (settings.autoWidth || settings.merge) {
1030
+ iterator = this._items.length;
1031
+ reciprocalItemsWidth = this._items[--iterator].width();
1032
+ elementWidth = this.$element.width();
1033
+ while (iterator--) {
1034
+ reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
1035
+ if (reciprocalItemsWidth > elementWidth) {
1036
+ break;
1037
+ }
1038
+ }
1039
+ maximum = iterator + 1;
1040
+ } else if (settings.center) {
1041
+ maximum = this._items.length - 1;
1042
+ } else {
1043
+ maximum = this._items.length - settings.items;
1044
+ }
1045
+
1046
+ if (relative) {
1047
+ maximum -= this._clones.length / 2;
1048
+ }
1049
+
1050
+ return Math.max(maximum, 0);
1051
+ };
1052
+
1053
+ /**
1054
+ * Gets the minimum position for the current item.
1055
+ * @public
1056
+ * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1057
+ * @returns {Number}
1058
+ */
1059
+ Owl.prototype.minimum = function(relative) {
1060
+ return relative ? 0 : this._clones.length / 2;
1061
+ };
1062
+
1063
+ /**
1064
+ * Gets an item at the specified relative position.
1065
+ * @public
1066
+ * @param {Number} [position] - The relative position of the item.
1067
+ * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1068
+ */
1069
+ Owl.prototype.items = function(position) {
1070
+ if (position === undefined) {
1071
+ return this._items.slice();
1072
+ }
1073
+
1074
+ position = this.normalize(position, true);
1075
+ return this._items[position];
1076
+ };
1077
+
1078
+ /**
1079
+ * Gets an item at the specified relative position.
1080
+ * @public
1081
+ * @param {Number} [position] - The relative position of the item.
1082
+ * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1083
+ */
1084
+ Owl.prototype.mergers = function(position) {
1085
+ if (position === undefined) {
1086
+ return this._mergers.slice();
1087
+ }
1088
+
1089
+ position = this.normalize(position, true);
1090
+ return this._mergers[position];
1091
+ };
1092
+
1093
+ /**
1094
+ * Gets the absolute positions of clones for an item.
1095
+ * @public
1096
+ * @param {Number} [position] - The relative position of the item.
1097
+ * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
1098
+ */
1099
+ Owl.prototype.clones = function(position) {
1100
+ var odd = this._clones.length / 2,
1101
+ even = odd + this._items.length,
1102
+ map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
1103
+
1104
+ if (position === undefined) {
1105
+ return $.map(this._clones, function(v, i) { return map(i) });
1106
+ }
1107
+
1108
+ return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
1109
+ };
1110
+
1111
+ /**
1112
+ * Sets the current animation speed.
1113
+ * @public
1114
+ * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
1115
+ * @returns {Number} - The current animation speed in milliseconds.
1116
+ */
1117
+ Owl.prototype.speed = function(speed) {
1118
+ if (speed !== undefined) {
1119
+ this._speed = speed;
1120
+ }
1121
+
1122
+ return this._speed;
1123
+ };
1124
+
1125
+ /**
1126
+ * Gets the coordinate of an item.
1127
+ * @todo The name of this method is missleanding.
1128
+ * @public
1129
+ * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
1130
+ * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
1131
+ */
1132
+ Owl.prototype.coordinates = function(position) {
1133
+ var multiplier = 1,
1134
+ newPosition = position - 1,
1135
+ coordinate;
1136
+
1137
+ if (position === undefined) {
1138
+ return $.map(this._coordinates, $.proxy(function(coordinate, index) {
1139
+ return this.coordinates(index);
1140
+ }, this));
1141
+ }
1142
+
1143
+ if (this.settings.center) {
1144
+ if (this.settings.rtl) {
1145
+ multiplier = -1;
1146
+ newPosition = position + 1;
1147
+ }
1148
+
1149
+ coordinate = this._coordinates[position];
1150
+ coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
1151
+ } else {
1152
+ coordinate = this._coordinates[newPosition] || 0;
1153
+ }
1154
+
1155
+ coordinate = Math.ceil(coordinate);
1156
+
1157
+ return coordinate;
1158
+ };
1159
+
1160
+ /**
1161
+ * Calculates the speed for a translation.
1162
+ * @protected
1163
+ * @param {Number} from - The absolute position of the start item.
1164
+ * @param {Number} to - The absolute position of the target item.
1165
+ * @param {Number} [factor=undefined] - The time factor in milliseconds.
1166
+ * @returns {Number} - The time in milliseconds for the translation.
1167
+ */
1168
+ Owl.prototype.duration = function(from, to, factor) {
1169
+ if (factor === 0) {
1170
+ return 0;
1171
+ }
1172
+
1173
+ return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
1174
+ };
1175
+
1176
+ /**
1177
+ * Slides to the specified item.
1178
+ * @public
1179
+ * @param {Number} position - The position of the item.
1180
+ * @param {Number} [speed] - The time in milliseconds for the transition.
1181
+ */
1182
+ Owl.prototype.to = function(position, speed) {
1183
+ var current = this.current(),
1184
+ revert = null,
1185
+ distance = position - this.relative(current),
1186
+ direction = (distance > 0) - (distance < 0),
1187
+ items = this._items.length,
1188
+ minimum = this.minimum(),
1189
+ maximum = this.maximum();
1190
+
1191
+ if (this.settings.loop) {
1192
+ if (!this.settings.rewind && Math.abs(distance) > items / 2) {
1193
+ distance += direction * -1 * items;
1194
+ }
1195
+
1196
+ position = current + distance;
1197
+ revert = ((position - minimum) % items + items) % items + minimum;
1198
+
1199
+ if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
1200
+ current = revert - distance;
1201
+ position = revert;
1202
+ this.reset(current);
1203
+ }
1204
+ } else if (this.settings.rewind) {
1205
+ maximum += 1;
1206
+ position = (position % maximum + maximum) % maximum;
1207
+ } else {
1208
+ position = Math.max(minimum, Math.min(maximum, position));
1209
+ }
1210
+
1211
+ this.speed(this.duration(current, position, speed));
1212
+ this.current(position);
1213
+
1214
+ if (this.$element.is(':visible')) {
1215
+ this.update();
1216
+ }
1217
+ };
1218
+
1219
+ /**
1220
+ * Slides to the next item.
1221
+ * @public
1222
+ * @param {Number} [speed] - The time in milliseconds for the transition.
1223
+ */
1224
+ Owl.prototype.next = function(speed) {
1225
+ speed = speed || false;
1226
+ this.to(this.relative(this.current()) + 1, speed);
1227
+ };
1228
+
1229
+ /**
1230
+ * Slides to the previous item.
1231
+ * @public
1232
+ * @param {Number} [speed] - The time in milliseconds for the transition.
1233
+ */
1234
+ Owl.prototype.prev = function(speed) {
1235
+ speed = speed || false;
1236
+ this.to(this.relative(this.current()) - 1, speed);
1237
+ };
1238
+
1239
+ /**
1240
+ * Handles the end of an animation.
1241
+ * @protected
1242
+ * @param {Event} event - The event arguments.
1243
+ */
1244
+ Owl.prototype.onTransitionEnd = function(event) {
1245
+
1246
+ // if css2 animation then event object is undefined
1247
+ if (event !== undefined) {
1248
+ event.stopPropagation();
1249
+
1250
+ // Catch only owl-stage transitionEnd event
1251
+ if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
1252
+ return false;
1253
+ }
1254
+ }
1255
+
1256
+ this.leave('animating');
1257
+ this.trigger('translated');
1258
+ };
1259
+
1260
+ /**
1261
+ * Gets viewport width.
1262
+ * @protected
1263
+ * @return {Number} - The width in pixel.
1264
+ */
1265
+ Owl.prototype.viewport = function() {
1266
+ var width;
1267
+ if (this.options.responsiveBaseElement !== window) {
1268
+ width = $(this.options.responsiveBaseElement).width();
1269
+ } else if (window.innerWidth) {
1270
+ width = window.innerWidth;
1271
+ } else if (document.documentElement && document.documentElement.clientWidth) {
1272
+ width = document.documentElement.clientWidth;
1273
+ } else {
1274
+ throw 'Can not detect viewport width.';
1275
+ }
1276
+ return width;
1277
+ };
1278
+
1279
+ /**
1280
+ * Replaces the current content.
1281
+ * @public
1282
+ * @param {HTMLElement|jQuery|String} content - The new content.
1283
+ */
1284
+ Owl.prototype.replace = function(content) {
1285
+ this.$stage.empty();
1286
+ this._items = [];
1287
+
1288
+ if (content) {
1289
+ content = (content instanceof jQuery) ? content : $(content);
1290
+ }
1291
+
1292
+ if (this.settings.nestedItemSelector) {
1293
+ content = content.find('.' + this.settings.nestedItemSelector);
1294
+ }
1295
+
1296
+ content.filter(function() {
1297
+ return this.nodeType === 1;
1298
+ }).each($.proxy(function(index, item) {
1299
+ item = this.prepare(item);
1300
+ this.$stage.append(item);
1301
+ this._items.push(item);
1302
+ this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1303
+ }, this));
1304
+
1305
+ this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
1306
+
1307
+ this.invalidate('items');
1308
+ };
1309
+
1310
+ /**
1311
+ * Adds an item.
1312
+ * @todo Use `item` instead of `content` for the event arguments.
1313
+ * @public
1314
+ * @param {HTMLElement|jQuery|String} content - The item content to add.
1315
+ * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
1316
+ */
1317
+ Owl.prototype.add = function(content, position) {
1318
+ var current = this.relative(this._current);
1319
+
1320
+ position = position === undefined ? this._items.length : this.normalize(position, true);
1321
+ content = content instanceof jQuery ? content : $(content);
1322
+
1323
+ this.trigger('add', { content: content, position: position });
1324
+
1325
+ content = this.prepare(content);
1326
+
1327
+ if (this._items.length === 0 || position === this._items.length) {
1328
+ this._items.length === 0 && this.$stage.append(content);
1329
+ this._items.length !== 0 && this._items[position - 1].after(content);
1330
+ this._items.push(content);
1331
+ this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1332
+ } else {
1333
+ this._items[position].before(content);
1334
+ this._items.splice(position, 0, content);
1335
+ this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1336
+ }
1337
+
1338
+ this._items[current] && this.reset(this._items[current].index());
1339
+
1340
+ this.invalidate('items');
1341
+
1342
+ this.trigger('added', { content: content, position: position });
1343
+ };
1344
+
1345
+ /**
1346
+ * Removes an item by its position.
1347
+ * @todo Use `item` instead of `content` for the event arguments.
1348
+ * @public
1349
+ * @param {Number} position - The relative position of the item to remove.
1350
+ */
1351
+ Owl.prototype.remove = function(position) {
1352
+ position = this.normalize(position, true);
1353
+
1354
+ if (position === undefined) {
1355
+ return;
1356
+ }
1357
+
1358
+ this.trigger('remove', { content: this._items[position], position: position });
1359
+
1360
+ this._items[position].remove();
1361
+ this._items.splice(position, 1);
1362
+ this._mergers.splice(position, 1);
1363
+
1364
+ this.invalidate('items');
1365
+
1366
+ this.trigger('removed', { content: null, position: position });
1367
+ };
1368
+
1369
+ /**
1370
+ * Preloads images with auto width.
1371
+ * @todo Replace by a more generic approach
1372
+ * @protected
1373
+ */
1374
+ Owl.prototype.preloadAutoWidthImages = function(images) {
1375
+ images.each($.proxy(function(i, element) {
1376
+ this.enter('pre-loading');
1377
+ element = $(element);
1378
+ $(new Image()).one('load', $.proxy(function(e) {
1379
+ element.attr('src', e.target.src);
1380
+ element.css('opacity', 1);
1381
+ this.leave('pre-loading');
1382
+ !this.is('pre-loading') && !this.is('initializing') && this.refresh();
1383
+ }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
1384
+ }, this));
1385
+ };
1386
+
1387
+ /**
1388
+ * Destroys the carousel.
1389
+ * @public
1390
+ */
1391
+ Owl.prototype.destroy = function() {
1392
+
1393
+ this.$element.off('.owl.core');
1394
+ this.$stage.off('.owl.core');
1395
+ $(document).off('.owl.core');
1396
+
1397
+ if (this.settings.responsive !== false) {
1398
+ window.clearTimeout(this.resizeTimer);
1399
+ this.off(window, 'resize', this._handlers.onThrottledResize);
1400
+ }
1401
+
1402
+ for (var i in this._plugins) {
1403
+ this._plugins[i].destroy();
1404
+ }
1405
+
1406
+ this.$stage.children('.cloned').remove();
1407
+
1408
+ this.$stage.unwrap();
1409
+ this.$stage.children().contents().unwrap();
1410
+ this.$stage.children().unwrap();
1411
+
1412
+ this.$element
1413
+ .removeClass(this.options.refreshClass)
1414
+ .removeClass(this.options.loadingClass)
1415
+ .removeClass(this.options.loadedClass)
1416
+ .removeClass(this.options.rtlClass)
1417
+ .removeClass(this.options.dragClass)
1418
+ .removeClass(this.options.grabClass)
1419
+ .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
1420
+ .removeData('owl.carousel');
1421
+ };
1422
+
1423
+ /**
1424
+ * Operators to calculate right-to-left and left-to-right.
1425
+ * @protected
1426
+ * @param {Number} [a] - The left side operand.
1427
+ * @param {String} [o] - The operator.
1428
+ * @param {Number} [b] - The right side operand.
1429
+ */
1430
+ Owl.prototype.op = function(a, o, b) {
1431
+ var rtl = this.settings.rtl;
1432
+ switch (o) {
1433
+ case '<':
1434
+ return rtl ? a > b : a < b;
1435
+ case '>':
1436
+ return rtl ? a < b : a > b;
1437
+ case '>=':
1438
+ return rtl ? a <= b : a >= b;
1439
+ case '<=':
1440
+ return rtl ? a >= b : a <= b;
1441
+ default:
1442
+ break;
1443
+ }
1444
+ };
1445
+
1446
+ /**
1447
+ * Attaches to an internal event.
1448
+ * @protected
1449
+ * @param {HTMLElement} element - The event source.
1450
+ * @param {String} event - The event name.
1451
+ * @param {Function} listener - The event handler to attach.
1452
+ * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
1453
+ */
1454
+ Owl.prototype.on = function(element, event, listener, capture) {
1455
+ if (element.addEventListener) {
1456
+ element.addEventListener(event, listener, capture);
1457
+ } else if (element.attachEvent) {
1458
+ element.attachEvent('on' + event, listener);
1459
+ }
1460
+ };
1461
+
1462
+ /**
1463
+ * Detaches from an internal event.
1464
+ * @protected
1465
+ * @param {HTMLElement} element - The event source.
1466
+ * @param {String} event - The event name.
1467
+ * @param {Function} listener - The attached event handler to detach.
1468
+ * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
1469
+ */
1470
+ Owl.prototype.off = function(element, event, listener, capture) {
1471
+ if (element.removeEventListener) {
1472
+ element.removeEventListener(event, listener, capture);
1473
+ } else if (element.detachEvent) {
1474
+ element.detachEvent('on' + event, listener);
1475
+ }
1476
+ };
1477
+
1478
+ /**
1479
+ * Triggers a public event.
1480
+ * @todo Remove `status`, `relatedTarget` should be used instead.
1481
+ * @protected
1482
+ * @param {String} name - The event name.
1483
+ * @param {*} [data=null] - The event data.
1484
+ * @param {String} [namespace=carousel] - The event namespace.
1485
+ * @param {String} [state] - The state which is associated with the event.
1486
+ * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
1487
+ * @returns {Event} - The event arguments.
1488
+ */
1489
+ Owl.prototype.trigger = function(name, data, namespace, state, enter) {
1490
+ var status = {
1491
+ item: { count: this._items.length, index: this.current() }
1492
+ }, handler = $.camelCase(
1493
+ $.grep([ 'on', name, namespace ], function(v) { return v })
1494
+ .join('-').toLowerCase()
1495
+ ), event = $.Event(
1496
+ [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
1497
+ $.extend({ relatedTarget: this }, status, data)
1498
+ );
1499
+
1500
+ if (!this._supress[name]) {
1501
+ $.each(this._plugins, function(name, plugin) {
1502
+ if (plugin.onTrigger) {
1503
+ plugin.onTrigger(event);
1504
+ }
1505
+ });
1506
+
1507
+ this.register({ type: Owl.Type.Event, name: name });
1508
+ this.$element.trigger(event);
1509
+
1510
+ if (this.settings && typeof this.settings[handler] === 'function') {
1511
+ this.settings[handler].call(this, event);
1512
+ }
1513
+ }
1514
+
1515
+ return event;
1516
+ };
1517
+
1518
+ /**
1519
+ * Enters a state.
1520
+ * @param name - The state name.
1521
+ */
1522
+ Owl.prototype.enter = function(name) {
1523
+ $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1524
+ if (this._states.current[name] === undefined) {
1525
+ this._states.current[name] = 0;
1526
+ }
1527
+
1528
+ this._states.current[name]++;
1529
+ }, this));
1530
+ };
1531
+
1532
+ /**
1533
+ * Leaves a state.
1534
+ * @param name - The state name.
1535
+ */
1536
+ Owl.prototype.leave = function(name) {
1537
+ $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1538
+ this._states.current[name]--;
1539
+ }, this));
1540
+ };
1541
+
1542
+ /**
1543
+ * Registers an event or state.
1544
+ * @public
1545
+ * @param {Object} object - The event or state to register.
1546
+ */
1547
+ Owl.prototype.register = function(object) {
1548
+ if (object.type === Owl.Type.Event) {
1549
+ if (!$.event.special[object.name]) {
1550
+ $.event.special[object.name] = {};
1551
+ }
1552
+
1553
+ if (!$.event.special[object.name].owl) {
1554
+ var _default = $.event.special[object.name]._default;
1555
+ $.event.special[object.name]._default = function(e) {
1556
+ if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
1557
+ return _default.apply(this, arguments);
1558
+ }
1559
+ return e.namespace && e.namespace.indexOf('owl') > -1;
1560
+ };
1561
+ $.event.special[object.name].owl = true;
1562
+ }
1563
+ } else if (object.type === Owl.Type.State) {
1564
+ if (!this._states.tags[object.name]) {
1565
+ this._states.tags[object.name] = object.tags;
1566
+ } else {
1567
+ this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
1568
+ }
1569
+
1570
+ this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
1571
+ return $.inArray(tag, this._states.tags[object.name]) === i;
1572
+ }, this));
1573
+ }
1574
+ };
1575
+
1576
+ /**
1577
+ * Suppresses events.
1578
+ * @protected
1579
+ * @param {Array.<String>} events - The events to suppress.
1580
+ */
1581
+ Owl.prototype.suppress = function(events) {
1582
+ $.each(events, $.proxy(function(index, event) {
1583
+ this._supress[event] = true;
1584
+ }, this));
1585
+ };
1586
+
1587
+ /**
1588
+ * Releases suppressed events.
1589
+ * @protected
1590
+ * @param {Array.<String>} events - The events to release.
1591
+ */
1592
+ Owl.prototype.release = function(events) {
1593
+ $.each(events, $.proxy(function(index, event) {
1594
+ delete this._supress[event];
1595
+ }, this));
1596
+ };
1597
+
1598
+ /**
1599
+ * Gets unified pointer coordinates from event.
1600
+ * @todo #261
1601
+ * @protected
1602
+ * @param {Event} - The `mousedown` or `touchstart` event.
1603
+ * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
1604
+ */
1605
+ Owl.prototype.pointer = function(event) {
1606
+ var result = { x: null, y: null };
1607
+
1608
+ event = event.originalEvent || event || window.event;
1609
+
1610
+ event = event.touches && event.touches.length ?
1611
+ event.touches[0] : event.changedTouches && event.changedTouches.length ?
1612
+ event.changedTouches[0] : event;
1613
+
1614
+ if (event.pageX) {
1615
+ result.x = event.pageX;
1616
+ result.y = event.pageY;
1617
+ } else {
1618
+ result.x = event.clientX;
1619
+ result.y = event.clientY;
1620
+ }
1621
+
1622
+ return result;
1623
+ };
1624
+
1625
+ /**
1626
+ * Determines if the input is a Number or something that can be coerced to a Number
1627
+ * @protected
1628
+ * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
1629
+ * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
1630
+ */
1631
+ Owl.prototype.isNumeric = function(number) {
1632
+ return !isNaN(parseFloat(number));
1633
+ };
1634
+
1635
+ /**
1636
+ * Gets the difference of two vectors.
1637
+ * @todo #261
1638
+ * @protected
1639
+ * @param {Object} - The first vector.
1640
+ * @param {Object} - The second vector.
1641
+ * @returns {Object} - The difference.
1642
+ */
1643
+ Owl.prototype.difference = function(first, second) {
1644
+ return {
1645
+ x: first.x - second.x,
1646
+ y: first.y - second.y
1647
+ };
1648
+ };
1649
+
1650
+ /**
1651
+ * The jQuery Plugin for the Owl Carousel
1652
+ * @todo Navigation plugin `next` and `prev`
1653
+ * @public
1654
+ */
1655
+ $.fn.owlCarousel = function(option) {
1656
+ var args = Array.prototype.slice.call(arguments, 1);
1657
+
1658
+ return this.each(function() {
1659
+ var $this = $(this),
1660
+ data = $this.data('owl.carousel');
1661
+
1662
+ if (!data) {
1663
+ data = new Owl(this, typeof option == 'object' && option);
1664
+ $this.data('owl.carousel', data);
1665
+
1666
+ $.each([
1667
+ 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
1668
+ ], function(i, event) {
1669
+ data.register({ type: Owl.Type.Event, name: event });
1670
+ data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
1671
+ if (e.namespace && e.relatedTarget !== this) {
1672
+ this.suppress([ event ]);
1673
+ data[event].apply(this, [].slice.call(arguments, 1));
1674
+ this.release([ event ]);
1675
+ }
1676
+ }, data));
1677
+ });
1678
+ }
1679
+
1680
+ if (typeof option == 'string' && option.charAt(0) !== '_') {
1681
+ data[option].apply(data, args);
1682
+ }
1683
+ });
1684
+ };
1685
+
1686
+ /**
1687
+ * The constructor for the jQuery Plugin
1688
+ * @public
1689
+ */
1690
+ $.fn.owlCarousel.Constructor = Owl;
1691
+
1692
+ })(window.Zepto || window.jQuery, window, document);