UNPKG

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