UNPKG

97 kBJavaScriptView Raw
1/*!
2 * Glide.js v3.5.2
3 * (c) 2013-2021 Jędrzej Chałubek (https://github.com/jedrzejchalubek/)
4 * Released under the MIT License.
5 */
6
7(function (global, factory) {
8 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
9 typeof define === 'function' && define.amd ? define(factory) :
10 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Glide = factory());
11})(this, (function () { 'use strict';
12
13 function _typeof(obj) {
14 "@babel/helpers - typeof";
15
16 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
17 _typeof = function (obj) {
18 return typeof obj;
19 };
20 } else {
21 _typeof = function (obj) {
22 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
23 };
24 }
25
26 return _typeof(obj);
27 }
28
29 function _classCallCheck(instance, Constructor) {
30 if (!(instance instanceof Constructor)) {
31 throw new TypeError("Cannot call a class as a function");
32 }
33 }
34
35 function _defineProperties(target, props) {
36 for (var i = 0; i < props.length; i++) {
37 var descriptor = props[i];
38 descriptor.enumerable = descriptor.enumerable || false;
39 descriptor.configurable = true;
40 if ("value" in descriptor) descriptor.writable = true;
41 Object.defineProperty(target, descriptor.key, descriptor);
42 }
43 }
44
45 function _createClass(Constructor, protoProps, staticProps) {
46 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
47 if (staticProps) _defineProperties(Constructor, staticProps);
48 return Constructor;
49 }
50
51 function _inherits(subClass, superClass) {
52 if (typeof superClass !== "function" && superClass !== null) {
53 throw new TypeError("Super expression must either be null or a function");
54 }
55
56 subClass.prototype = Object.create(superClass && superClass.prototype, {
57 constructor: {
58 value: subClass,
59 writable: true,
60 configurable: true
61 }
62 });
63 if (superClass) _setPrototypeOf(subClass, superClass);
64 }
65
66 function _getPrototypeOf(o) {
67 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
68 return o.__proto__ || Object.getPrototypeOf(o);
69 };
70 return _getPrototypeOf(o);
71 }
72
73 function _setPrototypeOf(o, p) {
74 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
75 o.__proto__ = p;
76 return o;
77 };
78
79 return _setPrototypeOf(o, p);
80 }
81
82 function _isNativeReflectConstruct() {
83 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
84 if (Reflect.construct.sham) return false;
85 if (typeof Proxy === "function") return true;
86
87 try {
88 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
89 return true;
90 } catch (e) {
91 return false;
92 }
93 }
94
95 function _assertThisInitialized(self) {
96 if (self === void 0) {
97 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
98 }
99
100 return self;
101 }
102
103 function _possibleConstructorReturn(self, call) {
104 if (call && (typeof call === "object" || typeof call === "function")) {
105 return call;
106 } else if (call !== void 0) {
107 throw new TypeError("Derived constructors may only return object or undefined");
108 }
109
110 return _assertThisInitialized(self);
111 }
112
113 function _createSuper(Derived) {
114 var hasNativeReflectConstruct = _isNativeReflectConstruct();
115
116 return function _createSuperInternal() {
117 var Super = _getPrototypeOf(Derived),
118 result;
119
120 if (hasNativeReflectConstruct) {
121 var NewTarget = _getPrototypeOf(this).constructor;
122
123 result = Reflect.construct(Super, arguments, NewTarget);
124 } else {
125 result = Super.apply(this, arguments);
126 }
127
128 return _possibleConstructorReturn(this, result);
129 };
130 }
131
132 function _superPropBase(object, property) {
133 while (!Object.prototype.hasOwnProperty.call(object, property)) {
134 object = _getPrototypeOf(object);
135 if (object === null) break;
136 }
137
138 return object;
139 }
140
141 function _get() {
142 if (typeof Reflect !== "undefined" && Reflect.get) {
143 _get = Reflect.get;
144 } else {
145 _get = function _get(target, property, receiver) {
146 var base = _superPropBase(target, property);
147
148 if (!base) return;
149 var desc = Object.getOwnPropertyDescriptor(base, property);
150
151 if (desc.get) {
152 return desc.get.call(arguments.length < 3 ? target : receiver);
153 }
154
155 return desc.value;
156 };
157 }
158
159 return _get.apply(this, arguments);
160 }
161
162 var defaults = {
163 /**
164 * Type of the movement.
165 *
166 * Available types:
167 * `slider` - Rewinds slider to the start/end when it reaches the first or last slide.
168 * `carousel` - Changes slides without starting over when it reaches the first or last slide.
169 *
170 * @type {String}
171 */
172 type: 'slider',
173
174 /**
175 * Start at specific slide number defined with zero-based index.
176 *
177 * @type {Number}
178 */
179 startAt: 0,
180
181 /**
182 * A number of slides visible on the single viewport.
183 *
184 * @type {Number}
185 */
186 perView: 1,
187
188 /**
189 * Focus currently active slide at a specified position in the track.
190 *
191 * Available inputs:
192 * `center` - Current slide will be always focused at the center of a track.
193 * `0,1,2,3...` - Current slide will be focused on the specified zero-based index.
194 *
195 * @type {String|Number}
196 */
197 focusAt: 0,
198
199 /**
200 * A size of the gap added between slides.
201 *
202 * @type {Number}
203 */
204 gap: 10,
205
206 /**
207 * Change slides after a specified interval. Use `false` for turning off autoplay.
208 *
209 * @type {Number|Boolean}
210 */
211 autoplay: false,
212
213 /**
214 * Stop autoplay on mouseover event.
215 *
216 * @type {Boolean}
217 */
218 hoverpause: true,
219
220 /**
221 * Allow for changing slides with left and right keyboard arrows.
222 *
223 * @type {Boolean}
224 */
225 keyboard: true,
226
227 /**
228 * Stop running `perView` number of slides from the end. Use this
229 * option if you don't want to have an empty space after
230 * a slider. Works only with `slider` type and a
231 * non-centered `focusAt` setting.
232 *
233 * @type {Boolean}
234 */
235 bound: false,
236
237 /**
238 * Minimal swipe distance needed to change the slide. Use `false` for turning off a swiping.
239 *
240 * @type {Number|Boolean}
241 */
242 swipeThreshold: 80,
243
244 /**
245 * Minimal mouse drag distance needed to change the slide. Use `false` for turning off a dragging.
246 *
247 * @type {Number|Boolean}
248 */
249 dragThreshold: 120,
250
251 /**
252 * A number of slides moved on single swipe.
253 *
254 * Available types:
255 * `` - Moves slider by one slide per swipe
256 * `|` - Moves slider between views per swipe (number of slides defined in `perView` options)
257 *
258 * @type {String}
259 */
260 perSwipe: '',
261
262 /**
263 * Moving distance ratio of the slides on a swiping and dragging.
264 *
265 * @type {Number}
266 */
267 touchRatio: 0.5,
268
269 /**
270 * Angle required to activate slides moving on swiping or dragging.
271 *
272 * @type {Number}
273 */
274 touchAngle: 45,
275
276 /**
277 * Duration of the animation in milliseconds.
278 *
279 * @type {Number}
280 */
281 animationDuration: 400,
282
283 /**
284 * Allows looping the `slider` type. Slider will rewind to the first/last slide when it's at the start/end.
285 *
286 * @type {Boolean}
287 */
288 rewind: true,
289
290 /**
291 * Duration of the rewinding animation of the `slider` type in milliseconds.
292 *
293 * @type {Number}
294 */
295 rewindDuration: 800,
296
297 /**
298 * Easing function for the animation.
299 *
300 * @type {String}
301 */
302 animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)',
303
304 /**
305 * Wait for the animation to finish until the next user input can be processed
306 *
307 * @type {boolean}
308 */
309 waitForTransition: true,
310
311 /**
312 * Throttle costly events at most once per every wait milliseconds.
313 *
314 * @type {Number}
315 */
316 throttle: 10,
317
318 /**
319 * Moving direction mode.
320 *
321 * Available inputs:
322 * - 'ltr' - left to right movement,
323 * - 'rtl' - right to left movement.
324 *
325 * @type {String}
326 */
327 direction: 'ltr',
328
329 /**
330 * The distance value of the next and previous viewports which
331 * have to peek in the current view. Accepts number and
332 * pixels as a string. Left and right peeking can be
333 * set up separately with a directions object.
334 *
335 * For example:
336 * `100` - Peek 100px on the both sides.
337 * { before: 100, after: 50 }` - Peek 100px on the left side and 50px on the right side.
338 *
339 * @type {Number|String|Object}
340 */
341 peek: 0,
342
343 /**
344 * Defines how many clones of current viewport will be generated.
345 *
346 * @type {Number}
347 */
348 cloningRatio: 1,
349
350 /**
351 * Collection of options applied at specified media breakpoints.
352 * For example: display two slides per view under 800px.
353 * `{
354 * '800px': {
355 * perView: 2
356 * }
357 * }`
358 */
359 breakpoints: {},
360
361 /**
362 * Collection of internally used HTML classes.
363 *
364 * @todo Refactor `slider` and `carousel` properties to single `type: { slider: '', carousel: '' }` object
365 * @type {Object}
366 */
367 classes: {
368 swipeable: 'glide--swipeable',
369 dragging: 'glide--dragging',
370 direction: {
371 ltr: 'glide--ltr',
372 rtl: 'glide--rtl'
373 },
374 type: {
375 slider: 'glide--slider',
376 carousel: 'glide--carousel'
377 },
378 slide: {
379 clone: 'glide__slide--clone',
380 active: 'glide__slide--active'
381 },
382 arrow: {
383 disabled: 'glide__arrow--disabled'
384 },
385 nav: {
386 active: 'glide__bullet--active'
387 }
388 }
389 };
390
391 /**
392 * Outputs warning message to the bowser console.
393 *
394 * @param {String} msg
395 * @return {Void}
396 */
397 function warn(msg) {
398 console.error("[Glide warn]: ".concat(msg));
399 }
400
401 /**
402 * Converts value entered as number
403 * or string to integer value.
404 *
405 * @param {String} value
406 * @returns {Number}
407 */
408 function toInt(value) {
409 return parseInt(value);
410 }
411 /**
412 * Converts value entered as number
413 * or string to flat value.
414 *
415 * @param {String} value
416 * @returns {Number}
417 */
418
419 function toFloat(value) {
420 return parseFloat(value);
421 }
422 /**
423 * Indicates whether the specified value is a string.
424 *
425 * @param {*} value
426 * @return {Boolean}
427 */
428
429 function isString(value) {
430 return typeof value === 'string';
431 }
432 /**
433 * Indicates whether the specified value is an object.
434 *
435 * @param {*} value
436 * @return {Boolean}
437 *
438 * @see https://github.com/jashkenas/underscore
439 */
440
441 function isObject(value) {
442 var type = _typeof(value);
443
444 return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators
445 }
446 /**
447 * Indicates whether the specified value is a function.
448 *
449 * @param {*} value
450 * @return {Boolean}
451 */
452
453 function isFunction(value) {
454 return typeof value === 'function';
455 }
456 /**
457 * Indicates whether the specified value is undefined.
458 *
459 * @param {*} value
460 * @return {Boolean}
461 */
462
463 function isUndefined(value) {
464 return typeof value === 'undefined';
465 }
466 /**
467 * Indicates whether the specified value is an array.
468 *
469 * @param {*} value
470 * @return {Boolean}
471 */
472
473 function isArray(value) {
474 return value.constructor === Array;
475 }
476
477 /**
478 * Creates and initializes specified collection of extensions.
479 * Each extension receives access to instance of glide and rest of components.
480 *
481 * @param {Object} glide
482 * @param {Object} extensions
483 *
484 * @returns {Object}
485 */
486
487 function mount(glide, extensions, events) {
488 var components = {};
489
490 for (var name in extensions) {
491 if (isFunction(extensions[name])) {
492 components[name] = extensions[name](glide, components, events);
493 } else {
494 warn('Extension must be a function');
495 }
496 }
497
498 for (var _name in components) {
499 if (isFunction(components[_name].mount)) {
500 components[_name].mount();
501 }
502 }
503
504 return components;
505 }
506
507 /**
508 * Defines getter and setter property on the specified object.
509 *
510 * @param {Object} obj Object where property has to be defined.
511 * @param {String} prop Name of the defined property.
512 * @param {Object} definition Get and set definitions for the property.
513 * @return {Void}
514 */
515 function define(obj, prop, definition) {
516 Object.defineProperty(obj, prop, definition);
517 }
518 /**
519 * Sorts aphabetically object keys.
520 *
521 * @param {Object} obj
522 * @return {Object}
523 */
524
525 function sortKeys(obj) {
526 return Object.keys(obj).sort().reduce(function (r, k) {
527 r[k] = obj[k];
528 return r[k], r;
529 }, {});
530 }
531 /**
532 * Merges passed settings object with default options.
533 *
534 * @param {Object} defaults
535 * @param {Object} settings
536 * @return {Object}
537 */
538
539 function mergeOptions(defaults, settings) {
540 var options = Object.assign({}, defaults, settings); // `Object.assign` do not deeply merge objects, so we
541 // have to do it manually for every nested object
542 // in options. Although it does not look smart,
543 // it's smaller and faster than some fancy
544 // merging deep-merge algorithm script.
545
546 if (settings.hasOwnProperty('classes')) {
547 options.classes = Object.assign({}, defaults.classes, settings.classes);
548
549 if (settings.classes.hasOwnProperty('direction')) {
550 options.classes.direction = Object.assign({}, defaults.classes.direction, settings.classes.direction);
551 }
552
553 if (settings.classes.hasOwnProperty('type')) {
554 options.classes.type = Object.assign({}, defaults.classes.type, settings.classes.type);
555 }
556
557 if (settings.classes.hasOwnProperty('slide')) {
558 options.classes.slide = Object.assign({}, defaults.classes.slide, settings.classes.slide);
559 }
560
561 if (settings.classes.hasOwnProperty('arrow')) {
562 options.classes.arrow = Object.assign({}, defaults.classes.arrow, settings.classes.arrow);
563 }
564
565 if (settings.classes.hasOwnProperty('nav')) {
566 options.classes.nav = Object.assign({}, defaults.classes.nav, settings.classes.nav);
567 }
568 }
569
570 if (settings.hasOwnProperty('breakpoints')) {
571 options.breakpoints = Object.assign({}, defaults.breakpoints, settings.breakpoints);
572 }
573
574 return options;
575 }
576
577 var EventsBus = /*#__PURE__*/function () {
578 /**
579 * Construct a EventBus instance.
580 *
581 * @param {Object} events
582 */
583 function EventsBus() {
584 var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
585
586 _classCallCheck(this, EventsBus);
587
588 this.events = events;
589 this.hop = events.hasOwnProperty;
590 }
591 /**
592 * Adds listener to the specifed event.
593 *
594 * @param {String|Array} event
595 * @param {Function} handler
596 */
597
598
599 _createClass(EventsBus, [{
600 key: "on",
601 value: function on(event, handler) {
602 if (isArray(event)) {
603 for (var i = 0; i < event.length; i++) {
604 this.on(event[i], handler);
605 }
606
607 return;
608 } // Create the event's object if not yet created
609
610
611 if (!this.hop.call(this.events, event)) {
612 this.events[event] = [];
613 } // Add the handler to queue
614
615
616 var index = this.events[event].push(handler) - 1; // Provide handle back for removal of event
617
618 return {
619 remove: function remove() {
620 delete this.events[event][index];
621 }
622 };
623 }
624 /**
625 * Runs registered handlers for specified event.
626 *
627 * @param {String|Array} event
628 * @param {Object=} context
629 */
630
631 }, {
632 key: "emit",
633 value: function emit(event, context) {
634 if (isArray(event)) {
635 for (var i = 0; i < event.length; i++) {
636 this.emit(event[i], context);
637 }
638
639 return;
640 } // If the event doesn't exist, or there's no handlers in queue, just leave
641
642
643 if (!this.hop.call(this.events, event)) {
644 return;
645 } // Cycle through events queue, fire!
646
647
648 this.events[event].forEach(function (item) {
649 item(context || {});
650 });
651 }
652 }]);
653
654 return EventsBus;
655 }();
656
657 var Glide$1 = /*#__PURE__*/function () {
658 /**
659 * Construct glide.
660 *
661 * @param {String} selector
662 * @param {Object} options
663 */
664 function Glide(selector) {
665 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
666
667 _classCallCheck(this, Glide);
668
669 this._c = {};
670 this._t = [];
671 this._e = new EventsBus();
672 this.disabled = false;
673 this.selector = selector;
674 this.settings = mergeOptions(defaults, options);
675 this.index = this.settings.startAt;
676 }
677 /**
678 * Initializes glide.
679 *
680 * @param {Object} extensions Collection of extensions to initialize.
681 * @return {Glide}
682 */
683
684
685 _createClass(Glide, [{
686 key: "mount",
687 value: function mount$1() {
688 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
689
690 this._e.emit('mount.before');
691
692 if (isObject(extensions)) {
693 this._c = mount(this, extensions, this._e);
694 } else {
695 warn('You need to provide a object on `mount()`');
696 }
697
698 this._e.emit('mount.after');
699
700 return this;
701 }
702 /**
703 * Collects an instance `translate` transformers.
704 *
705 * @param {Array} transformers Collection of transformers.
706 * @return {Void}
707 */
708
709 }, {
710 key: "mutate",
711 value: function mutate() {
712 var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
713
714 if (isArray(transformers)) {
715 this._t = transformers;
716 } else {
717 warn('You need to provide a array on `mutate()`');
718 }
719
720 return this;
721 }
722 /**
723 * Updates glide with specified settings.
724 *
725 * @param {Object} settings
726 * @return {Glide}
727 */
728
729 }, {
730 key: "update",
731 value: function update() {
732 var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
733 this.settings = mergeOptions(this.settings, settings);
734
735 if (settings.hasOwnProperty('startAt')) {
736 this.index = settings.startAt;
737 }
738
739 this._e.emit('update');
740
741 return this;
742 }
743 /**
744 * Change slide with specified pattern. A pattern must be in the special format:
745 * `>` - Move one forward
746 * `<` - Move one backward
747 * `={i}` - Go to {i} zero-based slide (eq. '=1', will go to second slide)
748 * `>>` - Rewinds to end (last slide)
749 * `<<` - Rewinds to start (first slide)
750 * `|>` - Move one viewport forward
751 * `|<` - Move one viewport backward
752 *
753 * @param {String} pattern
754 * @return {Glide}
755 */
756
757 }, {
758 key: "go",
759 value: function go(pattern) {
760 this._c.Run.make(pattern);
761
762 return this;
763 }
764 /**
765 * Move track by specified distance.
766 *
767 * @param {String} distance
768 * @return {Glide}
769 */
770
771 }, {
772 key: "move",
773 value: function move(distance) {
774 this._c.Transition.disable();
775
776 this._c.Move.make(distance);
777
778 return this;
779 }
780 /**
781 * Destroy instance and revert all changes done by this._c.
782 *
783 * @return {Glide}
784 */
785
786 }, {
787 key: "destroy",
788 value: function destroy() {
789 this._e.emit('destroy');
790
791 return this;
792 }
793 /**
794 * Start instance autoplaying.
795 *
796 * @param {Boolean|Number} interval Run autoplaying with passed interval regardless of `autoplay` settings
797 * @return {Glide}
798 */
799
800 }, {
801 key: "play",
802 value: function play() {
803 var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
804
805 if (interval) {
806 this.settings.autoplay = interval;
807 }
808
809 this._e.emit('play');
810
811 return this;
812 }
813 /**
814 * Stop instance autoplaying.
815 *
816 * @return {Glide}
817 */
818
819 }, {
820 key: "pause",
821 value: function pause() {
822 this._e.emit('pause');
823
824 return this;
825 }
826 /**
827 * Sets glide into a idle status.
828 *
829 * @return {Glide}
830 */
831
832 }, {
833 key: "disable",
834 value: function disable() {
835 this.disabled = true;
836 return this;
837 }
838 /**
839 * Sets glide into a active status.
840 *
841 * @return {Glide}
842 */
843
844 }, {
845 key: "enable",
846 value: function enable() {
847 this.disabled = false;
848 return this;
849 }
850 /**
851 * Adds cuutom event listener with handler.
852 *
853 * @param {String|Array} event
854 * @param {Function} handler
855 * @return {Glide}
856 */
857
858 }, {
859 key: "on",
860 value: function on(event, handler) {
861 this._e.on(event, handler);
862
863 return this;
864 }
865 /**
866 * Checks if glide is a precised type.
867 *
868 * @param {String} name
869 * @return {Boolean}
870 */
871
872 }, {
873 key: "isType",
874 value: function isType(name) {
875 return this.settings.type === name;
876 }
877 /**
878 * Gets value of the core options.
879 *
880 * @return {Object}
881 */
882
883 }, {
884 key: "settings",
885 get: function get() {
886 return this._o;
887 }
888 /**
889 * Sets value of the core options.
890 *
891 * @param {Object} o
892 * @return {Void}
893 */
894 ,
895 set: function set(o) {
896 if (isObject(o)) {
897 this._o = o;
898 } else {
899 warn('Options must be an `object` instance.');
900 }
901 }
902 /**
903 * Gets current index of the slider.
904 *
905 * @return {Object}
906 */
907
908 }, {
909 key: "index",
910 get: function get() {
911 return this._i;
912 }
913 /**
914 * Sets current index a slider.
915 *
916 * @return {Object}
917 */
918 ,
919 set: function set(i) {
920 this._i = toInt(i);
921 }
922 /**
923 * Gets type name of the slider.
924 *
925 * @return {String}
926 */
927
928 }, {
929 key: "type",
930 get: function get() {
931 return this.settings.type;
932 }
933 /**
934 * Gets value of the idle status.
935 *
936 * @return {Boolean}
937 */
938
939 }, {
940 key: "disabled",
941 get: function get() {
942 return this._d;
943 }
944 /**
945 * Sets value of the idle status.
946 *
947 * @return {Boolean}
948 */
949 ,
950 set: function set(status) {
951 this._d = !!status;
952 }
953 }]);
954
955 return Glide;
956 }();
957
958 function Run (Glide, Components, Events) {
959 var Run = {
960 /**
961 * Initializes autorunning of the glide.
962 *
963 * @return {Void}
964 */
965 mount: function mount() {
966 this._o = false;
967 },
968
969 /**
970 * Makes glides running based on the passed moving schema.
971 *
972 * @param {String} move
973 */
974 make: function make(move) {
975 var _this = this;
976
977 if (!Glide.disabled) {
978 !Glide.settings.waitForTransition || Glide.disable();
979 this.move = move;
980 Events.emit('run.before', this.move);
981 this.calculate();
982 Events.emit('run', this.move);
983 Components.Transition.after(function () {
984 if (_this.isStart()) {
985 Events.emit('run.start', _this.move);
986 }
987
988 if (_this.isEnd()) {
989 Events.emit('run.end', _this.move);
990 }
991
992 if (_this.isOffset()) {
993 _this._o = false;
994 Events.emit('run.offset', _this.move);
995 }
996
997 Events.emit('run.after', _this.move);
998 Glide.enable();
999 });
1000 }
1001 },
1002
1003 /**
1004 * Calculates current index based on defined move.
1005 *
1006 * @return {Number|Undefined}
1007 */
1008 calculate: function calculate() {
1009 var move = this.move,
1010 length = this.length;
1011 var steps = move.steps,
1012 direction = move.direction; // By default assume that size of view is equal to one slide
1013
1014 var viewSize = 1; // While direction is `=` we want jump to
1015 // a specified index described in steps.
1016
1017 if (direction === '=') {
1018 // Check if bound is true,
1019 // as we want to avoid whitespaces.
1020 if (Glide.settings.bound && toInt(steps) > length) {
1021 Glide.index = length;
1022 return;
1023 }
1024
1025 Glide.index = steps;
1026 return;
1027 } // When pattern is equal to `>>` we want
1028 // fast forward to the last slide.
1029
1030
1031 if (direction === '>' && steps === '>') {
1032 Glide.index = length;
1033 return;
1034 } // When pattern is equal to `<<` we want
1035 // fast forward to the first slide.
1036
1037
1038 if (direction === '<' && steps === '<') {
1039 Glide.index = 0;
1040 return;
1041 } // pagination movement
1042
1043
1044 if (direction === '|') {
1045 viewSize = Glide.settings.perView || 1;
1046 } // we are moving forward
1047
1048
1049 if (direction === '>' || direction === '|' && steps === '>') {
1050 var index = calculateForwardIndex(viewSize);
1051
1052 if (index > length) {
1053 this._o = true;
1054 }
1055
1056 Glide.index = normalizeForwardIndex(index, viewSize);
1057 return;
1058 } // we are moving backward
1059
1060
1061 if (direction === '<' || direction === '|' && steps === '<') {
1062 var _index = calculateBackwardIndex(viewSize);
1063
1064 if (_index < 0) {
1065 this._o = true;
1066 }
1067
1068 Glide.index = normalizeBackwardIndex(_index, viewSize);
1069 return;
1070 }
1071
1072 warn("Invalid direction pattern [".concat(direction).concat(steps, "] has been used"));
1073 },
1074
1075 /**
1076 * Checks if we are on the first slide.
1077 *
1078 * @return {Boolean}
1079 */
1080 isStart: function isStart() {
1081 return Glide.index <= 0;
1082 },
1083
1084 /**
1085 * Checks if we are on the last slide.
1086 *
1087 * @return {Boolean}
1088 */
1089 isEnd: function isEnd() {
1090 return Glide.index >= this.length;
1091 },
1092
1093 /**
1094 * Checks if we are making a offset run.
1095 *
1096 * @param {String} direction
1097 * @return {Boolean}
1098 */
1099 isOffset: function isOffset() {
1100 var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
1101
1102 if (!direction) {
1103 return this._o;
1104 }
1105
1106 if (!this._o) {
1107 return false;
1108 } // did we view to the right?
1109
1110
1111 if (direction === '|>') {
1112 return this.move.direction === '|' && this.move.steps === '>';
1113 } // did we view to the left?
1114
1115
1116 if (direction === '|<') {
1117 return this.move.direction === '|' && this.move.steps === '<';
1118 }
1119
1120 return this.move.direction === direction;
1121 },
1122
1123 /**
1124 * Checks if bound mode is active
1125 *
1126 * @return {Boolean}
1127 */
1128 isBound: function isBound() {
1129 return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound;
1130 }
1131 };
1132 /**
1133 * Returns index value to move forward/to the right
1134 *
1135 * @param viewSize
1136 * @returns {Number}
1137 */
1138
1139 function calculateForwardIndex(viewSize) {
1140 var index = Glide.index;
1141
1142 if (Glide.isType('carousel')) {
1143 return index + viewSize;
1144 }
1145
1146 return index + (viewSize - index % viewSize);
1147 }
1148 /**
1149 * Normalizes the given forward index based on glide settings, preventing it to exceed certain boundaries
1150 *
1151 * @param index
1152 * @param length
1153 * @param viewSize
1154 * @returns {Number}
1155 */
1156
1157
1158 function normalizeForwardIndex(index, viewSize) {
1159 var length = Run.length;
1160
1161 if (index <= length) {
1162 return index;
1163 }
1164
1165 if (Glide.isType('carousel')) {
1166 return index - (length + 1);
1167 }
1168
1169 if (Glide.settings.rewind) {
1170 // bound does funny things with the length, therefor we have to be certain
1171 // that we are on the last possible index value given by bound
1172 if (Run.isBound() && !Run.isEnd()) {
1173 return length;
1174 }
1175
1176 return 0;
1177 }
1178
1179 if (Run.isBound()) {
1180 return length;
1181 }
1182
1183 return Math.floor(length / viewSize) * viewSize;
1184 }
1185 /**
1186 * Calculates index value to move backward/to the left
1187 *
1188 * @param viewSize
1189 * @returns {Number}
1190 */
1191
1192
1193 function calculateBackwardIndex(viewSize) {
1194 var index = Glide.index;
1195
1196 if (Glide.isType('carousel')) {
1197 return index - viewSize;
1198 } // ensure our back navigation results in the same index as a forward navigation
1199 // to experience a homogeneous paging
1200
1201
1202 var view = Math.ceil(index / viewSize);
1203 return (view - 1) * viewSize;
1204 }
1205 /**
1206 * Normalizes the given backward index based on glide settings, preventing it to exceed certain boundaries
1207 *
1208 * @param index
1209 * @param length
1210 * @param viewSize
1211 * @returns {*}
1212 */
1213
1214
1215 function normalizeBackwardIndex(index, viewSize) {
1216 var length = Run.length;
1217
1218 if (index >= 0) {
1219 return index;
1220 }
1221
1222 if (Glide.isType('carousel')) {
1223 return index + (length + 1);
1224 }
1225
1226 if (Glide.settings.rewind) {
1227 // bound does funny things with the length, therefor we have to be certain
1228 // that we are on first possible index value before we to rewind to the length given by bound
1229 if (Run.isBound() && Run.isStart()) {
1230 return length;
1231 }
1232
1233 return Math.floor(length / viewSize) * viewSize;
1234 }
1235
1236 return 0;
1237 }
1238
1239 define(Run, 'move', {
1240 /**
1241 * Gets value of the move schema.
1242 *
1243 * @returns {Object}
1244 */
1245 get: function get() {
1246 return this._m;
1247 },
1248
1249 /**
1250 * Sets value of the move schema.
1251 *
1252 * @returns {Object}
1253 */
1254 set: function set(value) {
1255 var step = value.substr(1);
1256 this._m = {
1257 direction: value.substr(0, 1),
1258 steps: step ? toInt(step) ? toInt(step) : step : 0
1259 };
1260 }
1261 });
1262 define(Run, 'length', {
1263 /**
1264 * Gets value of the running distance based
1265 * on zero-indexing number of slides.
1266 *
1267 * @return {Number}
1268 */
1269 get: function get() {
1270 var settings = Glide.settings;
1271 var length = Components.Html.slides.length; // If the `bound` option is active, a maximum running distance should be
1272 // reduced by `perView` and `focusAt` settings. Running distance
1273 // should end before creating an empty space after instance.
1274
1275 if (this.isBound()) {
1276 return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt);
1277 }
1278
1279 return length - 1;
1280 }
1281 });
1282 define(Run, 'offset', {
1283 /**
1284 * Gets status of the offsetting flag.
1285 *
1286 * @return {Boolean}
1287 */
1288 get: function get() {
1289 return this._o;
1290 }
1291 });
1292 return Run;
1293 }
1294
1295 /**
1296 * Returns a current time.
1297 *
1298 * @return {Number}
1299 */
1300 function now() {
1301 return new Date().getTime();
1302 }
1303
1304 /**
1305 * Returns a function, that, when invoked, will only be triggered
1306 * at most once during a given window of time.
1307 *
1308 * @param {Function} func
1309 * @param {Number} wait
1310 * @param {Object=} options
1311 * @return {Function}
1312 *
1313 * @see https://github.com/jashkenas/underscore
1314 */
1315
1316 function throttle(func, wait, options) {
1317 var timeout, context, args, result;
1318 var previous = 0;
1319 if (!options) options = {};
1320
1321 var later = function later() {
1322 previous = options.leading === false ? 0 : now();
1323 timeout = null;
1324 result = func.apply(context, args);
1325 if (!timeout) context = args = null;
1326 };
1327
1328 var throttled = function throttled() {
1329 var at = now();
1330 if (!previous && options.leading === false) previous = at;
1331 var remaining = wait - (at - previous);
1332 context = this;
1333 args = arguments;
1334
1335 if (remaining <= 0 || remaining > wait) {
1336 if (timeout) {
1337 clearTimeout(timeout);
1338 timeout = null;
1339 }
1340
1341 previous = at;
1342 result = func.apply(context, args);
1343 if (!timeout) context = args = null;
1344 } else if (!timeout && options.trailing !== false) {
1345 timeout = setTimeout(later, remaining);
1346 }
1347
1348 return result;
1349 };
1350
1351 throttled.cancel = function () {
1352 clearTimeout(timeout);
1353 previous = 0;
1354 timeout = context = args = null;
1355 };
1356
1357 return throttled;
1358 }
1359
1360 var MARGIN_TYPE = {
1361 ltr: ['marginLeft', 'marginRight'],
1362 rtl: ['marginRight', 'marginLeft']
1363 };
1364 function Gaps (Glide, Components, Events) {
1365 var Gaps = {
1366 /**
1367 * Applies gaps between slides. First and last
1368 * slides do not receive it's edge margins.
1369 *
1370 * @param {HTMLCollection} slides
1371 * @return {Void}
1372 */
1373 apply: function apply(slides) {
1374 for (var i = 0, len = slides.length; i < len; i++) {
1375 var style = slides[i].style;
1376 var direction = Components.Direction.value;
1377
1378 if (i !== 0) {
1379 style[MARGIN_TYPE[direction][0]] = "".concat(this.value / 2, "px");
1380 } else {
1381 style[MARGIN_TYPE[direction][0]] = '';
1382 }
1383
1384 if (i !== slides.length - 1) {
1385 style[MARGIN_TYPE[direction][1]] = "".concat(this.value / 2, "px");
1386 } else {
1387 style[MARGIN_TYPE[direction][1]] = '';
1388 }
1389 }
1390 },
1391
1392 /**
1393 * Removes gaps from the slides.
1394 *
1395 * @param {HTMLCollection} slides
1396 * @returns {Void}
1397 */
1398 remove: function remove(slides) {
1399 for (var i = 0, len = slides.length; i < len; i++) {
1400 var style = slides[i].style;
1401 style.marginLeft = '';
1402 style.marginRight = '';
1403 }
1404 }
1405 };
1406 define(Gaps, 'value', {
1407 /**
1408 * Gets value of the gap.
1409 *
1410 * @returns {Number}
1411 */
1412 get: function get() {
1413 return toInt(Glide.settings.gap);
1414 }
1415 });
1416 define(Gaps, 'grow', {
1417 /**
1418 * Gets additional dimensions value caused by gaps.
1419 * Used to increase width of the slides wrapper.
1420 *
1421 * @returns {Number}
1422 */
1423 get: function get() {
1424 return Gaps.value * Components.Sizes.length;
1425 }
1426 });
1427 define(Gaps, 'reductor', {
1428 /**
1429 * Gets reduction value caused by gaps.
1430 * Used to subtract width of the slides.
1431 *
1432 * @returns {Number}
1433 */
1434 get: function get() {
1435 var perView = Glide.settings.perView;
1436 return Gaps.value * (perView - 1) / perView;
1437 }
1438 });
1439 /**
1440 * Apply calculated gaps:
1441 * - after building, so slides (including clones) will receive proper margins
1442 * - on updating via API, to recalculate gaps with new options
1443 */
1444
1445 Events.on(['build.after', 'update'], throttle(function () {
1446 Gaps.apply(Components.Html.wrapper.children);
1447 }, 30));
1448 /**
1449 * Remove gaps:
1450 * - on destroying to bring markup to its inital state
1451 */
1452
1453 Events.on('destroy', function () {
1454 Gaps.remove(Components.Html.wrapper.children);
1455 });
1456 return Gaps;
1457 }
1458
1459 /**
1460 * Finds siblings nodes of the passed node.
1461 *
1462 * @param {Element} node
1463 * @return {Array}
1464 */
1465 function siblings(node) {
1466 if (node && node.parentNode) {
1467 var n = node.parentNode.firstChild;
1468 var matched = [];
1469
1470 for (; n; n = n.nextSibling) {
1471 if (n.nodeType === 1 && n !== node) {
1472 matched.push(n);
1473 }
1474 }
1475
1476 return matched;
1477 }
1478
1479 return [];
1480 }
1481 /**
1482 * Checks if passed node exist and is a valid element.
1483 *
1484 * @param {Element} node
1485 * @return {Boolean}
1486 */
1487
1488 function exist(node) {
1489 if (node && node instanceof window.HTMLElement) {
1490 return true;
1491 }
1492
1493 return false;
1494 }
1495
1496 var TRACK_SELECTOR = '[data-glide-el="track"]';
1497 function Html (Glide, Components, Events) {
1498 var Html = {
1499 /**
1500 * Setup slider HTML nodes.
1501 *
1502 * @param {Glide} glide
1503 */
1504 mount: function mount() {
1505 this.root = Glide.selector;
1506 this.track = this.root.querySelector(TRACK_SELECTOR);
1507 this.collectSlides();
1508 },
1509
1510 /**
1511 * Collect slides
1512 */
1513 collectSlides: function collectSlides() {
1514 this.slides = Array.prototype.slice.call(this.wrapper.children).filter(function (slide) {
1515 return !slide.classList.contains(Glide.settings.classes.slide.clone);
1516 });
1517 }
1518 };
1519 define(Html, 'root', {
1520 /**
1521 * Gets node of the glide main element.
1522 *
1523 * @return {Object}
1524 */
1525 get: function get() {
1526 return Html._r;
1527 },
1528
1529 /**
1530 * Sets node of the glide main element.
1531 *
1532 * @return {Object}
1533 */
1534 set: function set(r) {
1535 if (isString(r)) {
1536 r = document.querySelector(r);
1537 }
1538
1539 if (exist(r)) {
1540 Html._r = r;
1541 } else {
1542 warn('Root element must be a existing Html node');
1543 }
1544 }
1545 });
1546 define(Html, 'track', {
1547 /**
1548 * Gets node of the glide track with slides.
1549 *
1550 * @return {Object}
1551 */
1552 get: function get() {
1553 return Html._t;
1554 },
1555
1556 /**
1557 * Sets node of the glide track with slides.
1558 *
1559 * @return {Object}
1560 */
1561 set: function set(t) {
1562 if (exist(t)) {
1563 Html._t = t;
1564 } else {
1565 warn("Could not find track element. Please use ".concat(TRACK_SELECTOR, " attribute."));
1566 }
1567 }
1568 });
1569 define(Html, 'wrapper', {
1570 /**
1571 * Gets node of the slides wrapper.
1572 *
1573 * @return {Object}
1574 */
1575 get: function get() {
1576 return Html.track.children[0];
1577 }
1578 });
1579 /**
1580 * Add/remove/reorder dynamic slides
1581 */
1582
1583 Events.on('update', function () {
1584 Html.collectSlides();
1585 });
1586 return Html;
1587 }
1588
1589 function Peek (Glide, Components, Events) {
1590 var Peek = {
1591 /**
1592 * Setups how much to peek based on settings.
1593 *
1594 * @return {Void}
1595 */
1596 mount: function mount() {
1597 this.value = Glide.settings.peek;
1598 }
1599 };
1600 define(Peek, 'value', {
1601 /**
1602 * Gets value of the peek.
1603 *
1604 * @returns {Number|Object}
1605 */
1606 get: function get() {
1607 return Peek._v;
1608 },
1609
1610 /**
1611 * Sets value of the peek.
1612 *
1613 * @param {Number|Object} value
1614 * @return {Void}
1615 */
1616 set: function set(value) {
1617 if (isObject(value)) {
1618 value.before = toInt(value.before);
1619 value.after = toInt(value.after);
1620 } else {
1621 value = toInt(value);
1622 }
1623
1624 Peek._v = value;
1625 }
1626 });
1627 define(Peek, 'reductor', {
1628 /**
1629 * Gets reduction value caused by peek.
1630 *
1631 * @returns {Number}
1632 */
1633 get: function get() {
1634 var value = Peek.value;
1635 var perView = Glide.settings.perView;
1636
1637 if (isObject(value)) {
1638 return value.before / perView + value.after / perView;
1639 }
1640
1641 return value * 2 / perView;
1642 }
1643 });
1644 /**
1645 * Recalculate peeking sizes on:
1646 * - when resizing window to update to proper percents
1647 */
1648
1649 Events.on(['resize', 'update'], function () {
1650 Peek.mount();
1651 });
1652 return Peek;
1653 }
1654
1655 function Move (Glide, Components, Events) {
1656 var Move = {
1657 /**
1658 * Constructs move component.
1659 *
1660 * @returns {Void}
1661 */
1662 mount: function mount() {
1663 this._o = 0;
1664 },
1665
1666 /**
1667 * Calculates a movement value based on passed offset and currently active index.
1668 *
1669 * @param {Number} offset
1670 * @return {Void}
1671 */
1672 make: function make() {
1673 var _this = this;
1674
1675 var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
1676 this.offset = offset;
1677 Events.emit('move', {
1678 movement: this.value
1679 });
1680 Components.Transition.after(function () {
1681 Events.emit('move.after', {
1682 movement: _this.value
1683 });
1684 });
1685 }
1686 };
1687 define(Move, 'offset', {
1688 /**
1689 * Gets an offset value used to modify current translate.
1690 *
1691 * @return {Object}
1692 */
1693 get: function get() {
1694 return Move._o;
1695 },
1696
1697 /**
1698 * Sets an offset value used to modify current translate.
1699 *
1700 * @return {Object}
1701 */
1702 set: function set(value) {
1703 Move._o = !isUndefined(value) ? toInt(value) : 0;
1704 }
1705 });
1706 define(Move, 'translate', {
1707 /**
1708 * Gets a raw movement value.
1709 *
1710 * @return {Number}
1711 */
1712 get: function get() {
1713 return Components.Sizes.slideWidth * Glide.index;
1714 }
1715 });
1716 define(Move, 'value', {
1717 /**
1718 * Gets an actual movement value corrected by offset.
1719 *
1720 * @return {Number}
1721 */
1722 get: function get() {
1723 var offset = this.offset;
1724 var translate = this.translate;
1725
1726 if (Components.Direction.is('rtl')) {
1727 return translate + offset;
1728 }
1729
1730 return translate - offset;
1731 }
1732 });
1733 /**
1734 * Make movement to proper slide on:
1735 * - before build, so glide will start at `startAt` index
1736 * - on each standard run to move to newly calculated index
1737 */
1738
1739 Events.on(['build.before', 'run'], function () {
1740 Move.make();
1741 });
1742 return Move;
1743 }
1744
1745 function Sizes (Glide, Components, Events) {
1746 var Sizes = {
1747 /**
1748 * Setups dimensions of slides.
1749 *
1750 * @return {Void}
1751 */
1752 setupSlides: function setupSlides() {
1753 var width = "".concat(this.slideWidth, "px");
1754 var slides = Components.Html.slides;
1755
1756 for (var i = 0; i < slides.length; i++) {
1757 slides[i].style.width = width;
1758 }
1759 },
1760
1761 /**
1762 * Setups dimensions of slides wrapper.
1763 *
1764 * @return {Void}
1765 */
1766 setupWrapper: function setupWrapper() {
1767 Components.Html.wrapper.style.width = "".concat(this.wrapperSize, "px");
1768 },
1769
1770 /**
1771 * Removes applied styles from HTML elements.
1772 *
1773 * @returns {Void}
1774 */
1775 remove: function remove() {
1776 var slides = Components.Html.slides;
1777
1778 for (var i = 0; i < slides.length; i++) {
1779 slides[i].style.width = '';
1780 }
1781
1782 Components.Html.wrapper.style.width = '';
1783 }
1784 };
1785 define(Sizes, 'length', {
1786 /**
1787 * Gets count number of the slides.
1788 *
1789 * @return {Number}
1790 */
1791 get: function get() {
1792 return Components.Html.slides.length;
1793 }
1794 });
1795 define(Sizes, 'width', {
1796 /**
1797 * Gets width value of the slider (visible area).
1798 *
1799 * @return {Number}
1800 */
1801 get: function get() {
1802 return Components.Html.track.offsetWidth;
1803 }
1804 });
1805 define(Sizes, 'wrapperSize', {
1806 /**
1807 * Gets size of the slides wrapper.
1808 *
1809 * @return {Number}
1810 */
1811 get: function get() {
1812 return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow;
1813 }
1814 });
1815 define(Sizes, 'slideWidth', {
1816 /**
1817 * Gets width value of a single slide.
1818 *
1819 * @return {Number}
1820 */
1821 get: function get() {
1822 return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor;
1823 }
1824 });
1825 /**
1826 * Apply calculated glide's dimensions:
1827 * - before building, so other dimensions (e.g. translate) will be calculated propertly
1828 * - when resizing window to recalculate sildes dimensions
1829 * - on updating via API, to calculate dimensions based on new options
1830 */
1831
1832 Events.on(['build.before', 'resize', 'update'], function () {
1833 Sizes.setupSlides();
1834 Sizes.setupWrapper();
1835 });
1836 /**
1837 * Remove calculated glide's dimensions:
1838 * - on destoting to bring markup to its inital state
1839 */
1840
1841 Events.on('destroy', function () {
1842 Sizes.remove();
1843 });
1844 return Sizes;
1845 }
1846
1847 function Build (Glide, Components, Events) {
1848 var Build = {
1849 /**
1850 * Init glide building. Adds classes, sets
1851 * dimensions and setups initial state.
1852 *
1853 * @return {Void}
1854 */
1855 mount: function mount() {
1856 Events.emit('build.before');
1857 this.typeClass();
1858 this.activeClass();
1859 Events.emit('build.after');
1860 },
1861
1862 /**
1863 * Adds `type` class to the glide element.
1864 *
1865 * @return {Void}
1866 */
1867 typeClass: function typeClass() {
1868 Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]);
1869 },
1870
1871 /**
1872 * Sets active class to current slide.
1873 *
1874 * @return {Void}
1875 */
1876 activeClass: function activeClass() {
1877 var classes = Glide.settings.classes;
1878 var slide = Components.Html.slides[Glide.index];
1879
1880 if (slide) {
1881 slide.classList.add(classes.slide.active);
1882 siblings(slide).forEach(function (sibling) {
1883 sibling.classList.remove(classes.slide.active);
1884 });
1885 }
1886 },
1887
1888 /**
1889 * Removes HTML classes applied at building.
1890 *
1891 * @return {Void}
1892 */
1893 removeClasses: function removeClasses() {
1894 var _Glide$settings$class = Glide.settings.classes,
1895 type = _Glide$settings$class.type,
1896 slide = _Glide$settings$class.slide;
1897 Components.Html.root.classList.remove(type[Glide.settings.type]);
1898 Components.Html.slides.forEach(function (sibling) {
1899 sibling.classList.remove(slide.active);
1900 });
1901 }
1902 };
1903 /**
1904 * Clear building classes:
1905 * - on destroying to bring HTML to its initial state
1906 * - on updating to remove classes before remounting component
1907 */
1908
1909 Events.on(['destroy', 'update'], function () {
1910 Build.removeClasses();
1911 });
1912 /**
1913 * Remount component:
1914 * - on resizing of the window to calculate new dimensions
1915 * - on updating settings via API
1916 */
1917
1918 Events.on(['resize', 'update'], function () {
1919 Build.mount();
1920 });
1921 /**
1922 * Swap active class of current slide:
1923 * - after each move to the new index
1924 */
1925
1926 Events.on('move.after', function () {
1927 Build.activeClass();
1928 });
1929 return Build;
1930 }
1931
1932 function Clones (Glide, Components, Events) {
1933 var Clones = {
1934 /**
1935 * Create pattern map and collect slides to be cloned.
1936 */
1937 mount: function mount() {
1938 this.items = [];
1939
1940 if (Glide.isType('carousel')) {
1941 this.items = this.collect();
1942 }
1943 },
1944
1945 /**
1946 * Collect clones with pattern.
1947 *
1948 * @return {[]}
1949 */
1950 collect: function collect() {
1951 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1952 var slides = Components.Html.slides;
1953 var _Glide$settings = Glide.settings,
1954 perView = _Glide$settings.perView,
1955 classes = _Glide$settings.classes,
1956 cloningRatio = _Glide$settings.cloningRatio;
1957
1958 if (slides.length !== 0) {
1959 var peekIncrementer = +!!Glide.settings.peek;
1960 var cloneCount = perView + peekIncrementer + Math.round(perView / 2);
1961 var append = slides.slice(0, cloneCount).reverse();
1962 var prepend = slides.slice(cloneCount * -1);
1963
1964 for (var r = 0; r < Math.max(cloningRatio, Math.floor(perView / slides.length)); r++) {
1965 for (var i = 0; i < append.length; i++) {
1966 var clone = append[i].cloneNode(true);
1967 clone.classList.add(classes.slide.clone);
1968 items.push(clone);
1969 }
1970
1971 for (var _i = 0; _i < prepend.length; _i++) {
1972 var _clone = prepend[_i].cloneNode(true);
1973
1974 _clone.classList.add(classes.slide.clone);
1975
1976 items.unshift(_clone);
1977 }
1978 }
1979 }
1980
1981 return items;
1982 },
1983
1984 /**
1985 * Append cloned slides with generated pattern.
1986 *
1987 * @return {Void}
1988 */
1989 append: function append() {
1990 var items = this.items;
1991 var _Components$Html = Components.Html,
1992 wrapper = _Components$Html.wrapper,
1993 slides = _Components$Html.slides;
1994 var half = Math.floor(items.length / 2);
1995 var prepend = items.slice(0, half).reverse();
1996 var append = items.slice(half * -1).reverse();
1997 var width = "".concat(Components.Sizes.slideWidth, "px");
1998
1999 for (var i = 0; i < append.length; i++) {
2000 wrapper.appendChild(append[i]);
2001 }
2002
2003 for (var _i2 = 0; _i2 < prepend.length; _i2++) {
2004 wrapper.insertBefore(prepend[_i2], slides[0]);
2005 }
2006
2007 for (var _i3 = 0; _i3 < items.length; _i3++) {
2008 items[_i3].style.width = width;
2009 }
2010 },
2011
2012 /**
2013 * Remove all cloned slides.
2014 *
2015 * @return {Void}
2016 */
2017 remove: function remove() {
2018 var items = this.items;
2019
2020 for (var i = 0; i < items.length; i++) {
2021 Components.Html.wrapper.removeChild(items[i]);
2022 }
2023 }
2024 };
2025 define(Clones, 'grow', {
2026 /**
2027 * Gets additional dimensions value caused by clones.
2028 *
2029 * @return {Number}
2030 */
2031 get: function get() {
2032 return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length;
2033 }
2034 });
2035 /**
2036 * Append additional slide's clones:
2037 * - while glide's type is `carousel`
2038 */
2039
2040 Events.on('update', function () {
2041 Clones.remove();
2042 Clones.mount();
2043 Clones.append();
2044 });
2045 /**
2046 * Append additional slide's clones:
2047 * - while glide's type is `carousel`
2048 */
2049
2050 Events.on('build.before', function () {
2051 if (Glide.isType('carousel')) {
2052 Clones.append();
2053 }
2054 });
2055 /**
2056 * Remove clones HTMLElements:
2057 * - on destroying, to bring HTML to its initial state
2058 */
2059
2060 Events.on('destroy', function () {
2061 Clones.remove();
2062 });
2063 return Clones;
2064 }
2065
2066 var EventsBinder = /*#__PURE__*/function () {
2067 /**
2068 * Construct a EventsBinder instance.
2069 */
2070 function EventsBinder() {
2071 var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2072
2073 _classCallCheck(this, EventsBinder);
2074
2075 this.listeners = listeners;
2076 }
2077 /**
2078 * Adds events listeners to arrows HTML elements.
2079 *
2080 * @param {String|Array} events
2081 * @param {Element|Window|Document} el
2082 * @param {Function} closure
2083 * @param {Boolean|Object} capture
2084 * @return {Void}
2085 */
2086
2087
2088 _createClass(EventsBinder, [{
2089 key: "on",
2090 value: function on(events, el, closure) {
2091 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
2092
2093 if (isString(events)) {
2094 events = [events];
2095 }
2096
2097 for (var i = 0; i < events.length; i++) {
2098 this.listeners[events[i]] = closure;
2099 el.addEventListener(events[i], this.listeners[events[i]], capture);
2100 }
2101 }
2102 /**
2103 * Removes event listeners from arrows HTML elements.
2104 *
2105 * @param {String|Array} events
2106 * @param {Element|Window|Document} el
2107 * @param {Boolean|Object} capture
2108 * @return {Void}
2109 */
2110
2111 }, {
2112 key: "off",
2113 value: function off(events, el) {
2114 var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
2115
2116 if (isString(events)) {
2117 events = [events];
2118 }
2119
2120 for (var i = 0; i < events.length; i++) {
2121 el.removeEventListener(events[i], this.listeners[events[i]], capture);
2122 }
2123 }
2124 /**
2125 * Destroy collected listeners.
2126 *
2127 * @returns {Void}
2128 */
2129
2130 }, {
2131 key: "destroy",
2132 value: function destroy() {
2133 delete this.listeners;
2134 }
2135 }]);
2136
2137 return EventsBinder;
2138 }();
2139
2140 function Resize (Glide, Components, Events) {
2141 /**
2142 * Instance of the binder for DOM Events.
2143 *
2144 * @type {EventsBinder}
2145 */
2146 var Binder = new EventsBinder();
2147 var Resize = {
2148 /**
2149 * Initializes window bindings.
2150 */
2151 mount: function mount() {
2152 this.bind();
2153 },
2154
2155 /**
2156 * Binds `rezsize` listener to the window.
2157 * It's a costly event, so we are debouncing it.
2158 *
2159 * @return {Void}
2160 */
2161 bind: function bind() {
2162 Binder.on('resize', window, throttle(function () {
2163 Events.emit('resize');
2164 }, Glide.settings.throttle));
2165 },
2166
2167 /**
2168 * Unbinds listeners from the window.
2169 *
2170 * @return {Void}
2171 */
2172 unbind: function unbind() {
2173 Binder.off('resize', window);
2174 }
2175 };
2176 /**
2177 * Remove bindings from window:
2178 * - on destroying, to remove added EventListener
2179 */
2180
2181 Events.on('destroy', function () {
2182 Resize.unbind();
2183 Binder.destroy();
2184 });
2185 return Resize;
2186 }
2187
2188 var VALID_DIRECTIONS = ['ltr', 'rtl'];
2189 var FLIPED_MOVEMENTS = {
2190 '>': '<',
2191 '<': '>',
2192 '=': '='
2193 };
2194 function Direction (Glide, Components, Events) {
2195 var Direction = {
2196 /**
2197 * Setups gap value based on settings.
2198 *
2199 * @return {Void}
2200 */
2201 mount: function mount() {
2202 this.value = Glide.settings.direction;
2203 },
2204
2205 /**
2206 * Resolves pattern based on direction value
2207 *
2208 * @param {String} pattern
2209 * @returns {String}
2210 */
2211 resolve: function resolve(pattern) {
2212 var token = pattern.slice(0, 1);
2213
2214 if (this.is('rtl')) {
2215 return pattern.split(token).join(FLIPED_MOVEMENTS[token]);
2216 }
2217
2218 return pattern;
2219 },
2220
2221 /**
2222 * Checks value of direction mode.
2223 *
2224 * @param {String} direction
2225 * @returns {Boolean}
2226 */
2227 is: function is(direction) {
2228 return this.value === direction;
2229 },
2230
2231 /**
2232 * Applies direction class to the root HTML element.
2233 *
2234 * @return {Void}
2235 */
2236 addClass: function addClass() {
2237 Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]);
2238 },
2239
2240 /**
2241 * Removes direction class from the root HTML element.
2242 *
2243 * @return {Void}
2244 */
2245 removeClass: function removeClass() {
2246 Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]);
2247 }
2248 };
2249 define(Direction, 'value', {
2250 /**
2251 * Gets value of the direction.
2252 *
2253 * @returns {Number}
2254 */
2255 get: function get() {
2256 return Direction._v;
2257 },
2258
2259 /**
2260 * Sets value of the direction.
2261 *
2262 * @param {String} value
2263 * @return {Void}
2264 */
2265 set: function set(value) {
2266 if (VALID_DIRECTIONS.indexOf(value) > -1) {
2267 Direction._v = value;
2268 } else {
2269 warn('Direction value must be `ltr` or `rtl`');
2270 }
2271 }
2272 });
2273 /**
2274 * Clear direction class:
2275 * - on destroy to bring HTML to its initial state
2276 * - on update to remove class before reappling bellow
2277 */
2278
2279 Events.on(['destroy', 'update'], function () {
2280 Direction.removeClass();
2281 });
2282 /**
2283 * Remount component:
2284 * - on update to reflect changes in direction value
2285 */
2286
2287 Events.on('update', function () {
2288 Direction.mount();
2289 });
2290 /**
2291 * Apply direction class:
2292 * - before building to apply class for the first time
2293 * - on updating to reapply direction class that may changed
2294 */
2295
2296 Events.on(['build.before', 'update'], function () {
2297 Direction.addClass();
2298 });
2299 return Direction;
2300 }
2301
2302 /**
2303 * Reflects value of glide movement.
2304 *
2305 * @param {Object} Glide
2306 * @param {Object} Components
2307 * @return {Object}
2308 */
2309 function Rtl (Glide, Components) {
2310 return {
2311 /**
2312 * Negates the passed translate if glide is in RTL option.
2313 *
2314 * @param {Number} translate
2315 * @return {Number}
2316 */
2317 modify: function modify(translate) {
2318 if (Components.Direction.is('rtl')) {
2319 return -translate;
2320 }
2321
2322 return translate;
2323 }
2324 };
2325 }
2326
2327 /**
2328 * Updates glide movement with a `gap` settings.
2329 *
2330 * @param {Object} Glide
2331 * @param {Object} Components
2332 * @return {Object}
2333 */
2334 function Gap (Glide, Components) {
2335 return {
2336 /**
2337 * Modifies passed translate value with number in the `gap` settings.
2338 *
2339 * @param {Number} translate
2340 * @return {Number}
2341 */
2342 modify: function modify(translate) {
2343 var multiplier = Math.floor(translate / Components.Sizes.slideWidth);
2344 return translate + Components.Gaps.value * multiplier;
2345 }
2346 };
2347 }
2348
2349 /**
2350 * Updates glide movement with width of additional clones width.
2351 *
2352 * @param {Object} Glide
2353 * @param {Object} Components
2354 * @return {Object}
2355 */
2356 function Grow (Glide, Components) {
2357 return {
2358 /**
2359 * Adds to the passed translate width of the half of clones.
2360 *
2361 * @param {Number} translate
2362 * @return {Number}
2363 */
2364 modify: function modify(translate) {
2365 return translate + Components.Clones.grow / 2;
2366 }
2367 };
2368 }
2369
2370 /**
2371 * Updates glide movement with a `peek` settings.
2372 *
2373 * @param {Object} Glide
2374 * @param {Object} Components
2375 * @return {Object}
2376 */
2377
2378 function Peeking (Glide, Components) {
2379 return {
2380 /**
2381 * Modifies passed translate value with a `peek` setting.
2382 *
2383 * @param {Number} translate
2384 * @return {Number}
2385 */
2386 modify: function modify(translate) {
2387 if (Glide.settings.focusAt >= 0) {
2388 var peek = Components.Peek.value;
2389
2390 if (isObject(peek)) {
2391 return translate - peek.before;
2392 }
2393
2394 return translate - peek;
2395 }
2396
2397 return translate;
2398 }
2399 };
2400 }
2401
2402 /**
2403 * Updates glide movement with a `focusAt` settings.
2404 *
2405 * @param {Object} Glide
2406 * @param {Object} Components
2407 * @return {Object}
2408 */
2409 function Focusing (Glide, Components) {
2410 return {
2411 /**
2412 * Modifies passed translate value with index in the `focusAt` setting.
2413 *
2414 * @param {Number} translate
2415 * @return {Number}
2416 */
2417 modify: function modify(translate) {
2418 var gap = Components.Gaps.value;
2419 var width = Components.Sizes.width;
2420 var focusAt = Glide.settings.focusAt;
2421 var slideWidth = Components.Sizes.slideWidth;
2422
2423 if (focusAt === 'center') {
2424 return translate - (width / 2 - slideWidth / 2);
2425 }
2426
2427 return translate - slideWidth * focusAt - gap * focusAt;
2428 }
2429 };
2430 }
2431
2432 /**
2433 * Applies diffrent transformers on translate value.
2434 *
2435 * @param {Object} Glide
2436 * @param {Object} Components
2437 * @return {Object}
2438 */
2439
2440 function mutator (Glide, Components, Events) {
2441 /**
2442 * Merge instance transformers with collection of default transformers.
2443 * It's important that the Rtl component be last on the list,
2444 * so it reflects all previous transformations.
2445 *
2446 * @type {Array}
2447 */
2448 var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]);
2449 return {
2450 /**
2451 * Piplines translate value with registered transformers.
2452 *
2453 * @param {Number} translate
2454 * @return {Number}
2455 */
2456 mutate: function mutate(translate) {
2457 for (var i = 0; i < TRANSFORMERS.length; i++) {
2458 var transformer = TRANSFORMERS[i];
2459
2460 if (isFunction(transformer) && isFunction(transformer().modify)) {
2461 translate = transformer(Glide, Components, Events).modify(translate);
2462 } else {
2463 warn('Transformer should be a function that returns an object with `modify()` method');
2464 }
2465 }
2466
2467 return translate;
2468 }
2469 };
2470 }
2471
2472 function Translate (Glide, Components, Events) {
2473 var Translate = {
2474 /**
2475 * Sets value of translate on HTML element.
2476 *
2477 * @param {Number} value
2478 * @return {Void}
2479 */
2480 set: function set(value) {
2481 var transform = mutator(Glide, Components).mutate(value);
2482 var translate3d = "translate3d(".concat(-1 * transform, "px, 0px, 0px)");
2483 Components.Html.wrapper.style.mozTransform = translate3d; // needed for supported Firefox 10-15
2484
2485 Components.Html.wrapper.style.webkitTransform = translate3d; // needed for supported Chrome 10-35, Safari 5.1-8, and Opera 15-22
2486
2487 Components.Html.wrapper.style.transform = translate3d;
2488 },
2489
2490 /**
2491 * Removes value of translate from HTML element.
2492 *
2493 * @return {Void}
2494 */
2495 remove: function remove() {
2496 Components.Html.wrapper.style.transform = '';
2497 },
2498
2499 /**
2500 * @return {number}
2501 */
2502 getStartIndex: function getStartIndex() {
2503 var length = Components.Sizes.length;
2504 var index = Glide.index;
2505 var perView = Glide.settings.perView;
2506
2507 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
2508 return length + (index - perView);
2509 } // "modulo length" converts an index that equals length to zero
2510
2511
2512 return (index + perView) % length;
2513 },
2514
2515 /**
2516 * @return {number}
2517 */
2518 getTravelDistance: function getTravelDistance() {
2519 var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView;
2520
2521 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
2522 // reverse travel distance so that we don't have to change subtract operations
2523 return travelDistance * -1;
2524 }
2525
2526 return travelDistance;
2527 }
2528 };
2529 /**
2530 * Set new translate value:
2531 * - on move to reflect index change
2532 * - on updating via API to reflect possible changes in options
2533 */
2534
2535 Events.on('move', function (context) {
2536 if (!Glide.isType('carousel') || !Components.Run.isOffset()) {
2537 return Translate.set(context.movement);
2538 }
2539
2540 Components.Transition.after(function () {
2541 Events.emit('translate.jump');
2542 Translate.set(Components.Sizes.slideWidth * Glide.index);
2543 });
2544 var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex();
2545 return Translate.set(startWidth - Components.Translate.getTravelDistance());
2546 });
2547 /**
2548 * Remove translate:
2549 * - on destroying to bring markup to its inital state
2550 */
2551
2552 Events.on('destroy', function () {
2553 Translate.remove();
2554 });
2555 return Translate;
2556 }
2557
2558 function Transition (Glide, Components, Events) {
2559 /**
2560 * Holds inactivity status of transition.
2561 * When true transition is not applied.
2562 *
2563 * @type {Boolean}
2564 */
2565 var disabled = false;
2566 var Transition = {
2567 /**
2568 * Composes string of the CSS transition.
2569 *
2570 * @param {String} property
2571 * @return {String}
2572 */
2573 compose: function compose(property) {
2574 var settings = Glide.settings;
2575
2576 if (!disabled) {
2577 return "".concat(property, " ").concat(this.duration, "ms ").concat(settings.animationTimingFunc);
2578 }
2579
2580 return "".concat(property, " 0ms ").concat(settings.animationTimingFunc);
2581 },
2582
2583 /**
2584 * Sets value of transition on HTML element.
2585 *
2586 * @param {String=} property
2587 * @return {Void}
2588 */
2589 set: function set() {
2590 var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform';
2591 Components.Html.wrapper.style.transition = this.compose(property);
2592 },
2593
2594 /**
2595 * Removes value of transition from HTML element.
2596 *
2597 * @return {Void}
2598 */
2599 remove: function remove() {
2600 Components.Html.wrapper.style.transition = '';
2601 },
2602
2603 /**
2604 * Runs callback after animation.
2605 *
2606 * @param {Function} callback
2607 * @return {Void}
2608 */
2609 after: function after(callback) {
2610 setTimeout(function () {
2611 callback();
2612 }, this.duration);
2613 },
2614
2615 /**
2616 * Enable transition.
2617 *
2618 * @return {Void}
2619 */
2620 enable: function enable() {
2621 disabled = false;
2622 this.set();
2623 },
2624
2625 /**
2626 * Disable transition.
2627 *
2628 * @return {Void}
2629 */
2630 disable: function disable() {
2631 disabled = true;
2632 this.set();
2633 }
2634 };
2635 define(Transition, 'duration', {
2636 /**
2637 * Gets duration of the transition based
2638 * on currently running animation type.
2639 *
2640 * @return {Number}
2641 */
2642 get: function get() {
2643 var settings = Glide.settings;
2644
2645 if (Glide.isType('slider') && Components.Run.offset) {
2646 return settings.rewindDuration;
2647 }
2648
2649 return settings.animationDuration;
2650 }
2651 });
2652 /**
2653 * Set transition `style` value:
2654 * - on each moving, because it may be cleared by offset move
2655 */
2656
2657 Events.on('move', function () {
2658 Transition.set();
2659 });
2660 /**
2661 * Disable transition:
2662 * - before initial build to avoid transitioning from `0` to `startAt` index
2663 * - while resizing window and recalculating dimensions
2664 * - on jumping from offset transition at start and end edges in `carousel` type
2665 */
2666
2667 Events.on(['build.before', 'resize', 'translate.jump'], function () {
2668 Transition.disable();
2669 });
2670 /**
2671 * Enable transition:
2672 * - on each running, because it may be disabled by offset move
2673 */
2674
2675 Events.on('run', function () {
2676 Transition.enable();
2677 });
2678 /**
2679 * Remove transition:
2680 * - on destroying to bring markup to its inital state
2681 */
2682
2683 Events.on('destroy', function () {
2684 Transition.remove();
2685 });
2686 return Transition;
2687 }
2688
2689 /**
2690 * Test via a getter in the options object to see
2691 * if the passive property is accessed.
2692 *
2693 * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
2694 */
2695 var supportsPassive = false;
2696
2697 try {
2698 var opts = Object.defineProperty({}, 'passive', {
2699 get: function get() {
2700 supportsPassive = true;
2701 }
2702 });
2703 window.addEventListener('testPassive', null, opts);
2704 window.removeEventListener('testPassive', null, opts);
2705 } catch (e) {}
2706
2707 var supportsPassive$1 = supportsPassive;
2708
2709 var START_EVENTS = ['touchstart', 'mousedown'];
2710 var MOVE_EVENTS = ['touchmove', 'mousemove'];
2711 var END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave'];
2712 var MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave'];
2713 function Swipe (Glide, Components, Events) {
2714 /**
2715 * Instance of the binder for DOM Events.
2716 *
2717 * @type {EventsBinder}
2718 */
2719 var Binder = new EventsBinder();
2720 var swipeSin = 0;
2721 var swipeStartX = 0;
2722 var swipeStartY = 0;
2723 var disabled = false;
2724 var capture = supportsPassive$1 ? {
2725 passive: true
2726 } : false;
2727 var Swipe = {
2728 /**
2729 * Initializes swipe bindings.
2730 *
2731 * @return {Void}
2732 */
2733 mount: function mount() {
2734 this.bindSwipeStart();
2735 },
2736
2737 /**
2738 * Handler for `swipestart` event. Calculates entry points of the user's tap.
2739 *
2740 * @param {Object} event
2741 * @return {Void}
2742 */
2743 start: function start(event) {
2744 if (!disabled && !Glide.disabled) {
2745 this.disable();
2746 var swipe = this.touches(event);
2747 swipeSin = null;
2748 swipeStartX = toInt(swipe.pageX);
2749 swipeStartY = toInt(swipe.pageY);
2750 this.bindSwipeMove();
2751 this.bindSwipeEnd();
2752 Events.emit('swipe.start');
2753 }
2754 },
2755
2756 /**
2757 * Handler for `swipemove` event. Calculates user's tap angle and distance.
2758 *
2759 * @param {Object} event
2760 */
2761 move: function move(event) {
2762 if (!Glide.disabled) {
2763 var _Glide$settings = Glide.settings,
2764 touchAngle = _Glide$settings.touchAngle,
2765 touchRatio = _Glide$settings.touchRatio,
2766 classes = _Glide$settings.classes;
2767 var swipe = this.touches(event);
2768 var subExSx = toInt(swipe.pageX) - swipeStartX;
2769 var subEySy = toInt(swipe.pageY) - swipeStartY;
2770 var powEX = Math.abs(subExSx << 2);
2771 var powEY = Math.abs(subEySy << 2);
2772 var swipeHypotenuse = Math.sqrt(powEX + powEY);
2773 var swipeCathetus = Math.sqrt(powEY);
2774 swipeSin = Math.asin(swipeCathetus / swipeHypotenuse);
2775
2776 if (swipeSin * 180 / Math.PI < touchAngle) {
2777 event.stopPropagation();
2778 Components.Move.make(subExSx * toFloat(touchRatio));
2779 Components.Html.root.classList.add(classes.dragging);
2780 Events.emit('swipe.move');
2781 } else {
2782 return false;
2783 }
2784 }
2785 },
2786
2787 /**
2788 * Handler for `swipeend` event. Finitializes user's tap and decides about glide move.
2789 *
2790 * @param {Object} event
2791 * @return {Void}
2792 */
2793 end: function end(event) {
2794 if (!Glide.disabled) {
2795 var _Glide$settings2 = Glide.settings,
2796 perSwipe = _Glide$settings2.perSwipe,
2797 touchAngle = _Glide$settings2.touchAngle,
2798 classes = _Glide$settings2.classes;
2799 var swipe = this.touches(event);
2800 var threshold = this.threshold(event);
2801 var swipeDistance = swipe.pageX - swipeStartX;
2802 var swipeDeg = swipeSin * 180 / Math.PI;
2803 this.enable();
2804
2805 if (swipeDistance > threshold && swipeDeg < touchAngle) {
2806 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<")));
2807 } else if (swipeDistance < -threshold && swipeDeg < touchAngle) {
2808 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">")));
2809 } else {
2810 // While swipe don't reach distance apply previous transform.
2811 Components.Move.make();
2812 }
2813
2814 Components.Html.root.classList.remove(classes.dragging);
2815 this.unbindSwipeMove();
2816 this.unbindSwipeEnd();
2817 Events.emit('swipe.end');
2818 }
2819 },
2820
2821 /**
2822 * Binds swipe's starting event.
2823 *
2824 * @return {Void}
2825 */
2826 bindSwipeStart: function bindSwipeStart() {
2827 var _this = this;
2828
2829 var _Glide$settings3 = Glide.settings,
2830 swipeThreshold = _Glide$settings3.swipeThreshold,
2831 dragThreshold = _Glide$settings3.dragThreshold;
2832
2833 if (swipeThreshold) {
2834 Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) {
2835 _this.start(event);
2836 }, capture);
2837 }
2838
2839 if (dragThreshold) {
2840 Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) {
2841 _this.start(event);
2842 }, capture);
2843 }
2844 },
2845
2846 /**
2847 * Unbinds swipe's starting event.
2848 *
2849 * @return {Void}
2850 */
2851 unbindSwipeStart: function unbindSwipeStart() {
2852 Binder.off(START_EVENTS[0], Components.Html.wrapper, capture);
2853 Binder.off(START_EVENTS[1], Components.Html.wrapper, capture);
2854 },
2855
2856 /**
2857 * Binds swipe's moving event.
2858 *
2859 * @return {Void}
2860 */
2861 bindSwipeMove: function bindSwipeMove() {
2862 var _this2 = this;
2863
2864 Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) {
2865 _this2.move(event);
2866 }, Glide.settings.throttle), capture);
2867 },
2868
2869 /**
2870 * Unbinds swipe's moving event.
2871 *
2872 * @return {Void}
2873 */
2874 unbindSwipeMove: function unbindSwipeMove() {
2875 Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture);
2876 },
2877
2878 /**
2879 * Binds swipe's ending event.
2880 *
2881 * @return {Void}
2882 */
2883 bindSwipeEnd: function bindSwipeEnd() {
2884 var _this3 = this;
2885
2886 Binder.on(END_EVENTS, Components.Html.wrapper, function (event) {
2887 _this3.end(event);
2888 });
2889 },
2890
2891 /**
2892 * Unbinds swipe's ending event.
2893 *
2894 * @return {Void}
2895 */
2896 unbindSwipeEnd: function unbindSwipeEnd() {
2897 Binder.off(END_EVENTS, Components.Html.wrapper);
2898 },
2899
2900 /**
2901 * Normalizes event touches points accorting to different types.
2902 *
2903 * @param {Object} event
2904 */
2905 touches: function touches(event) {
2906 if (MOUSE_EVENTS.indexOf(event.type) > -1) {
2907 return event;
2908 }
2909
2910 return event.touches[0] || event.changedTouches[0];
2911 },
2912
2913 /**
2914 * Gets value of minimum swipe distance settings based on event type.
2915 *
2916 * @return {Number}
2917 */
2918 threshold: function threshold(event) {
2919 var settings = Glide.settings;
2920
2921 if (MOUSE_EVENTS.indexOf(event.type) > -1) {
2922 return settings.dragThreshold;
2923 }
2924
2925 return settings.swipeThreshold;
2926 },
2927
2928 /**
2929 * Enables swipe event.
2930 *
2931 * @return {self}
2932 */
2933 enable: function enable() {
2934 disabled = false;
2935 Components.Transition.enable();
2936 return this;
2937 },
2938
2939 /**
2940 * Disables swipe event.
2941 *
2942 * @return {self}
2943 */
2944 disable: function disable() {
2945 disabled = true;
2946 Components.Transition.disable();
2947 return this;
2948 }
2949 };
2950 /**
2951 * Add component class:
2952 * - after initial building
2953 */
2954
2955 Events.on('build.after', function () {
2956 Components.Html.root.classList.add(Glide.settings.classes.swipeable);
2957 });
2958 /**
2959 * Remove swiping bindings:
2960 * - on destroying, to remove added EventListeners
2961 */
2962
2963 Events.on('destroy', function () {
2964 Swipe.unbindSwipeStart();
2965 Swipe.unbindSwipeMove();
2966 Swipe.unbindSwipeEnd();
2967 Binder.destroy();
2968 });
2969 return Swipe;
2970 }
2971
2972 function Images (Glide, Components, Events) {
2973 /**
2974 * Instance of the binder for DOM Events.
2975 *
2976 * @type {EventsBinder}
2977 */
2978 var Binder = new EventsBinder();
2979 var Images = {
2980 /**
2981 * Binds listener to glide wrapper.
2982 *
2983 * @return {Void}
2984 */
2985 mount: function mount() {
2986 this.bind();
2987 },
2988
2989 /**
2990 * Binds `dragstart` event on wrapper to prevent dragging images.
2991 *
2992 * @return {Void}
2993 */
2994 bind: function bind() {
2995 Binder.on('dragstart', Components.Html.wrapper, this.dragstart);
2996 },
2997
2998 /**
2999 * Unbinds `dragstart` event on wrapper.
3000 *
3001 * @return {Void}
3002 */
3003 unbind: function unbind() {
3004 Binder.off('dragstart', Components.Html.wrapper);
3005 },
3006
3007 /**
3008 * Event handler. Prevents dragging.
3009 *
3010 * @return {Void}
3011 */
3012 dragstart: function dragstart(event) {
3013 event.preventDefault();
3014 }
3015 };
3016 /**
3017 * Remove bindings from images:
3018 * - on destroying, to remove added EventListeners
3019 */
3020
3021 Events.on('destroy', function () {
3022 Images.unbind();
3023 Binder.destroy();
3024 });
3025 return Images;
3026 }
3027
3028 function Anchors (Glide, Components, Events) {
3029 /**
3030 * Instance of the binder for DOM Events.
3031 *
3032 * @type {EventsBinder}
3033 */
3034 var Binder = new EventsBinder();
3035 /**
3036 * Holds detaching status of anchors.
3037 * Prevents detaching of already detached anchors.
3038 *
3039 * @private
3040 * @type {Boolean}
3041 */
3042
3043 var detached = false;
3044 /**
3045 * Holds preventing status of anchors.
3046 * If `true` redirection after click will be disabled.
3047 *
3048 * @private
3049 * @type {Boolean}
3050 */
3051
3052 var prevented = false;
3053 var Anchors = {
3054 /**
3055 * Setups a initial state of anchors component.
3056 *
3057 * @returns {Void}
3058 */
3059 mount: function mount() {
3060 /**
3061 * Holds collection of anchors elements.
3062 *
3063 * @private
3064 * @type {HTMLCollection}
3065 */
3066 this._a = Components.Html.wrapper.querySelectorAll('a');
3067 this.bind();
3068 },
3069
3070 /**
3071 * Binds events to anchors inside a track.
3072 *
3073 * @return {Void}
3074 */
3075 bind: function bind() {
3076 Binder.on('click', Components.Html.wrapper, this.click);
3077 },
3078
3079 /**
3080 * Unbinds events attached to anchors inside a track.
3081 *
3082 * @return {Void}
3083 */
3084 unbind: function unbind() {
3085 Binder.off('click', Components.Html.wrapper);
3086 },
3087
3088 /**
3089 * Handler for click event. Prevents clicks when glide is in `prevent` status.
3090 *
3091 * @param {Object} event
3092 * @return {Void}
3093 */
3094 click: function click(event) {
3095 if (prevented) {
3096 event.stopPropagation();
3097 event.preventDefault();
3098 }
3099 },
3100
3101 /**
3102 * Detaches anchors click event inside glide.
3103 *
3104 * @return {self}
3105 */
3106 detach: function detach() {
3107 prevented = true;
3108
3109 if (!detached) {
3110 for (var i = 0; i < this.items.length; i++) {
3111 this.items[i].draggable = false;
3112 }
3113
3114 detached = true;
3115 }
3116
3117 return this;
3118 },
3119
3120 /**
3121 * Attaches anchors click events inside glide.
3122 *
3123 * @return {self}
3124 */
3125 attach: function attach() {
3126 prevented = false;
3127
3128 if (detached) {
3129 for (var i = 0; i < this.items.length; i++) {
3130 this.items[i].draggable = true;
3131 }
3132
3133 detached = false;
3134 }
3135
3136 return this;
3137 }
3138 };
3139 define(Anchors, 'items', {
3140 /**
3141 * Gets collection of the arrows HTML elements.
3142 *
3143 * @return {HTMLElement[]}
3144 */
3145 get: function get() {
3146 return Anchors._a;
3147 }
3148 });
3149 /**
3150 * Detach anchors inside slides:
3151 * - on swiping, so they won't redirect to its `href` attributes
3152 */
3153
3154 Events.on('swipe.move', function () {
3155 Anchors.detach();
3156 });
3157 /**
3158 * Attach anchors inside slides:
3159 * - after swiping and transitions ends, so they can redirect after click again
3160 */
3161
3162 Events.on('swipe.end', function () {
3163 Components.Transition.after(function () {
3164 Anchors.attach();
3165 });
3166 });
3167 /**
3168 * Unbind anchors inside slides:
3169 * - on destroying, to bring anchors to its initial state
3170 */
3171
3172 Events.on('destroy', function () {
3173 Anchors.attach();
3174 Anchors.unbind();
3175 Binder.destroy();
3176 });
3177 return Anchors;
3178 }
3179
3180 var NAV_SELECTOR = '[data-glide-el="controls[nav]"]';
3181 var CONTROLS_SELECTOR = '[data-glide-el^="controls"]';
3182 var PREVIOUS_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\"<\"]");
3183 var NEXT_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\">\"]");
3184 function Controls (Glide, Components, Events) {
3185 /**
3186 * Instance of the binder for DOM Events.
3187 *
3188 * @type {EventsBinder}
3189 */
3190 var Binder = new EventsBinder();
3191 var capture = supportsPassive$1 ? {
3192 passive: true
3193 } : false;
3194 var Controls = {
3195 /**
3196 * Inits arrows. Binds events listeners
3197 * to the arrows HTML elements.
3198 *
3199 * @return {Void}
3200 */
3201 mount: function mount() {
3202 /**
3203 * Collection of navigation HTML elements.
3204 *
3205 * @private
3206 * @type {HTMLCollection}
3207 */
3208 this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR);
3209 /**
3210 * Collection of controls HTML elements.
3211 *
3212 * @private
3213 * @type {HTMLCollection}
3214 */
3215
3216 this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR);
3217 /**
3218 * Collection of arrow control HTML elements.
3219 *
3220 * @private
3221 * @type {Object}
3222 */
3223
3224 this._arrowControls = {
3225 previous: Components.Html.root.querySelectorAll(PREVIOUS_CONTROLS_SELECTOR),
3226 next: Components.Html.root.querySelectorAll(NEXT_CONTROLS_SELECTOR)
3227 };
3228 this.addBindings();
3229 },
3230
3231 /**
3232 * Sets active class to current slide.
3233 *
3234 * @return {Void}
3235 */
3236 setActive: function setActive() {
3237 for (var i = 0; i < this._n.length; i++) {
3238 this.addClass(this._n[i].children);
3239 }
3240 },
3241
3242 /**
3243 * Removes active class to current slide.
3244 *
3245 * @return {Void}
3246 */
3247 removeActive: function removeActive() {
3248 for (var i = 0; i < this._n.length; i++) {
3249 this.removeClass(this._n[i].children);
3250 }
3251 },
3252
3253 /**
3254 * Toggles active class on items inside navigation.
3255 *
3256 * @param {HTMLElement} controls
3257 * @return {Void}
3258 */
3259 addClass: function addClass(controls) {
3260 var settings = Glide.settings;
3261 var item = controls[Glide.index];
3262
3263 if (!item) {
3264 return;
3265 }
3266
3267 if (item) {
3268 item.classList.add(settings.classes.nav.active);
3269 siblings(item).forEach(function (sibling) {
3270 sibling.classList.remove(settings.classes.nav.active);
3271 });
3272 }
3273 },
3274
3275 /**
3276 * Removes active class from active control.
3277 *
3278 * @param {HTMLElement} controls
3279 * @return {Void}
3280 */
3281 removeClass: function removeClass(controls) {
3282 var item = controls[Glide.index];
3283
3284 if (item) {
3285 item.classList.remove(Glide.settings.classes.nav.active);
3286 }
3287 },
3288
3289 /**
3290 * Calculates, removes or adds `Glide.settings.classes.disabledArrow` class on the control arrows
3291 */
3292 setArrowState: function setArrowState() {
3293 if (Glide.settings.rewind) {
3294 return;
3295 }
3296
3297 var next = Controls._arrowControls.next;
3298 var previous = Controls._arrowControls.previous;
3299 this.resetArrowState(next, previous);
3300
3301 if (Glide.index === 0) {
3302 this.disableArrow(previous);
3303 }
3304
3305 if (Glide.index === Components.Run.length) {
3306 this.disableArrow(next);
3307 }
3308 },
3309
3310 /**
3311 * Removes `Glide.settings.classes.disabledArrow` from given NodeList elements
3312 *
3313 * @param {NodeList[]} lists
3314 */
3315 resetArrowState: function resetArrowState() {
3316 var settings = Glide.settings;
3317
3318 for (var _len = arguments.length, lists = new Array(_len), _key = 0; _key < _len; _key++) {
3319 lists[_key] = arguments[_key];
3320 }
3321
3322 lists.forEach(function (list) {
3323 list.forEach(function (element) {
3324 element.classList.remove(settings.classes.arrow.disabled);
3325 });
3326 });
3327 },
3328
3329 /**
3330 * Adds `Glide.settings.classes.disabledArrow` to given NodeList elements
3331 *
3332 * @param {NodeList[]} lists
3333 */
3334 disableArrow: function disableArrow() {
3335 var settings = Glide.settings;
3336
3337 for (var _len2 = arguments.length, lists = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
3338 lists[_key2] = arguments[_key2];
3339 }
3340
3341 lists.forEach(function (list) {
3342 list.forEach(function (element) {
3343 element.classList.add(settings.classes.arrow.disabled);
3344 });
3345 });
3346 },
3347
3348 /**
3349 * Adds handles to the each group of controls.
3350 *
3351 * @return {Void}
3352 */
3353 addBindings: function addBindings() {
3354 for (var i = 0; i < this._c.length; i++) {
3355 this.bind(this._c[i].children);
3356 }
3357 },
3358
3359 /**
3360 * Removes handles from the each group of controls.
3361 *
3362 * @return {Void}
3363 */
3364 removeBindings: function removeBindings() {
3365 for (var i = 0; i < this._c.length; i++) {
3366 this.unbind(this._c[i].children);
3367 }
3368 },
3369
3370 /**
3371 * Binds events to arrows HTML elements.
3372 *
3373 * @param {HTMLCollection} elements
3374 * @return {Void}
3375 */
3376 bind: function bind(elements) {
3377 for (var i = 0; i < elements.length; i++) {
3378 Binder.on('click', elements[i], this.click);
3379 Binder.on('touchstart', elements[i], this.click, capture);
3380 }
3381 },
3382
3383 /**
3384 * Unbinds events binded to the arrows HTML elements.
3385 *
3386 * @param {HTMLCollection} elements
3387 * @return {Void}
3388 */
3389 unbind: function unbind(elements) {
3390 for (var i = 0; i < elements.length; i++) {
3391 Binder.off(['click', 'touchstart'], elements[i]);
3392 }
3393 },
3394
3395 /**
3396 * Handles `click` event on the arrows HTML elements.
3397 * Moves slider in direction given via the
3398 * `data-glide-dir` attribute.
3399 *
3400 * @param {Object} event
3401 * @return {void}
3402 */
3403 click: function click(event) {
3404 if (!supportsPassive$1 && event.type === 'touchstart') {
3405 event.preventDefault();
3406 }
3407
3408 var direction = event.currentTarget.getAttribute('data-glide-dir');
3409 Components.Run.make(Components.Direction.resolve(direction));
3410 }
3411 };
3412 define(Controls, 'items', {
3413 /**
3414 * Gets collection of the controls HTML elements.
3415 *
3416 * @return {HTMLElement[]}
3417 */
3418 get: function get() {
3419 return Controls._c;
3420 }
3421 });
3422 /**
3423 * Swap active class of current navigation item:
3424 * - after mounting to set it to initial index
3425 * - after each move to the new index
3426 */
3427
3428 Events.on(['mount.after', 'move.after'], function () {
3429 Controls.setActive();
3430 });
3431 /**
3432 * Add or remove disabled class of arrow elements
3433 */
3434
3435 Events.on(['mount.after', 'run'], function () {
3436 Controls.setArrowState();
3437 });
3438 /**
3439 * Remove bindings and HTML Classes:
3440 * - on destroying, to bring markup to its initial state
3441 */
3442
3443 Events.on('destroy', function () {
3444 Controls.removeBindings();
3445 Controls.removeActive();
3446 Binder.destroy();
3447 });
3448 return Controls;
3449 }
3450
3451 function Keyboard (Glide, Components, Events) {
3452 /**
3453 * Instance of the binder for DOM Events.
3454 *
3455 * @type {EventsBinder}
3456 */
3457 var Binder = new EventsBinder();
3458 var Keyboard = {
3459 /**
3460 * Binds keyboard events on component mount.
3461 *
3462 * @return {Void}
3463 */
3464 mount: function mount() {
3465 if (Glide.settings.keyboard) {
3466 this.bind();
3467 }
3468 },
3469
3470 /**
3471 * Adds keyboard press events.
3472 *
3473 * @return {Void}
3474 */
3475 bind: function bind() {
3476 Binder.on('keyup', document, this.press);
3477 },
3478
3479 /**
3480 * Removes keyboard press events.
3481 *
3482 * @return {Void}
3483 */
3484 unbind: function unbind() {
3485 Binder.off('keyup', document);
3486 },
3487
3488 /**
3489 * Handles keyboard's arrows press and moving glide foward and backward.
3490 *
3491 * @param {Object} event
3492 * @return {Void}
3493 */
3494 press: function press(event) {
3495 var perSwipe = Glide.settings.perSwipe;
3496
3497 if (event.keyCode === 39) {
3498 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">")));
3499 }
3500
3501 if (event.keyCode === 37) {
3502 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<")));
3503 }
3504 }
3505 };
3506 /**
3507 * Remove bindings from keyboard:
3508 * - on destroying to remove added events
3509 * - on updating to remove events before remounting
3510 */
3511
3512 Events.on(['destroy', 'update'], function () {
3513 Keyboard.unbind();
3514 });
3515 /**
3516 * Remount component
3517 * - on updating to reflect potential changes in settings
3518 */
3519
3520 Events.on('update', function () {
3521 Keyboard.mount();
3522 });
3523 /**
3524 * Destroy binder:
3525 * - on destroying to remove listeners
3526 */
3527
3528 Events.on('destroy', function () {
3529 Binder.destroy();
3530 });
3531 return Keyboard;
3532 }
3533
3534 function Autoplay (Glide, Components, Events) {
3535 /**
3536 * Instance of the binder for DOM Events.
3537 *
3538 * @type {EventsBinder}
3539 */
3540 var Binder = new EventsBinder();
3541 var Autoplay = {
3542 /**
3543 * Initializes autoplaying and events.
3544 *
3545 * @return {Void}
3546 */
3547 mount: function mount() {
3548 this.enable();
3549 this.start();
3550
3551 if (Glide.settings.hoverpause) {
3552 this.bind();
3553 }
3554 },
3555
3556 /**
3557 * Enables autoplaying
3558 *
3559 * @returns {Void}
3560 */
3561 enable: function enable() {
3562 this._e = true;
3563 },
3564
3565 /**
3566 * Disables autoplaying.
3567 *
3568 * @returns {Void}
3569 */
3570 disable: function disable() {
3571 this._e = false;
3572 },
3573
3574 /**
3575 * Starts autoplaying in configured interval.
3576 *
3577 * @param {Boolean|Number} force Run autoplaying with passed interval regardless of `autoplay` settings
3578 * @return {Void}
3579 */
3580 start: function start() {
3581 var _this = this;
3582
3583 if (!this._e) {
3584 return;
3585 }
3586
3587 this.enable();
3588
3589 if (Glide.settings.autoplay) {
3590 if (isUndefined(this._i)) {
3591 this._i = setInterval(function () {
3592 _this.stop();
3593
3594 Components.Run.make('>');
3595
3596 _this.start();
3597
3598 Events.emit('autoplay');
3599 }, this.time);
3600 }
3601 }
3602 },
3603
3604 /**
3605 * Stops autorunning of the glide.
3606 *
3607 * @return {Void}
3608 */
3609 stop: function stop() {
3610 this._i = clearInterval(this._i);
3611 },
3612
3613 /**
3614 * Stops autoplaying while mouse is over glide's area.
3615 *
3616 * @return {Void}
3617 */
3618 bind: function bind() {
3619 var _this2 = this;
3620
3621 Binder.on('mouseover', Components.Html.root, function () {
3622 if (_this2._e) {
3623 _this2.stop();
3624 }
3625 });
3626 Binder.on('mouseout', Components.Html.root, function () {
3627 if (_this2._e) {
3628 _this2.start();
3629 }
3630 });
3631 },
3632
3633 /**
3634 * Unbind mouseover events.
3635 *
3636 * @returns {Void}
3637 */
3638 unbind: function unbind() {
3639 Binder.off(['mouseover', 'mouseout'], Components.Html.root);
3640 }
3641 };
3642 define(Autoplay, 'time', {
3643 /**
3644 * Gets time period value for the autoplay interval. Prioritizes
3645 * times in `data-glide-autoplay` attrubutes over options.
3646 *
3647 * @return {Number}
3648 */
3649 get: function get() {
3650 var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay');
3651
3652 if (autoplay) {
3653 return toInt(autoplay);
3654 }
3655
3656 return toInt(Glide.settings.autoplay);
3657 }
3658 });
3659 /**
3660 * Stop autoplaying and unbind events:
3661 * - on destroying, to clear defined interval
3662 * - on updating via API to reset interval that may changed
3663 */
3664
3665 Events.on(['destroy', 'update'], function () {
3666 Autoplay.unbind();
3667 });
3668 /**
3669 * Stop autoplaying:
3670 * - before each run, to restart autoplaying
3671 * - on pausing via API
3672 * - on destroying, to clear defined interval
3673 * - while starting a swipe
3674 * - on updating via API to reset interval that may changed
3675 */
3676
3677 Events.on(['run.before', 'swipe.start', 'update'], function () {
3678 Autoplay.stop();
3679 });
3680 Events.on(['pause', 'destroy'], function () {
3681 Autoplay.disable();
3682 Autoplay.stop();
3683 });
3684 /**
3685 * Start autoplaying:
3686 * - after each run, to restart autoplaying
3687 * - on playing via API
3688 * - while ending a swipe
3689 */
3690
3691 Events.on(['run.after', 'swipe.end'], function () {
3692 Autoplay.start();
3693 });
3694 /**
3695 * Start autoplaying:
3696 * - after each run, to restart autoplaying
3697 * - on playing via API
3698 * - while ending a swipe
3699 */
3700
3701 Events.on(['play'], function () {
3702 Autoplay.enable();
3703 Autoplay.start();
3704 });
3705 /**
3706 * Remount autoplaying:
3707 * - on updating via API to reset interval that may changed
3708 */
3709
3710 Events.on('update', function () {
3711 Autoplay.mount();
3712 });
3713 /**
3714 * Destroy a binder:
3715 * - on destroying glide instance to clearup listeners
3716 */
3717
3718 Events.on('destroy', function () {
3719 Binder.destroy();
3720 });
3721 return Autoplay;
3722 }
3723
3724 /**
3725 * Sorts keys of breakpoint object so they will be ordered from lower to bigger.
3726 *
3727 * @param {Object} points
3728 * @returns {Object}
3729 */
3730
3731 function sortBreakpoints(points) {
3732 if (isObject(points)) {
3733 return sortKeys(points);
3734 } else {
3735 warn("Breakpoints option must be an object");
3736 }
3737
3738 return {};
3739 }
3740
3741 function Breakpoints (Glide, Components, Events) {
3742 /**
3743 * Instance of the binder for DOM Events.
3744 *
3745 * @type {EventsBinder}
3746 */
3747 var Binder = new EventsBinder();
3748 /**
3749 * Holds reference to settings.
3750 *
3751 * @type {Object}
3752 */
3753
3754 var settings = Glide.settings;
3755 /**
3756 * Holds reference to breakpoints object in settings. Sorts breakpoints
3757 * from smaller to larger. It is required in order to proper
3758 * matching currently active breakpoint settings.
3759 *
3760 * @type {Object}
3761 */
3762
3763 var points = sortBreakpoints(settings.breakpoints);
3764 /**
3765 * Cache initial settings before overwritting.
3766 *
3767 * @type {Object}
3768 */
3769
3770 var defaults = Object.assign({}, settings);
3771 var Breakpoints = {
3772 /**
3773 * Matches settings for currectly matching media breakpoint.
3774 *
3775 * @param {Object} points
3776 * @returns {Object}
3777 */
3778 match: function match(points) {
3779 if (typeof window.matchMedia !== 'undefined') {
3780 for (var point in points) {
3781 if (points.hasOwnProperty(point)) {
3782 if (window.matchMedia("(max-width: ".concat(point, "px)")).matches) {
3783 return points[point];
3784 }
3785 }
3786 }
3787 }
3788
3789 return defaults;
3790 }
3791 };
3792 /**
3793 * Overwrite instance settings with currently matching breakpoint settings.
3794 * This happens right after component initialization.
3795 */
3796
3797 Object.assign(settings, Breakpoints.match(points));
3798 /**
3799 * Update glide with settings of matched brekpoint:
3800 * - window resize to update slider
3801 */
3802
3803 Binder.on('resize', window, throttle(function () {
3804 Glide.settings = mergeOptions(settings, Breakpoints.match(points));
3805 }, Glide.settings.throttle));
3806 /**
3807 * Resort and update default settings:
3808 * - on reinit via API, so breakpoint matching will be performed with options
3809 */
3810
3811 Events.on('update', function () {
3812 points = sortBreakpoints(points);
3813 defaults = Object.assign({}, settings);
3814 });
3815 /**
3816 * Unbind resize listener:
3817 * - on destroying, to bring markup to its initial state
3818 */
3819
3820 Events.on('destroy', function () {
3821 Binder.off('resize', window);
3822 });
3823 return Breakpoints;
3824 }
3825
3826 var COMPONENTS = {
3827 // Required
3828 Html: Html,
3829 Translate: Translate,
3830 Transition: Transition,
3831 Direction: Direction,
3832 Peek: Peek,
3833 Sizes: Sizes,
3834 Gaps: Gaps,
3835 Move: Move,
3836 Clones: Clones,
3837 Resize: Resize,
3838 Build: Build,
3839 Run: Run,
3840 // Optional
3841 Swipe: Swipe,
3842 Images: Images,
3843 Anchors: Anchors,
3844 Controls: Controls,
3845 Keyboard: Keyboard,
3846 Autoplay: Autoplay,
3847 Breakpoints: Breakpoints
3848 };
3849
3850 var Glide = /*#__PURE__*/function (_Core) {
3851 _inherits(Glide, _Core);
3852
3853 var _super = _createSuper(Glide);
3854
3855 function Glide() {
3856 _classCallCheck(this, Glide);
3857
3858 return _super.apply(this, arguments);
3859 }
3860
3861 _createClass(Glide, [{
3862 key: "mount",
3863 value: function mount() {
3864 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3865 return _get(_getPrototypeOf(Glide.prototype), "mount", this).call(this, Object.assign({}, COMPONENTS, extensions));
3866 }
3867 }]);
3868
3869 return Glide;
3870 }(Glide$1);
3871
3872 return Glide;
3873
3874}));