vendor: 7,201 bytes, line 1
1!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AOS=t():e.AOS=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},r=n(1),a=(o(r),n(6)),u=o(a),c=n(7),f=o(c),s=n(8),d=o(s),l=n(9),p=o(l),m=n(10),b=o(m),v=n(11),y=o(v),g=n(14),h=o(g),w=[],k=!1,x={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,startEvent:"DOMContentLoaded",throttleDelay:99,debounceDelay:50,disableMutationObserver:!1},j=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(e&&(k=!0),k)return w=(0,y.default)(w,x),(0,b.default)(w,x.once),w},O=function(){w=(0,h.default)(),j()},_=function(){w.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay")})},S=function(e){return e===!0||"mobile"===e&&p.default.mobile()||"phone"===e&&p.default.phone()||"tablet"===e&&p.default.tablet()||"function"==typeof e&&e()===!0},z=function(e){x=i(x,e),w=(0,h.default)();var t=document.all&&!window.atob;return S(x.disable)||t?_():(document.querySelector("body").setAttribute("data-aos-easing",x.easing),document.querySelector("body").setAttribute("data-aos-duration",x.duration),document.querySelector("body").setAttribute("data-aos-delay",x.delay),"DOMContentLoaded"===x.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1?j(!0):"load"===x.startEvent?window.addEventListener(x.startEvent,function(){j(!0)}):document.addEventListener(x.startEvent,function(){j(!0)}),window.addEventListener("resize",(0,f.default)(j,x.debounceDelay,!0)),window.addEventListener("orientationchange",(0,f.default)(j,x.debounceDelay,!0)),window.addEventListener("scroll",(0,u.default)(function(){(0,b.default)(w,x.once)},x.throttleDelay)),x.disableMutationObserver||(0,d.default)("[data-aos]",O),w)};e.exports={init:z,refresh:j,refreshHard:O}},function(e,t){},,,,,function(e,t){(function(t){"use strict";function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.apply(o,n)}function r(e){return k=e,h=setTimeout(s,t),_?o(e):g}function a(e){var n=e-w,o=e-k,i=t-n;return S?j(i,y-o):i}function c(e){var n=e-w,o=e-k;return void 0===w||n>=t||n<0||S&&o>=y}function s(){var e=O();return c(e)?d(e):void(h=setTimeout(s,a(e)))}function d(e){return h=void 0,z&&b?o(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),k=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(O())}function m(){var e=O(),n=c(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(s,t),o(w)}return void 0===h&&(h=setTimeout(s,t)),g}var b,v,y,g,h,w,k=0,_=!1,S=!1,z=!0;if("function"!=typeof e)throw new TypeError(f);return t=u(t)||0,i(n)&&(_=!!n.leading,S="maxWait"in n,y=S?x(u(n.maxWait)||0,t):y,z="trailing"in n?!!n.trailing:z),m.cancel=l,m.flush=p,m}function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeError(f);return i(o)&&(r="leading"in o?!!o.leading:r,a="trailing"in o?!!o.trailing:a),n(e,t,{leading:r,maxWait:t,trailing:a})}function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("object"==t||"function"==t)}function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(e))}function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||r(e)&&k.call(e)==d}function u(e){if("number"==typeof e)return e;if(a(e))return s;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(l,"");var n=m.test(e);return n||b.test(e)?v(e.slice(2),n?2:8):p.test(e)?s:+e}var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f="Expected a function",s=NaN,d="[object Symbol]",l=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,b=/^0o[0-7]+$/i,v=parseInt,y="object"==("undefined"==typeof t?"undefined":c(t))&&t&&t.Object===Object&&t,g="object"==("undefined"==typeof self?"undefined":c(self))&&self&&self.Object===Object&&self,h=y||g||Function("return this")(),w=Object.prototype,k=w.toString,x=Math.max,j=Math.min,O=function(){return h.Date.now()};e.exports=o}).call(t,function(){return this}())},function(e,t){(function(t){"use strict";function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.apply(o,n)}function r(e){return O=e,h=setTimeout(s,t),_?i(e):g}function u(e){var n=e-w,o=e-O,i=t-n;return S?x(i,y-o):i}function f(e){var n=e-w,o=e-O;return void 0===w||n>=t||n<0||S&&o>=y}function s(){var e=j();return f(e)?d(e):void(h=setTimeout(s,u(e)))}function d(e){return h=void 0,z&&b?i(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),O=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(j())}function m(){var e=j(),n=f(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(s,t),i(w)}return void 0===h&&(h=setTimeout(s,t)),g}var b,v,y,g,h,w,O=0,_=!1,S=!1,z=!0;if("function"!=typeof e)throw new TypeError(c);return t=a(t)||0,o(n)&&(_=!!n.leading,S="maxWait"in n,y=S?k(a(n.maxWait)||0,t):y,z="trailing"in n?!!n.trailing:z),m.cancel=l,m.flush=p,m}function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("object"==t||"function"==t)}function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(e))}function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||i(e)&&w.call(e)==s}function a(e){if("number"==typeof e)return e;if(r(e))return f;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(d,"");var n=p.test(e);return n||m.test(e)?b(e.slice(2),n?2:8):l.test(e)?f:+e}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c="Expected a function",f=NaN,s="[object Symbol]",d=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,p=/^0b[01]+$/i,m=/^0o[0-7]+$/i,b=parseInt,v="object"==("undefined"==typeof t?"undefined":u(t))&&t&&t.Object===Object&&t,y="object"==("undefined"==typeof self?"undefined":u(self))&&self&&self.Object===Object&&self,g=v||y||Function("return this")(),h=Object.prototype,w=h.toString,k=Math.max,x=Math.min,j=function(){return g.Date.now()};e.exports=n}).call(t,function(){return this}())},function(e,t){"use strict";function n(e,t){var n=window.document,r=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,a=new r(o);i=t,a.observe(n.documentElement,{childList:!0,subtree:!0,removedNodes:!0})}function o(e){e&&e.forEach(function(e){var t=Array.prototype.slice.call(e.addedNodes),n=Array.prototype.slice.call(e.removedNodes
1),o=t.concat(n).filter(function(e){return e.hasAttribute&&e.hasAttribute("data-aos")}).length;o&&i()})}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){};t.default=n},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){return navigator.userAgent||navigator.vendor||window.opera||""}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),r=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,a=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,u=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i,c=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
1sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,f=function(){function e(){n(this,e)}return i(e,[{key:"phone",value:function(){var e=o();return!(!r.test(e)&&!a.test(e.substr(0,4)))}},{key:"mobile",value:function(){var e=o();return!(!u.test(e)&&!c.test(e.substr(0,4)))}},{key:"tablet",value:function(){return this.mobile()&&!this.phone()}}]),e}();t.default=new f},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){var o=e.node.getAttribute("data-aos-once");t>e.position?e.node.classList.add("aos-animate"):"undefined"!=typeof o&&("false"===o||!n&&"true"!==o)&&e.node.classList.remove("aos-animate")},o=function(e,t){var o=window.pageYOffset,i=window.innerHeight;e.forEach(function(e,r){n(e,i+o,t)})};t.default=o},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(12),r=o(i),a=function(e,t){return e.forEach(function(e,n){e.node.classList.add("aos-init"),e.position=(0,r.default)(e.node,t.offset)}),e};t.default=a},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(13),r=o(i),a=function(e,t){var n=0,o=0,i=window.innerHeight,a={offset:e.getAttribute("data-aos-offset"),anchor:e.getAttribute("data-aos-anchor"),anchorPlacement:e.getAttribute("data-aos-anchor-placement")};switch(a.offset&&!isNaN(a.offset)&&(o=parseInt(a.offset)),a.anchor&&document.querySelectorAll(a.anchor)&&(e=document.querySelectorAll(a.anchor)[0]),n=(0,r.default)(e).top,a.anchorPlacement){case"top-bottom":break;case"center-bottom":n+=e.offsetHeight/2;break;case"bottom-bottom":n+=e.offsetHeight;break;case"top-center":n+=i/2;break;case"bottom-center":n+=i/2+e.offsetHeight;break;case"center-center":n+=i/2+e.offsetHeight/2;break;case"top-top":n+=i;break;case"bottom-top":n+=e.offsetHeight+i;break;case"center-top":n+=e.offsetHeight/2+i}return a.anchorPlacement||a.offset||isNaN(t)||(o=t),n+o};t.default=a},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}};t.default=n},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){return e=e||document.querySelectorAll("[data-aos]"),Array.prototype.map.call(e,function(e){return{node:e}})};t.default=n}])}); 2/*! 3 * Glide.js v3.6.2
vendor: 97,708 bytes, lines 3-3901
3 4 * (c) 2013-2024 JÄdrzej ChaÅubek (https://github.com/jedrzejchalubek/) 5 * Released under the MIT License. 6 */ 7 8(function (global, factory) { 9 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 10 typeof define === 'function' && define.amd ? define(factory) : 11 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Glide = factory()); 12})(this, (function () { 'use strict'; 13 14 function ownKeys(object, enumerableOnly) { 15 var keys = Object.keys(object); 16 17 if (Object.getOwnPropertySymbols) { 18 var symbols = Object.getOwnPropertySymbols(object); 19 20 if (enumerableOnly) { 21 symbols = symbols.filter(function (sym) { 22 return Object.getOwnPropertyDescriptor(object, sym).enumerable; 23 }); 24 } 25 26 keys.push.apply(keys, symbols); 27 } 28 29 return keys; 30 } 31 32 function _objectSpread2(target) { 33 for (var i = 1; i < arguments.length; i++) { 34 var source = arguments[i] != null ? arguments[i] : {}; 35 36 if (i % 2) { 37 ownKeys(Object(source), true).forEach(function (key) { 38 _defineProperty(target, key, source[key]); 39 }); 40 } else if (Object.getOwnPropertyDescriptors) { 41 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); 42 } else { 43 ownKeys(Object(source)).forEach(function (key) { 44 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); 45 }); 46 } 47 } 48 49 return target; 50 } 51 52 function _typeof(obj) { 53 "@babel/helpers - typeof"; 54 55 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 56 _typeof = function (obj) { 57 return typeof obj; 58 }; 59 } else { 60 _typeof = function (obj) { 61 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 62 }; 63 } 64 65 return _typeof(obj); 66 } 67 68 function _classCallCheck(instance, Constructor) { 69 if (!(instance instanceof Constructor)) { 70 throw new TypeError("Cannot call a class as a function"); 71 } 72 } 73 74 function _defineProperties(target, props) { 75 for (var i = 0; i < props.length; i++) { 76 var descriptor = props[i]; 77 descriptor.enumerable = descriptor.enumerable || false; 78 descriptor.configurable = true; 79 if ("value" in descriptor) descriptor.writable = true; 80 Object.defineProperty(target, descriptor.key, descriptor); 81 } 82 } 83 84 function _createClass(Constructor, protoProps, staticProps) { 85 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 86 if (staticProps) _defineProperties(Constructor, staticProps); 87 return Constructor; 88 } 89 90 function _defineProperty(obj, key, value) { 91 if (key in obj) { 92 Object.defineProperty(obj, key, { 93 value: value, 94 enumerable: true, 95 configurable: true, 96 writable: true 97 }); 98 } else { 99 obj[key] = value; 100 } 101 102 return obj; 103 } 104 105 function _inherits(subClass, superClass) { 106 if (typeof superClass !== "function" && superClass !== null) { 107 throw new TypeError("Super expression must either be null or a function"); 108 } 109 110 subClass.prototype = Object.create(superClass && superClass.prototype, { 111 constructor: { 112 value: subClass, 113 writable: true, 114 configurable: true 115 } 116 }); 117 if (superClass) _setPrototypeOf(subClass, superClass); 118 } 119 120 function _getPrototypeOf(o) { 121 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 122 return o.__proto__ || Object.getPrototypeOf(o); 123 }; 124 return _getPrototypeOf(o); 125 } 126 127 function _setPrototypeOf(o, p) { 128 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 129 o.__proto__ = p; 130 return o; 131 }; 132 133 return _setPrototypeOf(o, p); 134 } 135 136 function _isNativeReflectConstruct() { 137 if (typeof Reflect === "undefined" || !Reflect.construct) return false; 138 if (Reflect.construct.sham) return false; 139 if (typeof Proxy === "function") return true; 140 141 try { 142 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); 143 return true; 144 } catch (e) { 145 return false; 146 } 147 } 148 149 function _assertThisInitialized(self) { 150 if (self === void 0) { 151 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 152 } 153 154 return self; 155 } 156 157 function _possibleConstructorReturn(self, call) { 158 if (call && (typeof call === "object" || typeof call === "function")) { 159 return call; 160 } else if (call !== void 0) { 161 throw new TypeError("Derived constructors may only return object or undefined"); 162 } 163 164 return _assertThisInitialized(self); 165 } 166 167 function _createSuper(Derived) { 168 var hasNativeReflectConstruct = _isNativeReflectConstruct(); 169 170 return function _createSuperInternal() { 171 var Super = _getPrototypeOf(Derived), 172 result; 173 174 if (hasNativeReflectConstruct) { 175 var NewTarget = _getPrototypeOf(this).constructor; 176 177 result = Reflect.construct(Super, arguments, NewTarget); 178 } else { 179 result = Super.apply(this, arguments); 180 } 181 182 return _possibleConstructorReturn(this, result); 183 }; 184 } 185 186 function _superPropBase(object, property) { 187 while (!Object.prototype.hasOwnProperty.call(object, property)) { 188 object = _getPrototypeOf(object); 189 if (object === null) break; 190 } 191 192 return object; 193 } 194 195 function _get() { 196 if (typeof Reflect !== "undefined" && Reflect.get) { 197 _get = Reflect.get; 198 } else { 199 _get = function _get(target, property, receiver) { 200 var base = _superPropBase(target, property); 201 202 if (!base) return; 203 var desc = Object.getOwnPropertyDescriptor(base, property); 204 205 if (desc.get) { 206 return desc.get.call(arguments.length < 3 ? target : receiver); 207 } 208 209 return desc.value; 210 }; 211 } 212 213 return _get.apply(this, arguments); 214 } 215 216 var defaults = { 217 /** 218 * Type of the movement. 219 * 220 * Available types: 221 * `slider` - Rewinds slider to the start/end when it reaches the first or last slide. 222 * `carousel` - Changes slides without starting over when it reaches the first or last slide. 223 * 224 * @type {String} 225 */ 226 type: 'slider', 227 228 /** 229 * Start at specific slide number defined with zero-based index. 230 * 231 * @type {Number} 232 */ 233 startAt: 0, 234 235 /** 236 * A number of slides visible on the single viewport. 237 * 238 * @type {Number} 239 */ 240 perView: 1, 241 242 /** 243 * Focus currently active slide at a specified position in the track. 244 * 245 * Available inputs: 246 * `center` - Current slide will be always focused at the center of a track. 247 * `0,1,2,3...` - Current slide will be focused on the specified zero-based index. 248 * 249 * @type {String|Number} 250 */ 251 focusAt: 0, 252 253 /** 254 * A size of the gap added between slides. 255 * 256 * @type {Number} 257 */ 258 gap: 10, 259 260 /** 261 * Change slides after a specified interval. Use `false` for turning off autoplay. 262 * 263 * @type {Number|Boolean} 264 */ 265 autoplay: false, 266 267 /** 268 * Stop autoplay on mouseover event. 269 * 270 * @type {Boolean} 271 */ 272 hoverpause: true, 273 274 /** 275 * Allow for changing slides with left and right keyboard arrows. 276 * 277 * @type {Boolean} 278 */ 279 keyboard: true, 280 281 /** 282 * Stop running `perView` number of slides from the end. Use this 283 * option if you don't want to have an empty space after 284 * a slider. Works only with `slider` type and a 285 * non-centered `focusAt` setting. 286 * 287 * @type {Boolean} 288 */ 289 bound: false, 290 291 /** 292 * Minimal swipe distance needed to change the slide. Use `false` for turning off a swiping. 293 * 294 * @type {Number|Boolean} 295 */ 296 swipeThreshold: 80, 297 298 /** 299 * Minimal mouse drag distance needed to change the slide. Use `false` for turning off a dragging. 300 * 301 * @type {Number|Boolean} 302 */ 303 dragThreshold: 120, 304 305 /** 306 * A number of slides moved on single swipe. 307 * 308 * Available types: 309 * `` - Moves slider by one slide per swipe 310 * `|` - Moves slider between views per swipe (number of slides defined in `perView` options) 311 * 312 * @type {String} 313 */ 314 perSwipe: '', 315 316 /** 317 * Moving distance ratio of the slides on a swiping and dragging. 318 * 319 * @type {Number} 320 */ 321 touchRatio: 0.5, 322 323 /** 324 * Angle required to activate slides moving on swiping or dragging. 325 * 326 * @type {Number} 327 */ 328 touchAngle: 45, 329 330 /** 331 * Duration of the animation in milliseconds. 332 * 333 * @type {Number} 334 */ 335 animationDuration: 400, 336 337 /** 338 * Allows looping the `slider` type. Slider will rewind to the first/last slide when it's at the start/end. 339 * 340 * @type {Boolean} 341 */ 342 rewind: true, 343 344 /** 345 * Duration of the rewinding animation of the `slider` type in milliseconds. 346 * 347 * @type {Number} 348 */ 349 rewindDuration: 800, 350 351 /** 352 * Easing function for the animation. 353 * 354 * @type {String} 355 */ 356 animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)', 357 358 /** 359 * Wait for the animation to finish until the next user input can be processed 360 * 361 * @type {boolean} 362 */ 363 waitForTransition: true, 364 365 /** 366 * Throttle costly events at most once per every wait milliseconds. 367 * 368 * @type {Number} 369 */ 370 throttle: 10, 371 372 /** 373 * Moving direction mode. 374 * 375 * Available inputs: 376 * - 'ltr' - left to right movement, 377 * - 'rtl' - right to left movement. 378 * 379 * @type {String} 380 */ 381 direction: 'ltr', 382 383 /** 384 * The distance value of the next and previous viewports which 385 * have to peek in the current view. Accepts number and 386 * pixels as a string. Left and right peeking can be 387 * set up separately with a directions object. 388 * 389 * For example: 390 * `100` - Peek 100px on the both sides. 391 * { before: 100, after: 50 }` - Peek 100px on the left side and 50px on the right side. 392 * 393 * @type {Number|String|Object} 394 */ 395 peek: 0, 396 397 /** 398 * Defines how many clones of current viewport will be generated. 399 * 400 * @type {Number} 401 */ 402 cloningRatio: 1, 403 404 /** 405 * Collection of options applied at specified media breakpoints. 406 * For example: display two slides per view under 800px. 407 * `{ 408 * '800px': { 409 * perView: 2 410 * } 411 * }` 412 */ 413 breakpoints: {}, 414 415 /** 416 * Collection of internally used HTML classes. 417 * 418 * @todo Refactor `slider` and `carousel` properties to single `type: { slider: '', carousel: '' }` object 419 * @type {Object} 420 */ 421 classes: { 422 swipeable: 'glide--swipeable', 423 dragging: 'glide--dragging', 424 direction: { 425 ltr: 'glide--ltr', 426 rtl: 'glide--rtl' 427 }, 428 type: { 429 slider: 'glide--slider', 430 carousel: 'glide--carousel' 431 }, 432 slide: { 433 clone: 'glide__slide--clone', 434 active: 'glide__slide--active' 435 }, 436 arrow: { 437 disabled: 'glide__arrow--disabled' 438 }, 439 nav: { 440 active: 'glide__bullet--active' 441 } 442 } 443 }; 444 445 /** 446 * Outputs warning message to the bowser console. 447 * 448 * @param {String} msg 449 * @return {Void} 450 */ 451 function warn(msg) { 452 console.error("[Glide warn]: ".concat(msg)); 453 } 454 455 /** 456 * Converts value entered as number 457 * or string to integer value. 458 * 459 * @param {String} value 460 * @returns {Number} 461 */ 462 function toInt(value) { 463 return parseInt(value); 464 } 465 /** 466 * Converts value entered as number 467 * or string to flat value. 468 * 469 * @param {String} value 470 * @returns {Number} 471 */ 472 473 function toFloat(value) { 474 return parseFloat(value); 475 } 476 /** 477 * Indicates whether the specified value is a string. 478 * 479 * @param {*} value 480 * @return {Boolean} 481 */ 482 483 function isString(value) { 484 return typeof value === 'string'; 485 } 486 /** 487 * Indicates whether the specified value is an object. 488 * 489 * @param {*} value 490 * @return {Boolean} 491 * 492 * @see https://github.com/jashkenas/underscore 493 */ 494 495 function isObject(value) { 496 var type = _typeof(value); 497 498 return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators 499 } 500 /** 501 * Indicates whether the specified value is a function. 502 * 503 * @param {*} value 504 * @return {Boolean} 505 */ 506 507 function isFunction(value) { 508 return typeof value === 'function'; 509 } 510 /** 511 * Indicates whether the specified value is undefined. 512 * 513 * @param {*} value 514 * @return {Boolean} 515 */ 516 517 function isUndefined(value) { 518 return typeof value === 'undefined'; 519 } 520 /** 521 * Indicates whether the specified value is an array. 522 * 523 * @param {*} value 524 * @return {Boolean} 525 */ 526 527 function isArray(value) { 528 return value.constructor === Array; 529 } 530 531 /** 532 * Creates and initializes specified collection of extensions. 533 * Each extension receives access to instance of glide and rest of components. 534 * 535 * @param {Object} glide 536 * @param {Object} extensions 537 * 538 * @returns {Object} 539 */ 540 541 function mount(glide, extensions, events) { 542 var components = {}; 543 544 for (var name in extensions) { 545 if (isFunction(extensions[name])) { 546 components[name] = extensions[name](glide, components, events); 547 } else { 548 warn('Extension must be a function'); 549 } 550 } 551 552 for (var _name in components) { 553 if (isFunction(components[_name].mount)) { 554 components[_name].mount(); 555 } 556 } 557 558 return components; 559 } 560 561 /** 562 * Defines getter and setter property on the specified object. 563 * 564 * @param {Object} obj Object where property has to be defined. 565 * @param {String} prop Name of the defined property. 566 * @param {Object} definition Get and set definitions for the property. 567 * @return {Void} 568 */ 569 function define(obj, prop, definition) { 570 Object.defineProperty(obj, prop, definition); 571 } 572 /** 573 * Sorts aphabetically object keys. 574 * 575 * @param {Object} obj 576 * @return {Object} 577 */ 578 579 function sortKeys(obj) { 580 return Object.keys(obj).sort().reduce(function (r, k) { 581 r[k] = obj[k]; 582 return r[k], r; 583 }, {}); 584 } 585 /** 586 * Merges passed settings object with default options. 587 * 588 * @param {Object} defaults 589 * @param {Object} settings 590 * @return {Object} 591 */ 592 593 function mergeOptions(defaults, settings) { 594 var options = Object.assign({}, defaults, settings); // `Object.assign` do not deeply merge objects, so we 595 // have to do it manually for every nested object 596 // in options. Although it does not look smart, 597 // it's smaller and faster than some fancy 598 // merging deep-merge algorithm script. 599 600 if (settings.hasOwnProperty('classes')) { 601 options.classes = Object.assign({}, defaults.classes, settings.classes); 602 var properties = ['direction', 'type', 'slide', 'arrow', 'nav']; 603 properties.forEach(function (property) { 604 if (settings.classes.hasOwnProperty(property)) { 605 options.classes[property] = _objectSpread2(_objectSpread2({}, defaults.classes[property]), settings.classes[property]); 606 } 607 }); 608 } 609 610 if (settings.hasOwnProperty('breakpoints')) { 611 options.breakpoints = Object.assign({}, defaults.breakpoints, settings.breakpoints); 612 } 613 614 return options; 615 } 616 617 var EventsBus = /*#__PURE__*/function () { 618 /** 619 * Construct a EventBus instance. 620 * 621 * @param {Object} events 622 */ 623 function EventsBus() { 624 var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 625 626 _classCallCheck(this, EventsBus); 627 628 this.events = events; 629 this.hop = events.hasOwnProperty; 630 } 631 /** 632 * Adds listener to the specifed event. 633 * 634 * @param {String|Array} event 635 * @param {Function} handler 636 */ 637 638 639 _createClass(EventsBus, [{ 640 key: "on", 641 value: function on(event, handler) { 642 if (isArray(event)) { 643 for (var i = 0; i < event.length; i++) { 644 this.on(event[i], handler); 645 } 646 647 return; 648 } // Create the event's object if not yet created 649 650 651 if (!this.hop.call(this.events, event)) { 652 this.events[event] = []; 653 } // Add the handler to queue 654 655 656 var index = this.events[event].push(handler) - 1; // Provide handle back for removal of event 657 658 return { 659 remove: function remove() { 660 delete this.events[event][index]; 661 } 662 }; 663 } 664 /** 665 * Runs registered handlers for specified event. 666 * 667 * @param {String|Array} event 668 * @param {Object=} context 669 */ 670 671 }, { 672 key: "emit", 673 value: function emit(event, context) { 674 if (isArray(event)) { 675 for (var i = 0; i < event.length; i++) { 676 this.emit(event[i], context); 677 } 678 679 return; 680 } // If the event doesn't exist, or there's no handlers in queue, just leave 681 682 683 if (!this.hop.call(this.events, event)) { 684 return; 685 } // Cycle through events queue, fire! 686 687 688 this.events[event].forEach(function (item) { 689 item(context || {}); 690 }); 691 } 692 }]); 693 694 return EventsBus; 695 }(); 696 697 var Glide$1 = /*#__PURE__*/function () { 698 /** 699 * Construct glide. 700 * 701 * @param {String} selector 702 * @param {Object} options 703 */ 704 function Glide(selector) { 705 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 706 707 _classCallCheck(this, Glide); 708 709 this._c = {}; 710 this._t = []; 711 this._e = new EventsBus(); 712 this.disabled = false; 713 this.selector = selector; 714 this.settings = mergeOptions(defaults, options); 715 this.index = this.settings.startAt; 716 } 717 /** 718 * Initializes glide. 719 * 720 * @param {Object} extensions Collection of extensions to initialize. 721 * @return {Glide} 722 */ 723 724 725 _createClass(Glide, [{ 726 key: "mount", 727 value: function mount$1() { 728 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 729 730 this._e.emit('mount.before'); 731 732 if (isObject(extensions)) { 733 this._c = mount(this, extensions, this._e); 734 } else { 735 warn('You need to provide a object on `mount()`'); 736 } 737 738 this._e.emit('mount.after'); 739 740 return this; 741 } 742 /** 743 * Collects an instance `translate` transformers. 744 * 745 * @param {Array} transformers Collection of transformers. 746 * @return {Void} 747 */ 748 749 }, { 750 key: "mutate", 751 value: function mutate() { 752 var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 753 754 if (isArray(transformers)) { 755 this._t = transformers; 756 } else { 757 warn('You need to provide a array on `mutate()`'); 758 } 759 760 return this; 761 } 762 /** 763 * Updates glide with specified settings. 764 * 765 * @param {Object} settings 766 * @return {Glide} 767 */ 768 769 }, { 770 key: "update", 771 value: function update() { 772 var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 773 this.settings = mergeOptions(this.settings, settings); 774 775 if (settings.hasOwnProperty('startAt')) { 776 this.index = settings.startAt; 777 } 778 779 this._e.emit('update'); 780 781 return this; 782 } 783 /** 784 * Change slide with specified pattern. A pattern must be in the special format: 785 * `>` - Move one forward 786 * `<` - Move one backward 787 * `={i}` - Go to {i} zero-based slide (eq. '=1', will go to second slide) 788 * `>>` - Rewinds to end (last slide) 789 * `<<` - Rewinds to start (first slide) 790 * `|>` - Move one viewport forward 791 * `|<` - Move one viewport backward 792 * 793 * @param {String} pattern 794 * @return {Glide} 795 */ 796 797 }, { 798 key: "go", 799 value: function go(pattern) { 800 this._c.Run.make(pattern); 801 802 return this; 803 } 804 /** 805 * Move track by specified distance. 806 * 807 * @param {String} distance 808 * @return {Glide} 809 */ 810 811 }, { 812 key: "move", 813 value: function move(distance) { 814 this._c.Transition.disable(); 815 816 this._c.Move.make(distance); 817 818 return this; 819 } 820 /** 821 * Destroy instance and revert all changes done by this._c. 822 * 823 * @return {Glide} 824 */ 825 826 }, { 827 key: "destroy", 828 value: function destroy() { 829 this._e.emit('destroy'); 830 831 return this; 832 } 833 /** 834 * Start instance autoplaying. 835 * 836 * @param {Boolean|Number} interval Run autoplaying with passed interval regardless of `autoplay` settings 837 * @return {Glide} 838 */ 839 840 }, { 841 key: "play", 842 value: function play() { 843 var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; 844 845 if (interval) { 846 this.settings.autoplay = interval; 847 } 848 849 this._e.emit('play'); 850 851 return this; 852 } 853 /** 854 * Stop instance autoplaying. 855 * 856 * @return {Glide} 857 */ 858 859 }, { 860 key: "pause", 861 value: function pause() { 862 this._e.emit('pause'); 863 864 return this; 865 } 866 /** 867 * Sets glide into a idle status. 868 * 869 * @return {Glide} 870 */ 871 872 }, { 873 key: "disable", 874 value: function disable() { 875 this.disabled = true; 876 return this; 877 } 878 /** 879 * Sets glide into a active status. 880 * 881 * @return {Glide} 882 */ 883 884 }, { 885 key: "enable", 886 value: function enable() { 887 this.disabled = false; 888 return this; 889 } 890 /** 891 * Adds cuutom event listener with handler. 892 * 893 * @param {String|Array} event 894 * @param {Function} handler 895 * @return {Glide} 896 */ 897 898 }, { 899 key: "on", 900 value: function on(event, handler) { 901 this._e.on(event, handler); 902 903 return this; 904 } 905 /** 906 * Checks if glide is a precised type. 907 * 908 * @param {String} name 909 * @return {Boolean} 910 */ 911 912 }, { 913 key: "isType", 914 value: function isType(name) { 915 return this.settings.type === name; 916 } 917 /** 918 * Gets value of the core options. 919 * 920 * @return {Object} 921 */ 922 923 }, { 924 key: "settings", 925 get: function get() { 926 return this._o; 927 } 928 /** 929 * Sets value of the core options. 930 * 931 * @param {Object} o 932 * @return {Void} 933 */ 934 , 935 set: function set(o) { 936 if (isObject(o)) { 937 this._o = o; 938 } else { 939 warn('Options must be an `object` instance.'); 940 } 941 } 942 /** 943 * Gets current index of the slider. 944 * 945 * @return {Object} 946 */ 947 948 }, { 949 key: "index", 950 get: function get() { 951 return this._i; 952 } 953 /** 954 * Sets current index a slider. 955 * 956 * @return {Object} 957 */ 958 , 959 set: function set(i) { 960 this._i = toInt(i); 961 } 962 /** 963 * Gets type name of the slider. 964 * 965 * @return {String} 966 */ 967 968 }, { 969 key: "type", 970 get: function get() { 971 return this.settings.type; 972 } 973 /** 974 * Gets value of the idle status. 975 * 976 * @return {Boolean} 977 */ 978 979 }, { 980 key: "disabled", 981 get: function get() { 982 return this._d; 983 } 984 /** 985 * Sets value of the idle status. 986 * 987 * @return {Boolean} 988 */ 989 , 990 set: function set(status) { 991 this._d = !!status; 992 } 993 }]); 994 995 return Glide; 996 }(); 997 998 function Run (Glide, Components, Events) { 999 var Run = { 1000 /** 1001 * Initializes autorunning of the glide. 1002 * 1003 * @return {Void} 1004 */ 1005 mount: function mount() { 1006 this._o = false; 1007 }, 1008 1009 /** 1010 * Makes glides running based on the passed moving schema. 1011 * 1012 * @param {String} move 1013 */ 1014 make: function make(move) { 1015 var _this = this; 1016 1017 if (!Glide.disabled) { 1018 !Glide.settings.waitForTransition || Glide.disable(); 1019 this.move = move; 1020 Events.emit('run.before', this.move); 1021 this.calculate(); 1022 Events.emit('run', this.move); 1023 Components.Transition.after(function () { 1024 if (_this.isStart()) { 1025 Events.emit('run.start', _this.move); 1026 } 1027 1028 if (_this.isEnd()) { 1029 Events.emit('run.end', _this.move); 1030 } 1031 1032 if (_this.isOffset()) { 1033 _this._o = false; 1034 Events.emit('run.offset', _this.move); 1035 } 1036 1037 Events.emit('run.after', _this.move); 1038 Glide.enable(); 1039 }); 1040 } 1041 }, 1042 1043 /** 1044 * Calculates current index based on defined move. 1045 * 1046 * @return {Number|Undefined} 1047 */ 1048 calculate: function calculate() { 1049 var move = this.move, 1050 length = this.length; 1051 var steps = move.steps, 1052 direction = move.direction; // By default assume that size of view is equal to one slide 1053 1054 var viewSize = 1; // While direction is `=` we want jump to 1055 // a specified index described in steps. 1056 1057 if (direction === '=') { 1058 // Check if bound is true, 1059 // as we want to avoid whitespaces. 1060 if (Glide.settings.bound && toInt(steps) > length) { 1061 Glide.index = length; 1062 return; 1063 } 1064 1065 Glide.index = steps; 1066 return; 1067 } // When pattern is equal to `>>` we want 1068 // fast forward to the last slide. 1069 1070 1071 if (direction === '>' && steps === '>') { 1072 Glide.index = length; 1073 return; 1074 } // When pattern is equal to `<<` we want 1075 // fast forward to the first slide. 1076 1077 1078 if (direction === '<' && steps === '<') { 1079 Glide.index = 0; 1080 return; 1081 } // pagination movement 1082 1083 1084 if (direction === '|') { 1085 viewSize = Glide.settings.perView || 1; 1086 } // we are moving forward 1087 1088 1089 if (direction === '>' || direction === '|' && steps === '>') { 1090 var index = calculateForwardIndex(viewSize); 1091 1092 if (index > length) { 1093 this._o = true; 1094 } 1095 1096 Glide.index = normalizeForwardIndex(index, viewSize); 1097 return; 1098 } // we are moving backward 1099 1100 1101 if (direction === '<' || direction === '|' && steps === '<') { 1102 var _index = calculateBackwardIndex(viewSize); 1103 1104 if (_index < 0) { 1105 this._o = true; 1106 } 1107 1108 Glide.index = normalizeBackwardIndex(_index, viewSize); 1109 return; 1110 } 1111 1112 warn("Invalid direction pattern [".concat(direction).concat(steps, "] has been used")); 1113 }, 1114 1115 /** 1116 * Checks if we are on the first slide. 1117 * 1118 * @return {Boolean} 1119 */ 1120 isStart: function isStart() { 1121 return Glide.index <= 0; 1122 }, 1123 1124 /** 1125 * Checks if we are on the last slide. 1126 * 1127 * @return {Boolean} 1128 */ 1129 isEnd: function isEnd() { 1130 return Glide.index >= this.length; 1131 }, 1132 1133 /** 1134 * Checks if we are making a offset run. 1135 * 1136 * @param {String} direction 1137 * @return {Boolean} 1138 */ 1139 isOffset: function isOffset() { 1140 var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; 1141 1142 if (!direction) { 1143 return this._o; 1144 } 1145 1146 if (!this._o) { 1147 return false; 1148 } // did we view to the right? 1149 1150 1151 if (direction === '|>') { 1152 return this.move.direction === '|' && this.move.steps === '>'; 1153 } // did we view to the left? 1154 1155 1156 if (direction === '|<') { 1157 return this.move.direction === '|' && this.move.steps === '<'; 1158 } 1159 1160 return this.move.direction === direction; 1161 }, 1162 1163 /** 1164 * Checks if bound mode is active 1165 * 1166 * @return {Boolean} 1167 */ 1168 isBound: function isBound() { 1169 return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound; 1170 } 1171 }; 1172 /** 1173 * Returns index value to move forward/to the right 1174 * 1175 * @param viewSize 1176 * @returns {Number} 1177 */ 1178 1179 function calculateForwardIndex(viewSize) { 1180 var index = Glide.index; 1181 1182 if (Glide.isType('carousel')) { 1183 return index + viewSize; 1184 } 1185 1186 return index + (viewSize - index % viewSize); 1187 } 1188 /** 1189 * Normalizes the given forward index based on glide settings, preventing it to exceed certain boundaries 1190 * 1191 * @param index 1192 * @param length 1193 * @param viewSize 1194 * @returns {Number} 1195 */ 1196 1197 1198 function normalizeForwardIndex(index, viewSize) { 1199 var length = Run.length; 1200 1201 if (index <= length) { 1202 return index; 1203 } 1204 1205 if (Glide.isType('carousel')) { 1206 return index - (length + 1); 1207 } 1208 1209 if (Glide.settings.rewind) { 1210 // bound does funny things with the length, therefor we have to be certain 1211 // that we are on the last possible index value given by bound 1212 if (Run.isBound() && !Run.isEnd()) { 1213 return length; 1214 } 1215 1216 return 0; 1217 } 1218 1219 if (Run.isBound()) { 1220 return length; 1221 } 1222 1223 return Math.floor(length / viewSize) * viewSize; 1224 } 1225 /** 1226 * Calculates index value to move backward/to the left 1227 * 1228 * @param viewSize 1229 * @returns {Number} 1230 */ 1231 1232 1233 function calculateBackwardIndex(viewSize) { 1234 var index = Glide.index; 1235 1236 if (Glide.isType('carousel')) { 1237 return index - viewSize; 1238 } // ensure our back navigation results in the same index as a forward navigation 1239 // to experience a homogeneous paging 1240 1241 1242 var view = Math.ceil(index / viewSize); 1243 return (view - 1) * viewSize; 1244 } 1245 /** 1246 * Normalizes the given backward index based on glide settings, preventing it to exceed certain boundaries 1247 * 1248 * @param index 1249 * @param length 1250 * @param viewSize 1251 * @returns {*} 1252 */ 1253 1254 1255 function normalizeBackwardIndex(index, viewSize) { 1256 var length = Run.length; 1257 1258 if (index >= 0) { 1259 return index; 1260 } 1261 1262 if (Glide.isType('carousel')) { 1263 return index + (length + 1); 1264 } 1265 1266 if (Glide.settings.rewind) { 1267 // bound does funny things with the length, therefor we have to be certain 1268 // that we are on first possible index value before we to rewind to the length given by bound 1269 if (Run.isBound() && Run.isStart()) { 1270 return length; 1271 } 1272 1273 return Math.floor(length / viewSize) * viewSize; 1274 } 1275 1276 return 0; 1277 } 1278 1279 define(Run, 'move', { 1280 /** 1281 * Gets value of the move schema. 1282 * 1283 * @returns {Object} 1284 */ 1285 get: function get() { 1286 return this._m; 1287 }, 1288 1289 /** 1290 * Sets value of the move schema. 1291 * 1292 * @returns {Object} 1293 */ 1294 set: function set(value) { 1295 var step = value.substr(1); 1296 this._m = { 1297 direction: value.substr(0, 1), 1298 steps: step ? toInt(step) ? toInt(step) : step : 0 1299 }; 1300 } 1301 }); 1302 define(Run, 'length', { 1303 /** 1304 * Gets value of the running distance based 1305 * on zero-indexing number of slides. 1306 * 1307 * @return {Number} 1308 */ 1309 get: function get() { 1310 var settings = Glide.settings; 1311 var length = Components.Html.slides.length; // If the `bound` option is active, a maximum running distance should be 1312 // reduced by `perView` and `focusAt` settings. Running distance 1313 // should end before creating an empty space after instance. 1314 1315 if (this.isBound()) { 1316 return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt); 1317 } 1318 1319 return length - 1; 1320 } 1321 }); 1322 define(Run, 'offset', { 1323 /** 1324 * Gets status of the offsetting flag. 1325 * 1326 * @return {Boolean} 1327 */ 1328 get: function get() { 1329 return this._o; 1330 } 1331 }); 1332 return Run; 1333 } 1334 1335 /** 1336 * Returns a current time. 1337 * 1338 * @return {Number} 1339 */ 1340 function now() { 1341 return new Date().getTime(); 1342 } 1343 1344 /** 1345 * Returns a function, that, when invoked, will only be triggered 1346 * at most once during a given window of time. 1347 * 1348 * @param {Function} func 1349 * @param {Number} wait 1350 * @param {Object=} options 1351 * @return {Function} 1352 * 1353 * @see https://github.com/jashkenas/underscore 1354 */ 1355 1356 function throttle(func, wait) { 1357 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 1358 var timeout, context, args, result; 1359 var previous = 0; 1360 1361 var later = function later() { 1362 previous = options.leading === false ? 0 : now(); 1363 timeout = null; 1364 result = func.apply(context, args); 1365 if (!timeout) context = args = null; 1366 }; 1367 1368 var throttled = function throttled() { 1369 var at = now(); 1370 if (!previous && options.leading === false) previous = at; 1371 var remaining = wait - (at - previous); 1372 context = this; 1373 args = arguments; 1374 1375 if (remaining <= 0 || remaining > wait) { 1376 if (timeout) { 1377 clearTimeout(timeout); 1378 timeout = null; 1379 } 1380 1381 previous = at; 1382 result = func.apply(context, args); 1383 if (!timeout) context = args = null; 1384 } else if (!timeout && options.trailing !== false) { 1385 timeout = setTimeout(later, remaining); 1386 } 1387 1388 return result; 1389 }; 1390 1391 throttled.cancel = function () { 1392 clearTimeout(timeout); 1393 previous = 0; 1394 timeout = context = args = null; 1395 }; 1396 1397 return throttled; 1398 } 1399 1400 var MARGIN_TYPE = { 1401 ltr: ['marginLeft', 'marginRight'], 1402 rtl: ['marginRight', 'marginLeft'] 1403 }; 1404 function Gaps (Glide, Components, Events) { 1405 var Gaps = { 1406 /** 1407 * Applies gaps between slides. First and last 1408 * slides do not receive it's edge margins. 1409 * 1410 * @param {HTMLCollection} slides 1411 * @return {Void} 1412 */ 1413 apply: function apply(slides) { 1414 for (var i = 0, len = slides.length; i < len; i++) { 1415 var style = slides[i].style; 1416 var direction = Components.Direction.value; 1417 1418 if (i !== 0) { 1419 style[MARGIN_TYPE[direction][0]] = "".concat(this.value / 2, "px"); 1420 } else { 1421 style[MARGIN_TYPE[direction][0]] = ''; 1422 } 1423 1424 if (i !== slides.length - 1) { 1425 style[MARGIN_TYPE[direction][1]] = "".concat(this.value / 2, "px"); 1426 } else { 1427 style[MARGIN_TYPE[direction][1]] = ''; 1428 } 1429 } 1430 }, 1431 1432 /** 1433 * Removes gaps from the slides. 1434 * 1435 * @param {HTMLCollection} slides 1436 * @returns {Void} 1437 */ 1438 remove: function remove(slides) { 1439 for (var i = 0, len = slides.length; i < len; i++) { 1440 var style = slides[i].style; 1441 style.marginLeft = ''; 1442 style.marginRight = ''; 1443 } 1444 } 1445 }; 1446 define(Gaps, 'value', { 1447 /** 1448 * Gets value of the gap. 1449 * 1450 * @returns {Number} 1451 */ 1452 get: function get() { 1453 return toInt(Glide.settings.gap); 1454 } 1455 }); 1456 define(Gaps, 'grow', { 1457 /** 1458 * Gets additional dimensions value caused by gaps. 1459 * Used to increase width of the slides wrapper. 1460 * 1461 * @returns {Number} 1462 */ 1463 get: function get() { 1464 return Gaps.value * Components.Sizes.length; 1465 } 1466 }); 1467 define(Gaps, 'reductor', { 1468 /** 1469 * Gets reduction value caused by gaps. 1470 * Used to subtract width of the slides. 1471 * 1472 * @returns {Number} 1473 */ 1474 get: function get() { 1475 var perView = Glide.settings.perView; 1476 return Gaps.value * (perView - 1) / perView; 1477 } 1478 }); 1479 /** 1480 * Apply calculated gaps: 1481 * - after building, so slides (including clones) will receive proper margins 1482 * - on updating via API, to recalculate gaps with new options 1483 */ 1484 1485 Events.on(['build.after', 'update'], throttle(function () { 1486 Gaps.apply(Components.Html.wrapper.children); 1487 }, 30)); 1488 /** 1489 * Remove gaps: 1490 * - on destroying to bring markup to its inital state 1491 */ 1492 1493 Events.on('destroy', function () { 1494 Gaps.remove(Components.Html.wrapper.children); 1495 }); 1496 return Gaps; 1497 } 1498 1499 /** 1500 * Finds siblings nodes of the passed node. 1501 * 1502 * @param {Element} node 1503 * @return {Array} 1504 */ 1505 function siblings(node) { 1506 if (node && node.parentNode) { 1507 var n = node.parentNode.firstChild; 1508 var matched = []; 1509 1510 for (; n; n = n.nextSibling) { 1511 if (n.nodeType === 1 && n !== node) { 1512 matched.push(n); 1513 } 1514 } 1515 1516 return matched; 1517 } 1518 1519 return []; 1520 } 1521 /** 1522 * Coerces a NodeList to an Array. 1523 * 1524 * @param {NodeList} nodeList 1525 * @return {Array} 1526 */ 1527 1528 function toArray(nodeList) { 1529 return Array.prototype.slice.call(nodeList); 1530 } 1531 1532 var TRACK_SELECTOR = '[data-glide-el="track"]'; 1533 function Html (Glide, Components, Events) { 1534 var Html = { 1535 /** 1536 * Setup slider HTML nodes. 1537 * 1538 * @param {Glide} glide 1539 */ 1540 mount: function mount() { 1541 this.root = Glide.selector; 1542 this.track = this.root.querySelector(TRACK_SELECTOR); 1543 this.collectSlides(); 1544 }, 1545 1546 /** 1547 * Collect slides 1548 */ 1549 collectSlides: function collectSlides() { 1550 this.slides = toArray(this.wrapper.children).filter(function (slide) { 1551 return !slide.classList.contains(Glide.settings.classes.slide.clone); 1552 }); 1553 } 1554 }; 1555 define(Html, 'root', { 1556 /** 1557 * Gets node of the glide main element. 1558 * 1559 * @return {Object} 1560 */ 1561 get: function get() { 1562 return Html._r; 1563 }, 1564 1565 /** 1566 * Sets node of the glide main element. 1567 * 1568 * @return {Object} 1569 */ 1570 set: function set(r) { 1571 if (isString(r)) { 1572 r = document.querySelector(r); 1573 } 1574 1575 if (r !== null) { 1576 Html._r = r; 1577 } else { 1578 warn('Root element must be a existing Html node'); 1579 } 1580 } 1581 }); 1582 define(Html, 'track', { 1583 /** 1584 * Gets node of the glide track with slides. 1585 * 1586 * @return {Object} 1587 */ 1588 get: function get() { 1589 return Html._t; 1590 }, 1591 1592 /** 1593 * Sets node of the glide track with slides. 1594 * 1595 * @return {Object} 1596 */ 1597 set: function set(t) { 1598 Html._t = t; 1599 } 1600 }); 1601 define(Html, 'wrapper', { 1602 /** 1603 * Gets node of the slides wrapper. 1604 * 1605 * @return {Object} 1606 */ 1607 get: function get() { 1608 return Html.track.children[0]; 1609 } 1610 }); 1611 /** 1612 * Add/remove/reorder dynamic slides 1613 */ 1614 1615 Events.on('update', function () { 1616 Html.collectSlides(); 1617 }); 1618 return Html; 1619 } 1620 1621 function Peek (Glide, Components, Events) { 1622 var Peek = { 1623 /** 1624 * Setups how much to peek based on settings. 1625 * 1626 * @return {Void} 1627 */ 1628 mount: function mount() { 1629 this.value = Glide.settings.peek; 1630 } 1631 }; 1632 define(Peek, 'value', { 1633 /** 1634 * Gets value of the peek. 1635 * 1636 * @returns {Number|Object} 1637 */ 1638 get: function get() { 1639 return Peek._v; 1640 }, 1641 1642 /** 1643 * Sets value of the peek. 1644 * 1645 * @param {Number|Object} value 1646 * @return {Void} 1647 */ 1648 set: function set(value) { 1649 if (isObject(value)) { 1650 value.before = toInt(value.before); 1651 value.after = toInt(value.after); 1652 } else { 1653 value = toInt(value); 1654 } 1655 1656 Peek._v = value; 1657 } 1658 }); 1659 define(Peek, 'reductor', { 1660 /** 1661 * Gets reduction value caused by peek. 1662 * 1663 * @returns {Number} 1664 */ 1665 get: function get() { 1666 var value = Peek.value; 1667 var perView = Glide.settings.perView; 1668 1669 if (isObject(value)) { 1670 return value.before / perView + value.after / perView; 1671 } 1672 1673 return value * 2 / perView; 1674 } 1675 }); 1676 /** 1677 * Recalculate peeking sizes on: 1678 * - when resizing window to update to proper percents 1679 */ 1680 1681 Events.on(['resize', 'update'], function () { 1682 Peek.mount(); 1683 }); 1684 return Peek; 1685 } 1686 1687 function Move (Glide, Components, Events) { 1688 var Move = { 1689 /** 1690 * Constructs move component. 1691 * 1692 * @returns {Void} 1693 */ 1694 mount: function mount() { 1695 this._o = 0; 1696 }, 1697 1698 /** 1699 * Calculates a movement value based on passed offset and currently active index. 1700 * 1701 * @param {Number} offset 1702 * @return {Void} 1703 */ 1704 make: function make() { 1705 var _this = this; 1706 1707 var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1708 this.offset = offset; 1709 Events.emit('move', { 1710 movement: this.value 1711 }); 1712 Components.Transition.after(function () { 1713 Events.emit('move.after', { 1714 movement: _this.value 1715 }); 1716 }); 1717 } 1718 }; 1719 define(Move, 'offset', { 1720 /** 1721 * Gets an offset value used to modify current translate. 1722 * 1723 * @return {Object} 1724 */ 1725 get: function get() { 1726 return Move._o; 1727 }, 1728 1729 /** 1730 * Sets an offset value used to modify current translate. 1731 * 1732 * @return {Object} 1733 */ 1734 set: function set(value) { 1735 Move._o = !isUndefined(value) ? toInt(value) : 0; 1736 } 1737 }); 1738 define(Move, 'translate', { 1739 /** 1740 * Gets a raw movement value. 1741 * 1742 * @return {Number} 1743 */ 1744 get: function get() { 1745 return Components.Sizes.slideWidth * Glide.index; 1746 } 1747 }); 1748 define(Move, 'value', { 1749 /** 1750 * Gets an actual movement value corrected by offset. 1751 * 1752 * @return {Number} 1753 */ 1754 get: function get() { 1755 var offset = this.offset; 1756 var translate = this.translate; 1757 1758 if (Components.Direction.is('rtl')) { 1759 return translate + offset; 1760 } 1761 1762 return translate - offset; 1763 } 1764 }); 1765 /** 1766 * Make movement to proper slide on: 1767 * - before build, so glide will start at `startAt` index 1768 * - on each standard run to move to newly calculated index 1769 */ 1770 1771 Events.on(['build.before', 'run'], function () { 1772 Move.make(); 1773 }); 1774 return Move; 1775 } 1776 1777 function Sizes (Glide, Components, Events) { 1778 var Sizes = { 1779 /** 1780 * Setups dimensions of slides. 1781 * 1782 * @return {Void} 1783 */ 1784 setupSlides: function setupSlides() { 1785 var width = "".concat(this.slideWidth, "px"); 1786 var slides = Components.Html.slides; 1787 1788 for (var i = 0; i < slides.length; i++) { 1789 slides[i].style.width = width; 1790 } 1791 }, 1792 1793 /** 1794 * Setups dimensions of slides wrapper. 1795 * 1796 * @return {Void} 1797 */ 1798 setupWrapper: function setupWrapper() { 1799 Components.Html.wrapper.style.width = "".concat(this.wrapperSize, "px"); 1800 }, 1801 1802 /** 1803 * Removes applied styles from HTML elements. 1804 * 1805 * @returns {Void} 1806 */ 1807 remove: function remove() { 1808 var slides = Components.Html.slides; 1809 1810 for (var i = 0; i < slides.length; i++) { 1811 slides[i].style.width = ''; 1812 } 1813 1814 Components.Html.wrapper.style.width = ''; 1815 } 1816 }; 1817 define(Sizes, 'length', { 1818 /** 1819 * Gets count number of the slides. 1820 * 1821 * @return {Number} 1822 */ 1823 get: function get() { 1824 return Components.Html.slides.length; 1825 } 1826 }); 1827 define(Sizes, 'width', { 1828 /** 1829 * Gets width value of the slider (visible area). 1830 * 1831 * @return {Number} 1832 */ 1833 get: function get() { 1834 return Components.Html.track.offsetWidth; 1835 } 1836 }); 1837 define(Sizes, 'wrapperSize', { 1838 /** 1839 * Gets size of the slides wrapper. 1840 * 1841 * @return {Number} 1842 */ 1843 get: function get() { 1844 return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow; 1845 } 1846 }); 1847 define(Sizes, 'slideWidth', { 1848 /** 1849 * Gets width value of a single slide. 1850 * 1851 * @return {Number} 1852 */ 1853 get: function get() { 1854 return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor; 1855 } 1856 }); 1857 /** 1858 * Apply calculated glide's dimensions: 1859 * - before building, so other dimensions (e.g. translate) will be calculated propertly 1860 * - when resizing window to recalculate sildes dimensions 1861 * - on updating via API, to calculate dimensions based on new options 1862 */ 1863 1864 Events.on(['build.before', 'resize', 'update'], function () { 1865 Sizes.setupSlides(); 1866 Sizes.setupWrapper(); 1867 }); 1868 /** 1869 * Remove calculated glide's dimensions: 1870 * - on destoting to bring markup to its inital state 1871 */ 1872 1873 Events.on('destroy', function () { 1874 Sizes.remove(); 1875 }); 1876 return Sizes; 1877 } 1878 1879 function Build (Glide, Components, Events) { 1880 var Build = { 1881 /** 1882 * Init glide building. Adds classes, sets 1883 * dimensions and setups initial state. 1884 * 1885 * @return {Void} 1886 */ 1887 mount: function mount() { 1888 Events.emit('build.before'); 1889 this.typeClass(); 1890 this.activeClass(); 1891 Events.emit('build.after'); 1892 }, 1893 1894 /** 1895 * Adds `type` class to the glide element. 1896 * 1897 * @return {Void} 1898 */ 1899 typeClass: function typeClass() { 1900 Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]); 1901 }, 1902 1903 /** 1904 * Sets active class to current slide. 1905 * 1906 * @return {Void} 1907 */ 1908 activeClass: function activeClass() { 1909 var classes = Glide.settings.classes; 1910 var slide = Components.Html.slides[Glide.index]; 1911 1912 if (slide) { 1913 slide.classList.add(classes.slide.active); 1914 siblings(slide).forEach(function (sibling) { 1915 sibling.classList.remove(classes.slide.active); 1916 }); 1917 } 1918 }, 1919 1920 /** 1921 * Removes HTML classes applied at building. 1922 * 1923 * @return {Void} 1924 */ 1925 removeClasses: function removeClasses() { 1926 var _Glide$settings$class = Glide.settings.classes, 1927 type = _Glide$settings$class.type, 1928 slide = _Glide$settings$class.slide; 1929 Components.Html.root.classList.remove(type[Glide.settings.type]); 1930 Components.Html.slides.forEach(function (sibling) { 1931 sibling.classList.remove(slide.active); 1932 }); 1933 } 1934 }; 1935 /** 1936 * Clear building classes: 1937 * - on destroying to bring HTML to its initial state 1938 * - on updating to remove classes before remounting component 1939 */ 1940 1941 Events.on(['destroy', 'update'], function () { 1942 Build.removeClasses(); 1943 }); 1944 /** 1945 * Remount component: 1946 * - on resizing of the window to calculate new dimensions 1947 * - on updating settings via API 1948 */ 1949 1950 Events.on(['resize', 'update'], function () { 1951 Build.mount(); 1952 }); 1953 /** 1954 * Swap active class of current slide: 1955 * - after each move to the new index 1956 */ 1957 1958 Events.on('move.after', function () { 1959 Build.activeClass(); 1960 }); 1961 return Build; 1962 } 1963 1964 function Clones (Glide, Components, Events) { 1965 var Clones = { 1966 /** 1967 * Create pattern map and collect slides to be cloned. 1968 */ 1969 mount: function mount() { 1970 this.items = []; 1971 1972 if (Glide.isType('carousel')) { 1973 this.items = this.collect(); 1974 } 1975 }, 1976 1977 /** 1978 * Collect clones with pattern. 1979 * 1980 * @return {[]} 1981 */ 1982 collect: function collect() { 1983 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 1984 var slides = Components.Html.slides; 1985 var _Glide$settings = Glide.settings, 1986 perView = _Glide$settings.perView, 1987 classes = _Glide$settings.classes, 1988 cloningRatio = _Glide$settings.cloningRatio; 1989 1990 if (slides.length > 0) { 1991 var peekIncrementer = +!!Glide.settings.peek; 1992 var cloneCount = perView + peekIncrementer + Math.round(perView / 2); 1993 var append = slides.slice(0, cloneCount).reverse(); 1994 var prepend = slides.slice(cloneCount * -1); 1995 1996 for (var r = 0; r < Math.max(cloningRatio, Math.floor(perView / slides.length)); r++) { 1997 for (var i = 0; i < append.length; i++) { 1998 var clone = append[i].cloneNode(true); 1999 clone.classList.add(classes.slide.clone); 2000 items.push(clone); 2001 } 2002 2003 for (var _i = 0; _i < prepend.length; _i++) { 2004 var _clone = prepend[_i].cloneNode(true); 2005 2006 _clone.classList.add(classes.slide.clone); 2007 2008 items.unshift(_clone); 2009 } 2010 } 2011 } 2012 2013 return items; 2014 }, 2015 2016 /** 2017 * Append cloned slides with generated pattern. 2018 * 2019 * @return {Void} 2020 */ 2021 append: function append() { 2022 var items = this.items; 2023 var _Components$Html = Components.Html, 2024 wrapper = _Components$Html.wrapper, 2025 slides = _Components$Html.slides; 2026 var half = Math.floor(items.length / 2); 2027 var prepend = items.slice(0, half).reverse(); 2028 var append = items.slice(half * -1).reverse(); 2029 var width = "".concat(Components.Sizes.slideWidth, "px"); 2030 2031 for (var i = 0; i < append.length; i++) { 2032 wrapper.appendChild(append[i]); 2033 } 2034 2035 for (var _i2 = 0; _i2 < prepend.length; _i2++) { 2036 wrapper.insertBefore(prepend[_i2], slides[0]); 2037 } 2038 2039 for (var _i3 = 0; _i3 < items.length; _i3++) { 2040 items[_i3].style.width = width; 2041 } 2042 }, 2043 2044 /** 2045 * Remove all cloned slides. 2046 * 2047 * @return {Void} 2048 */ 2049 remove: function remove() { 2050 var items = this.items; 2051 2052 for (var i = 0; i < items.length; i++) { 2053 Components.Html.wrapper.removeChild(items[i]); 2054 } 2055 } 2056 }; 2057 define(Clones, 'grow', { 2058 /** 2059 * Gets additional dimensions value caused by clones. 2060 * 2061 * @return {Number} 2062 */ 2063 get: function get() { 2064 return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length; 2065 } 2066 }); 2067 /** 2068 * Append additional slide's clones: 2069 * - while glide's type is `carousel` 2070 */ 2071 2072 Events.on('update', function () { 2073 Clones.remove(); 2074 Clones.mount(); 2075 Clones.append(); 2076 }); 2077 /** 2078 * Append additional slide's clones: 2079 * - while glide's type is `carousel` 2080 */ 2081 2082 Events.on('build.before', function () { 2083 if (Glide.isType('carousel')) { 2084 Clones.append(); 2085 } 2086 }); 2087 /** 2088 * Remove clones HTMLElements: 2089 * - on destroying, to bring HTML to its initial state 2090 */ 2091 2092 Events.on('destroy', function () { 2093 Clones.remove(); 2094 }); 2095 return Clones; 2096 } 2097 2098 var EventsBinder = /*#__PURE__*/function () { 2099 /** 2100 * Construct a EventsBinder instance. 2101 */ 2102 function EventsBinder() { 2103 var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2104 2105 _classCallCheck(this, EventsBinder); 2106 2107 this.listeners = listeners; 2108 } 2109 /** 2110 * Adds events listeners to arrows HTML elements. 2111 * 2112 * @param {String|Array} events 2113 * @param {Element|Window|Document} el 2114 * @param {Function} closure 2115 * @param {Boolean|Object} capture 2116 * @return {Void} 2117 */ 2118 2119 2120 _createClass(EventsBinder, [{ 2121 key: "on", 2122 value: function on(events, el, closure) { 2123 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; 2124 2125 if (isString(events)) { 2126 events = [events]; 2127 } 2128 2129 for (var i = 0; i < events.length; i++) { 2130 this.listeners[events[i]] = closure; 2131 el.addEventListener(events[i], this.listeners[events[i]], capture); 2132 } 2133 } 2134 /** 2135 * Removes event listeners from arrows HTML elements. 2136 * 2137 * @param {String|Array} events 2138 * @param {Element|Window|Document} el 2139 * @param {Boolean|Object} capture 2140 * @return {Void} 2141 */ 2142 2143 }, { 2144 key: "off", 2145 value: function off(events, el) { 2146 var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 2147 2148 if (isString(events)) { 2149 events = [events]; 2150 } 2151 2152 for (var i = 0; i < events.length; i++) { 2153 el.removeEventListener(events[i], this.listeners[events[i]], capture); 2154 } 2155 } 2156 /** 2157 * Destroy collected listeners. 2158 * 2159 * @returns {Void} 2160 */ 2161 2162 }, { 2163 key: "destroy", 2164 value: function destroy() { 2165 delete this.listeners; 2166 } 2167 }]); 2168 2169 return EventsBinder; 2170 }(); 2171 2172 function Resize (Glide, Components, Events) { 2173 /** 2174 * Instance of the binder for DOM Events. 2175 * 2176 * @type {EventsBinder} 2177 */ 2178 var Binder = new EventsBinder(); 2179 var Resize = { 2180 /** 2181 * Initializes window bindings. 2182 */ 2183 mount: function mount() { 2184 this.bind(); 2185 }, 2186 2187 /** 2188 * Binds `rezsize` listener to the window. 2189 * It's a costly event, so we are debouncing it. 2190 * 2191 * @return {Void} 2192 */ 2193 bind: function bind() { 2194 Binder.on('resize', window, throttle(function () { 2195 Events.emit('resize'); 2196 }, Glide.settings.throttle)); 2197 }, 2198 2199 /** 2200 * Unbinds listeners from the window. 2201 * 2202 * @return {Void} 2203 */ 2204 unbind: function unbind() { 2205 Binder.off('resize', window); 2206 } 2207 }; 2208 /** 2209 * Remove bindings from window: 2210 * - on destroying, to remove added EventListener 2211 */ 2212 2213 Events.on('destroy', function () { 2214 Resize.unbind(); 2215 Binder.destroy(); 2216 }); 2217 return Resize; 2218 } 2219 2220 var VALID_DIRECTIONS = ['ltr', 'rtl']; 2221 var FLIPED_MOVEMENTS = { 2222 '>': '<', 2223 '<': '>', 2224 '=': '=' 2225 }; 2226 function Direction (Glide, Components, Events) { 2227 var Direction = { 2228 /** 2229 * Setups gap value based on settings. 2230 * 2231 * @return {Void} 2232 */ 2233 mount: function mount() { 2234 this.value = Glide.settings.direction; 2235 }, 2236 2237 /** 2238 * Resolves pattern based on direction value 2239 * 2240 * @param {String} pattern 2241 * @returns {String} 2242 */ 2243 resolve: function resolve(pattern) { 2244 var token = pattern.slice(0, 1); 2245 2246 if (this.is('rtl')) { 2247 return pattern.split(token).join(FLIPED_MOVEMENTS[token]); 2248 } 2249 2250 return pattern; 2251 }, 2252 2253 /** 2254 * Checks value of direction mode. 2255 * 2256 * @param {String} direction 2257 * @returns {Boolean} 2258 */ 2259 is: function is(direction) { 2260 return this.value === direction; 2261 }, 2262 2263 /** 2264 * Applies direction class to the root HTML element. 2265 * 2266 * @return {Void} 2267 */ 2268 addClass: function addClass() { 2269 Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]); 2270 }, 2271 2272 /** 2273 * Removes direction class from the root HTML element. 2274 * 2275 * @return {Void} 2276 */ 2277 removeClass: function removeClass() { 2278 Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]); 2279 } 2280 }; 2281 define(Direction, 'value', { 2282 /** 2283 * Gets value of the direction. 2284 * 2285 * @returns {Number} 2286 */ 2287 get: function get() { 2288 return Direction._v; 2289 }, 2290 2291 /** 2292 * Sets value of the direction. 2293 * 2294 * @param {String} value 2295 * @return {Void} 2296 */ 2297 set: function set(value) { 2298 if (VALID_DIRECTIONS.indexOf(value) > -1) { 2299 Direction._v = value; 2300 } else { 2301 warn('Direction value must be `ltr` or `rtl`'); 2302 } 2303 } 2304 }); 2305 /** 2306 * Clear direction class: 2307 * - on destroy to bring HTML to its initial state 2308 * - on update to remove class before reappling bellow 2309 */ 2310 2311 Events.on(['destroy', 'update'], function () { 2312 Direction.removeClass(); 2313 }); 2314 /** 2315 * Remount component: 2316 * - on update to reflect changes in direction value 2317 */ 2318 2319 Events.on('update', function () { 2320 Direction.mount(); 2321 }); 2322 /** 2323 * Apply direction class: 2324 * - before building to apply class for the first time 2325 * - on updating to reapply direction class that may changed 2326 */ 2327 2328 Events.on(['build.before', 'update'], function () { 2329 Direction.addClass(); 2330 }); 2331 return Direction; 2332 } 2333 2334 /** 2335 * Reflects value of glide movement. 2336 * 2337 * @param {Object} Glide 2338 * @param {Object} Components 2339 * @return {Object} 2340 */ 2341 function Rtl (Glide, Components) { 2342 return { 2343 /** 2344 * Negates the passed translate if glide is in RTL option. 2345 * 2346 * @param {Number} translate 2347 * @return {Number} 2348 */ 2349 modify: function modify(translate) { 2350 if (Components.Direction.is('rtl')) { 2351 return -translate; 2352 } 2353 2354 return translate; 2355 } 2356 }; 2357 } 2358 2359 /** 2360 * Updates glide movement with a `gap` settings. 2361 * 2362 * @param {Object} Glide 2363 * @param {Object} Components 2364 * @return {Object} 2365 */ 2366 function Gap (Glide, Components) { 2367 return { 2368 /** 2369 * Modifies passed translate value with number in the `gap` settings. 2370 * 2371 * @param {Number} translate 2372 * @return {Number} 2373 */ 2374 modify: function modify(translate) { 2375 var multiplier = Math.floor(translate / Components.Sizes.slideWidth); 2376 return translate + Components.Gaps.value * multiplier; 2377 } 2378 }; 2379 } 2380 2381 /** 2382 * Updates glide movement with width of additional clones width. 2383 * 2384 * @param {Object} Glide 2385 * @param {Object} Components 2386 * @return {Object} 2387 */ 2388 function Grow (Glide, Components) { 2389 return { 2390 /** 2391 * Adds to the passed translate width of the half of clones. 2392 * 2393 * @param {Number} translate 2394 * @return {Number} 2395 */ 2396 modify: function modify(translate) { 2397 return translate + Components.Clones.grow / 2; 2398 } 2399 }; 2400 } 2401 2402 /** 2403 * Updates glide movement with a `peek` settings. 2404 * 2405 * @param {Object} Glide 2406 * @param {Object} Components 2407 * @return {Object} 2408 */ 2409 2410 function Peeking (Glide, Components) { 2411 return { 2412 /** 2413 * Modifies passed translate value with a `peek` setting. 2414 * 2415 * @param {Number} translate 2416 * @return {Number} 2417 */ 2418 modify: function modify(translate) { 2419 if (Glide.settings.focusAt >= 0) { 2420 var peek = Components.Peek.value; 2421 2422 if (isObject(peek)) { 2423 return translate - peek.before; 2424 } 2425 2426 return translate - peek; 2427 } 2428 2429 return translate; 2430 } 2431 }; 2432 } 2433 2434 /** 2435 * Updates glide movement with a `focusAt` settings. 2436 * 2437 * @param {Object} Glide 2438 * @param {Object} Components 2439 * @return {Object} 2440 */ 2441 function Focusing (Glide, Components) { 2442 return { 2443 /** 2444 * Modifies passed translate value with index in the `focusAt` setting. 2445 * 2446 * @param {Number} translate 2447 * @return {Number} 2448 */ 2449 modify: function modify(translate) { 2450 var gap = Components.Gaps.value; 2451 var width = Components.Sizes.width; 2452 var focusAt = Glide.settings.focusAt; 2453 var slideWidth = Components.Sizes.slideWidth; 2454 2455 if (focusAt === 'center') { 2456 return translate - (width / 2 - slideWidth / 2); 2457 } 2458 2459 return translate - slideWidth * focusAt - gap * focusAt; 2460 } 2461 }; 2462 } 2463 2464 /** 2465 * Applies diffrent transformers on translate value. 2466 * 2467 * @param {Object} Glide 2468 * @param {Object} Components 2469 * @return {Object} 2470 */ 2471 2472 function mutator (Glide, Components, Events) { 2473 /** 2474 * Merge instance transformers with collection of default transformers. 2475 * It's important that the Rtl component be last on the list, 2476 * so it reflects all previous transformations. 2477 * 2478 * @type {Array} 2479 */ 2480 var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]); 2481 return { 2482 /** 2483 * Piplines translate value with registered transformers. 2484 * 2485 * @param {Number} translate 2486 * @return {Number} 2487 */ 2488 mutate: function mutate(translate) { 2489 for (var i = 0; i < TRANSFORMERS.length; i++) { 2490 var transformer = TRANSFORMERS[i]; 2491 2492 if (isFunction(transformer) && isFunction(transformer().modify)) { 2493 translate = transformer(Glide, Components, Events).modify(translate); 2494 } else { 2495 warn('Transformer should be a function that returns an object with `modify()` method'); 2496 } 2497 } 2498 2499 return translate; 2500 } 2501 }; 2502 } 2503 2504 function Translate (Glide, Components, Events) { 2505 var Translate = { 2506 /** 2507 * Sets value of translate on HTML element. 2508 * 2509 * @param {Number} value 2510 * @return {Void} 2511 */ 2512 set: function set(value) { 2513 var transform = mutator(Glide, Components).mutate(value); 2514 var translate3d = "translate3d(".concat(-1 * transform, "px, 0px, 0px)"); 2515 Components.Html.wrapper.style.mozTransform = translate3d; // needed for supported Firefox 10-15 2516 2517 Components.Html.wrapper.style.webkitTransform = translate3d; // needed for supported Chrome 10-35, Safari 5.1-8, and Opera 15-22 2518 2519 Components.Html.wrapper.style.transform = translate3d; 2520 }, 2521 2522 /** 2523 * Removes value of translate from HTML element. 2524 * 2525 * @return {Void} 2526 */ 2527 remove: function remove() { 2528 Components.Html.wrapper.style.transform = ''; 2529 }, 2530 2531 /** 2532 * @return {number} 2533 */ 2534 getStartIndex: function getStartIndex() { 2535 var length = Components.Sizes.length; 2536 var index = Glide.index; 2537 var perView = Glide.settings.perView; 2538 2539 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) { 2540 return length + (index - perView); 2541 } // "modulo length" converts an index that equals length to zero 2542 2543 2544 return (index + perView) % length; 2545 }, 2546 2547 /** 2548 * @return {number} 2549 */ 2550 getTravelDistance: function getTravelDistance() { 2551 var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView; 2552 2553 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) { 2554 // reverse travel distance so that we don't have to change subtract operations 2555 return travelDistance * -1; 2556 } 2557 2558 return travelDistance; 2559 } 2560 }; 2561 /** 2562 * Set new translate value: 2563 * - on move to reflect index change 2564 * - on updating via API to reflect possible changes in options 2565 */ 2566 2567 Events.on('move', function (context) { 2568 if (!Glide.isType('carousel') || !Components.Run.isOffset()) { 2569 return Translate.set(context.movement); 2570 } 2571 2572 Components.Transition.after(function () { 2573 Events.emit('translate.jump'); 2574 Translate.set(Components.Sizes.slideWidth * Glide.index); 2575 }); 2576 var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex(); 2577 return Translate.set(startWidth - Components.Translate.getTravelDistance()); 2578 }); 2579 /** 2580 * Remove translate: 2581 * - on destroying to bring markup to its inital state 2582 */ 2583 2584 Events.on('destroy', function () { 2585 Translate.remove(); 2586 }); 2587 return Translate; 2588 } 2589 2590 function Transition (Glide, Components, Events) { 2591 /** 2592 * Holds inactivity status of transition. 2593 * When true transition is not applied. 2594 * 2595 * @type {Boolean} 2596 */ 2597 var disabled = false; 2598 var Transition = { 2599 /** 2600 * Composes string of the CSS transition. 2601 * 2602 * @param {String} property 2603 * @return {String} 2604 */ 2605 compose: function compose(property) { 2606 var settings = Glide.settings; 2607 2608 if (disabled) { 2609 return "".concat(property, " 0ms ").concat(settings.animationTimingFunc); 2610 } 2611 2612 return "".concat(property, " ").concat(this.duration, "ms ").concat(settings.animationTimingFunc); 2613 }, 2614 2615 /** 2616 * Sets value of transition on HTML element. 2617 * 2618 * @param {String=} property 2619 * @return {Void} 2620 */ 2621 set: function set() { 2622 var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform'; 2623 Components.Html.wrapper.style.transition = this.compose(property); 2624 }, 2625 2626 /** 2627 * Removes value of transition from HTML element. 2628 * 2629 * @return {Void} 2630 */ 2631 remove: function remove() { 2632 Components.Html.wrapper.style.transition = ''; 2633 }, 2634 2635 /** 2636 * Runs callback after animation. 2637 * 2638 * @param {Function} callback 2639 * @return {Void} 2640 */ 2641 after: function after(callback) { 2642 setTimeout(function () { 2643 callback(); 2644 }, this.duration); 2645 }, 2646 2647 /** 2648 * Enable transition. 2649 * 2650 * @return {Void} 2651 */ 2652 enable: function enable() { 2653 disabled = false; 2654 this.set(); 2655 }, 2656 2657 /** 2658 * Disable transition. 2659 * 2660 * @return {Void} 2661 */ 2662 disable: function disable() { 2663 disabled = true; 2664 this.set(); 2665 } 2666 }; 2667 define(Transition, 'duration', { 2668 /** 2669 * Gets duration of the transition based 2670 * on currently running animation type. 2671 * 2672 * @return {Number} 2673 */ 2674 get: function get() { 2675 var settings = Glide.settings; 2676 2677 if (Glide.isType('slider') && Components.Run.offset) { 2678 return settings.rewindDuration; 2679 } 2680 2681 return settings.animationDuration; 2682 } 2683 }); 2684 /** 2685 * Set transition `style` value: 2686 * - on each moving, because it may be cleared by offset move 2687 */ 2688 2689 Events.on('move', function () { 2690 Transition.set(); 2691 }); 2692 /** 2693 * Disable transition: 2694 * - before initial build to avoid transitioning from `0` to `startAt` index 2695 * - while resizing window and recalculating dimensions 2696 * - on jumping from offset transition at start and end edges in `carousel` type 2697 */ 2698 2699 Events.on(['build.before', 'resize', 'translate.jump'], function () { 2700 Transition.disable(); 2701 }); 2702 /** 2703 * Enable transition: 2704 * - on each running, because it may be disabled by offset move 2705 */ 2706 2707 Events.on('run', function () { 2708 Transition.enable(); 2709 }); 2710 /** 2711 * Remove transition: 2712 * - on destroying to bring markup to its inital state 2713 */ 2714 2715 Events.on('destroy', function () { 2716 Transition.remove(); 2717 }); 2718 return Transition; 2719 } 2720 2721 /** 2722 * Test via a getter in the options object to see 2723 * if the passive property is accessed. 2724 * 2725 * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection 2726 */ 2727 var supportsPassive = false; 2728 2729 try { 2730 var opts = Object.defineProperty({}, 'passive', { 2731 get: function get() { 2732 supportsPassive = true; 2733 } 2734 }); 2735 window.addEventListener('testPassive', null, opts); 2736 window.removeEventListener('testPassive', null, opts); 2737 } catch (e) {} 2738 2739 var supportsPassive$1 = supportsPassive; 2740 2741 var START_EVENTS = ['touchstart', 'mousedown']; 2742 var MOVE_EVENTS = ['touchmove', 'mousemove']; 2743 var END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave']; 2744 var MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave']; 2745 function Swipe (Glide, Components, Events) { 2746 /** 2747 * Instance of the binder for DOM Events. 2748 * 2749 * @type {EventsBinder} 2750 */ 2751 var Binder = new EventsBinder(); 2752 var swipeSin = 0; 2753 var swipeStartX = 0; 2754 var swipeStartY = 0; 2755 var disabled = false; 2756 var capture = supportsPassive$1 ? { 2757 passive: true 2758 } : false; 2759 var Swipe = { 2760 /** 2761 * Initializes swipe bindings. 2762 * 2763 * @return {Void} 2764 */ 2765 mount: function mount() { 2766 this.bindSwipeStart(); 2767 }, 2768 2769 /** 2770 * Handler for `swipestart` event. Calculates entry points of the user's tap. 2771 * 2772 * @param {Object} event 2773 * @return {Void} 2774 */ 2775 start: function start(event) { 2776 if (!disabled && !Glide.disabled) { 2777 this.disable(); 2778 var swipe = this.touches(event); 2779 swipeSin = null; 2780 swipeStartX = toInt(swipe.pageX); 2781 swipeStartY = toInt(swipe.pageY); 2782 this.bindSwipeMove(); 2783 this.bindSwipeEnd(); 2784 Events.emit('swipe.start'); 2785 } 2786 }, 2787 2788 /** 2789 * Handler for `swipemove` event. Calculates user's tap angle and distance. 2790 * 2791 * @param {Object} event 2792 */ 2793 move: function move(event) { 2794 if (!Glide.disabled) { 2795 var _Glide$settings = Glide.settings, 2796 touchAngle = _Glide$settings.touchAngle, 2797 touchRatio = _Glide$settings.touchRatio, 2798 classes = _Glide$settings.classes; 2799 var swipe = this.touches(event); 2800 var subExSx = toInt(swipe.pageX) - swipeStartX; 2801 var subEySy = toInt(swipe.pageY) - swipeStartY; 2802 var powEX = Math.abs(subExSx << 2); 2803 var powEY = Math.abs(subEySy << 2); 2804 var swipeHypotenuse = Math.sqrt(powEX + powEY); 2805 var swipeCathetus = Math.sqrt(powEY); 2806 swipeSin = Math.asin(swipeCathetus / swipeHypotenuse); 2807 2808 if (swipeSin * 180 / Math.PI < touchAngle) { 2809 event.stopPropagation(); 2810 Components.Move.make(subExSx * toFloat(touchRatio)); 2811 Components.Html.root.classList.add(classes.dragging); 2812 Events.emit('swipe.move'); 2813 } else { 2814 return false; 2815 } 2816 } 2817 }, 2818 2819 /** 2820 * Handler for `swipeend` event. Finitializes user's tap and decides about glide move. 2821 * 2822 * @param {Object} event 2823 * @return {Void} 2824 */ 2825 end: function end(event) { 2826 if (!Glide.disabled) { 2827 var _Glide$settings2 = Glide.settings, 2828 perSwipe = _Glide$settings2.perSwipe, 2829 touchAngle = _Glide$settings2.touchAngle, 2830 classes = _Glide$settings2.classes; 2831 var swipe = this.touches(event); 2832 var threshold = this.threshold(event); 2833 var swipeDistance = swipe.pageX - swipeStartX; 2834 var swipeDeg = swipeSin * 180 / Math.PI; 2835 this.enable(); 2836 2837 if (swipeDistance > threshold && swipeDeg < touchAngle) { 2838 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<"))); 2839 } else if (swipeDistance < -threshold && swipeDeg < touchAngle) { 2840 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">"))); 2841 } else { 2842 // While swipe don't reach distance apply previous transform. 2843 Components.Move.make(); 2844 } 2845 2846 Components.Html.root.classList.remove(classes.dragging); 2847 this.unbindSwipeMove(); 2848 this.unbindSwipeEnd(); 2849 Events.emit('swipe.end'); 2850 } 2851 }, 2852 2853 /** 2854 * Binds swipe's starting event. 2855 * 2856 * @return {Void} 2857 */ 2858 bindSwipeStart: function bindSwipeStart() { 2859 var _this = this; 2860 2861 var _Glide$settings3 = Glide.settings, 2862 swipeThreshold = _Glide$settings3.swipeThreshold, 2863 dragThreshold = _Glide$settings3.dragThreshold; 2864 2865 if (swipeThreshold) { 2866 Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) { 2867 _this.start(event); 2868 }, capture); 2869 } 2870 2871 if (dragThreshold) { 2872 Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) { 2873 _this.start(event); 2874 }, capture); 2875 } 2876 }, 2877 2878 /** 2879 * Unbinds swipe's starting event. 2880 * 2881 * @return {Void} 2882 */ 2883 unbindSwipeStart: function unbindSwipeStart() { 2884 Binder.off(START_EVENTS[0], Components.Html.wrapper, capture); 2885 Binder.off(START_EVENTS[1], Components.Html.wrapper, capture); 2886 }, 2887 2888 /** 2889 * Binds swipe's moving event. 2890 * 2891 * @return {Void} 2892 */ 2893 bindSwipeMove: function bindSwipeMove() { 2894 var _this2 = this; 2895 2896 Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) { 2897 _this2.move(event); 2898 }, Glide.settings.throttle), capture); 2899 }, 2900 2901 /** 2902 * Unbinds swipe's moving event. 2903 * 2904 * @return {Void} 2905 */ 2906 unbindSwipeMove: function unbindSwipeMove() { 2907 Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture); 2908 }, 2909 2910 /** 2911 * Binds swipe's ending event. 2912 * 2913 * @return {Void} 2914 */ 2915 bindSwipeEnd: function bindSwipeEnd() { 2916 var _this3 = this; 2917 2918 Binder.on(END_EVENTS, Components.Html.wrapper, function (event) { 2919 _this3.end(event); 2920 }); 2921 }, 2922 2923 /** 2924 * Unbinds swipe's ending event. 2925 * 2926 * @return {Void} 2927 */ 2928 unbindSwipeEnd: function unbindSwipeEnd() { 2929 Binder.off(END_EVENTS, Components.Html.wrapper); 2930 }, 2931 2932 /** 2933 * Normalizes event touches points accorting to different types. 2934 * 2935 * @param {Object} event 2936 */ 2937 touches: function touches(event) { 2938 if (MOUSE_EVENTS.indexOf(event.type) > -1) { 2939 return event; 2940 } 2941 2942 return event.touches[0] || event.changedTouches[0]; 2943 }, 2944 2945 /** 2946 * Gets value of minimum swipe distance settings based on event type. 2947 * 2948 * @return {Number} 2949 */ 2950 threshold: function threshold(event) { 2951 var settings = Glide.settings; 2952 2953 if (MOUSE_EVENTS.indexOf(event.type) > -1) { 2954 return settings.dragThreshold; 2955 } 2956 2957 return settings.swipeThreshold; 2958 }, 2959 2960 /** 2961 * Enables swipe event. 2962 * 2963 * @return {self} 2964 */ 2965 enable: function enable() { 2966 disabled = false; 2967 Components.Transition.enable(); 2968 return this; 2969 }, 2970 2971 /** 2972 * Disables swipe event. 2973 * 2974 * @return {self} 2975 */ 2976 disable: function disable() { 2977 disabled = true; 2978 Components.Transition.disable(); 2979 return this; 2980 } 2981 }; 2982 /** 2983 * Add component class: 2984 * - after initial building 2985 */ 2986 2987 Events.on('build.after', function () { 2988 Components.Html.root.classList.add(Glide.settings.classes.swipeable); 2989 }); 2990 /** 2991 * Remove swiping bindings: 2992 * - on destroying, to remove added EventListeners 2993 */ 2994 2995 Events.on('destroy', function () { 2996 Swipe.unbindSwipeStart(); 2997 Swipe.unbindSwipeMove(); 2998 Swipe.unbindSwipeEnd(); 2999 Binder.destroy(); 3000 }); 3001 return Swipe; 3002 } 3003 3004 function Images (Glide, Components, Events) { 3005 /** 3006 * Instance of the binder for DOM Events. 3007 * 3008 * @type {EventsBinder} 3009 */ 3010 var Binder = new EventsBinder(); 3011 var Images = { 3012 /** 3013 * Binds listener to glide wrapper. 3014 * 3015 * @return {Void} 3016 */ 3017 mount: function mount() { 3018 this.bind(); 3019 }, 3020 3021 /** 3022 * Binds `dragstart` event on wrapper to prevent dragging images. 3023 * 3024 * @return {Void} 3025 */ 3026 bind: function bind() { 3027 Binder.on('dragstart', Components.Html.wrapper, this.dragstart); 3028 }, 3029 3030 /** 3031 * Unbinds `dragstart` event on wrapper. 3032 * 3033 * @return {Void} 3034 */ 3035 unbind: function unbind() { 3036 Binder.off('dragstart', Components.Html.wrapper); 3037 }, 3038 3039 /** 3040 * Event handler. Prevents dragging. 3041 * 3042 * @return {Void} 3043 */ 3044 dragstart: function dragstart(event) { 3045 event.preventDefault(); 3046 } 3047 }; 3048 /** 3049 * Remove bindings from images: 3050 * - on destroying, to remove added EventListeners 3051 */ 3052 3053 Events.on('destroy', function () { 3054 Images.unbind(); 3055 Binder.destroy(); 3056 }); 3057 return Images; 3058 } 3059 3060 function Anchors (Glide, Components, Events) { 3061 /** 3062 * Instance of the binder for DOM Events. 3063 * 3064 * @type {EventsBinder} 3065 */ 3066 var Binder = new EventsBinder(); 3067 /** 3068 * Holds detaching status of anchors. 3069 * Prevents detaching of already detached anchors. 3070 * 3071 * @private 3072 * @type {Boolean} 3073 */ 3074 3075 var detached = false; 3076 /** 3077 * Holds preventing status of anchors. 3078 * If `true` redirection after click will be disabled. 3079 * 3080 * @private 3081 * @type {Boolean} 3082 */ 3083 3084 var prevented = false; 3085 var Anchors = { 3086 /** 3087 * Setups a initial state of anchors component. 3088 * 3089 * @returns {Void} 3090 */ 3091 mount: function mount() { 3092 /** 3093 * Holds collection of anchors elements. 3094 * 3095 * @private 3096 * @type {HTMLCollection} 3097 */ 3098 this._a = Components.Html.wrapper.querySelectorAll('a'); 3099 this.bind(); 3100 }, 3101 3102 /** 3103 * Binds events to anchors inside a track. 3104 * 3105 * @return {Void} 3106 */ 3107 bind: function bind() { 3108 Binder.on('click', Components.Html.wrapper, this.click); 3109 }, 3110 3111 /** 3112 * Unbinds events attached to anchors inside a track. 3113 * 3114 * @return {Void} 3115 */ 3116 unbind: function unbind() { 3117 Binder.off('click', Components.Html.wrapper); 3118 }, 3119 3120 /** 3121 * Handler for click event. Prevents clicks when glide is in `prevent` status. 3122 * 3123 * @param {Object} event 3124 * @return {Void} 3125 */ 3126 click: function click(event) { 3127 if (prevented) { 3128 event.stopPropagation(); 3129 event.preventDefault(); 3130 } 3131 }, 3132 3133 /** 3134 * Detaches anchors click event inside glide. 3135 * 3136 * @return {self} 3137 */ 3138 detach: function detach() { 3139 prevented = true; 3140 3141 if (!detached) { 3142 for (var i = 0; i < this.items.length; i++) { 3143 this.items[i].draggable = false; 3144 } 3145 3146 detached = true; 3147 } 3148 3149 return this; 3150 }, 3151 3152 /** 3153 * Attaches anchors click events inside glide. 3154 * 3155 * @return {self} 3156 */ 3157 attach: function attach() { 3158 prevented = false; 3159 3160 if (detached) { 3161 for (var i = 0; i < this.items.length; i++) { 3162 this.items[i].draggable = true; 3163 } 3164 3165 detached = false; 3166 } 3167 3168 return this; 3169 } 3170 }; 3171 define(Anchors, 'items', { 3172 /** 3173 * Gets collection of the arrows HTML elements. 3174 * 3175 * @return {HTMLElement[]} 3176 */ 3177 get: function get() { 3178 return Anchors._a; 3179 } 3180 }); 3181 /** 3182 * Detach anchors inside slides: 3183 * - on swiping, so they won't redirect to its `href` attributes 3184 */ 3185 3186 Events.on('swipe.move', function () { 3187 Anchors.detach(); 3188 }); 3189 /** 3190 * Attach anchors inside slides: 3191 * - after swiping and transitions ends, so they can redirect after click again 3192 */ 3193 3194 Events.on('swipe.end', function () { 3195 Components.Transition.after(function () { 3196 Anchors.attach(); 3197 }); 3198 }); 3199 /** 3200 * Unbind anchors inside slides: 3201 * - on destroying, to bring anchors to its initial state 3202 */ 3203 3204 Events.on('destroy', function () { 3205 Anchors.attach(); 3206 Anchors.unbind(); 3207 Binder.destroy(); 3208 }); 3209 return Anchors; 3210 } 3211 3212 var NAV_SELECTOR = '[data-glide-el="controls[nav]"]'; 3213 var CONTROLS_SELECTOR = '[data-glide-el^="controls"]'; 3214 var PREVIOUS_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\"<\"]"); 3215 var NEXT_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\">\"]"); 3216 function Controls (Glide, Components, Events) { 3217 /** 3218 * Instance of the binder for DOM Events. 3219 * 3220 * @type {EventsBinder} 3221 */ 3222 var Binder = new EventsBinder(); 3223 var capture = supportsPassive$1 ? { 3224 passive: true 3225 } : false; 3226 var Controls = { 3227 /** 3228 * Inits arrows. Binds events listeners 3229 * to the arrows HTML elements. 3230 * 3231 * @return {Void} 3232 */ 3233 mount: function mount() { 3234 /** 3235 * Collection of navigation HTML elements. 3236 * 3237 * @private 3238 * @type {HTMLCollection} 3239 */ 3240 this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR); 3241 /** 3242 * Collection of controls HTML elements. 3243 * 3244 * @private 3245 * @type {HTMLCollection} 3246 */ 3247 3248 this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR); 3249 /** 3250 * Collection of arrow control HTML elements. 3251 * 3252 * @private 3253 * @type {Object} 3254 */ 3255 3256 this._arrowControls = { 3257 previous: Components.Html.root.querySelectorAll(PREVIOUS_CONTROLS_SELECTOR), 3258 next: Components.Html.root.querySelectorAll(NEXT_CONTROLS_SELECTOR) 3259 }; 3260 this.addBindings(); 3261 }, 3262 3263 /** 3264 * Sets active class to current slide. 3265 * 3266 * @return {Void} 3267 */ 3268 setActive: function setActive() { 3269 for (var i = 0; i < this._n.length; i++) { 3270 this.addClass(this._n[i].children); 3271 } 3272 }, 3273 3274 /** 3275 * Removes active class to current slide. 3276 * 3277 * @return {Void} 3278 */ 3279 removeActive: function removeActive() { 3280 for (var i = 0; i < this._n.length; i++) { 3281 this.removeClass(this._n[i].children); 3282 } 3283 }, 3284 3285 /** 3286 * Toggles active class on items inside navigation. 3287 * 3288 * @param {HTMLElement} controls 3289 * @return {Void} 3290 */ 3291 addClass: function addClass(controls) { 3292 var settings = Glide.settings; 3293 var item = controls[Glide.index]; 3294 3295 if (!item) { 3296 return; 3297 } 3298 3299 item.classList.add(settings.classes.nav.active); 3300 siblings(item).forEach(function (sibling) { 3301 sibling.classList.remove(settings.classes.nav.active); 3302 }); 3303 }, 3304 3305 /** 3306 * Removes active class from active control. 3307 * 3308 * @param {HTMLElement} controls 3309 * @return {Void} 3310 */ 3311 removeClass: function removeClass(controls) { 3312 var item = controls[Glide.index]; 3313 item === null || item === void 0 ? void 0 : item.classList.remove(Glide.settings.classes.nav.active); 3314 }, 3315 3316 /** 3317 * Calculates, removes or adds `Glide.settings.classes.disabledArrow` class on the control arrows 3318 */ 3319 setArrowState: function setArrowState() { 3320 if (Glide.settings.rewind) { 3321 return; 3322 } 3323 3324 var next = Controls._arrowControls.next; 3325 var previous = Controls._arrowControls.previous; 3326 this.resetArrowState(next, previous); 3327 3328 if (Glide.index === 0) { 3329 this.disableArrow(previous); 3330 } 3331 3332 if (Glide.index === Components.Run.length) { 3333 this.disableArrow(next); 3334 } 3335 }, 3336 3337 /** 3338 * Removes `Glide.settings.classes.disabledArrow` from given NodeList elements 3339 * 3340 * @param {NodeList[]} lists 3341 */ 3342 resetArrowState: function resetArrowState() { 3343 var settings = Glide.settings; 3344 3345 for (var _len = arguments.length, lists = new Array(_len), _key = 0; _key < _len; _key++) { 3346 lists[_key] = arguments[_key]; 3347 } 3348 3349 lists.forEach(function (list) { 3350 toArray(list).forEach(function (element) { 3351 element.classList.remove(settings.classes.arrow.disabled); 3352 }); 3353 }); 3354 }, 3355 3356 /** 3357 * Adds `Glide.settings.classes.disabledArrow` to given NodeList elements 3358 * 3359 * @param {NodeList[]} lists 3360 */ 3361 disableArrow: function disableArrow() { 3362 var settings = Glide.settings; 3363 3364 for (var _len2 = arguments.length, lists = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 3365 lists[_key2] = arguments[_key2]; 3366 } 3367 3368 lists.forEach(function (list) { 3369 toArray(list).forEach(function (element) { 3370 element.classList.add(settings.classes.arrow.disabled); 3371 }); 3372 }); 3373 }, 3374 3375 /** 3376 * Adds handles to the each group of controls. 3377 * 3378 * @return {Void} 3379 */ 3380 addBindings: function addBindings() { 3381 for (var i = 0; i < this._c.length; i++) { 3382 this.bind(this._c[i].children); 3383 } 3384 }, 3385 3386 /** 3387 * Removes handles from the each group of controls. 3388 * 3389 * @return {Void} 3390 */ 3391 removeBindings: function removeBindings() { 3392 for (var i = 0; i < this._c.length; i++) { 3393 this.unbind(this._c[i].children); 3394 } 3395 }, 3396 3397 /** 3398 * Binds events to arrows HTML elements. 3399 * 3400 * @param {HTMLCollection} elements 3401 * @return {Void} 3402 */ 3403 bind: function bind(elements) { 3404 for (var i = 0; i < elements.length; i++) { 3405 Binder.on('click', elements[i], this.click); 3406 Binder.on('touchstart', elements[i], this.click, capture); 3407 } 3408 }, 3409 3410 /** 3411 * Unbinds events binded to the arrows HTML elements. 3412 * 3413 * @param {HTMLCollection} elements 3414 * @return {Void} 3415 */ 3416 unbind: function unbind(elements) { 3417 for (var i = 0; i < elements.length; i++) { 3418 Binder.off(['click', 'touchstart'], elements[i]); 3419 } 3420 }, 3421 3422 /** 3423 * Handles `click` event on the arrows HTML elements. 3424 * Moves slider in direction given via the 3425 * `data-glide-dir` attribute. 3426 * 3427 * @param {Object} event 3428 * @return {void} 3429 */ 3430 click: function click(event) { 3431 if (!supportsPassive$1 && event.type === 'touchstart') { 3432 event.preventDefault(); 3433 } 3434 3435 var direction = event.currentTarget.getAttribute('data-glide-dir'); 3436 Components.Run.make(Components.Direction.resolve(direction)); 3437 } 3438 }; 3439 define(Controls, 'items', { 3440 /** 3441 * Gets collection of the controls HTML elements. 3442 * 3443 * @return {HTMLElement[]} 3444 */ 3445 get: function get() { 3446 return Controls._c; 3447 } 3448 }); 3449 /** 3450 * Swap active class of current navigation item: 3451 * - after mounting to set it to initial index 3452 * - after each move to the new index 3453 */ 3454 3455 Events.on(['mount.after', 'move.after'], function () { 3456 Controls.setActive(); 3457 }); 3458 /** 3459 * Add or remove disabled class of arrow elements 3460 */ 3461 3462 Events.on(['mount.after', 'run'], function () { 3463 Controls.setArrowState(); 3464 }); 3465 /** 3466 * Remove bindings and HTML Classes: 3467 * - on destroying, to bring markup to its initial state 3468 */ 3469 3470 Events.on('destroy', function () { 3471 Controls.removeBindings(); 3472 Controls.removeActive(); 3473 Binder.destroy(); 3474 }); 3475 return Controls; 3476 } 3477 3478 function Keyboard (Glide, Components, Events) { 3479 /** 3480 * Instance of the binder for DOM Events. 3481 * 3482 * @type {EventsBinder} 3483 */ 3484 var Binder = new EventsBinder(); 3485 var Keyboard = { 3486 /** 3487 * Binds keyboard events on component mount. 3488 * 3489 * @return {Void} 3490 */ 3491 mount: function mount() { 3492 if (Glide.settings.keyboard) { 3493 this.bind(); 3494 } 3495 }, 3496 3497 /** 3498 * Adds keyboard press events. 3499 * 3500 * @return {Void} 3501 */ 3502 bind: function bind() { 3503 Binder.on('keyup', document, this.press); 3504 }, 3505 3506 /** 3507 * Removes keyboard press events. 3508 * 3509 * @return {Void} 3510 */ 3511 unbind: function unbind() { 3512 Binder.off('keyup', document); 3513 }, 3514 3515 /** 3516 * Handles keyboard's arrows press and moving glide foward and backward. 3517 * 3518 * @param {Object} event 3519 * @return {Void} 3520 */ 3521 press: function press(event) { 3522 var perSwipe = Glide.settings.perSwipe; 3523 var arrowSymbols = { 3524 ArrowRight: '>', 3525 ArrowLeft: '<' 3526 }; 3527 3528 if (['ArrowRight', 'ArrowLeft'].includes(event.code)) { 3529 Components.Run.make(Components.Direction.resolve("".concat(perSwipe).concat(arrowSymbols[event.code]))); 3530 } 3531 } 3532 }; 3533 /** 3534 * Remove bindings from keyboard: 3535 * - on destroying to remove added events 3536 * - on updating to remove events before remounting 3537 */ 3538 3539 Events.on(['destroy', 'update'], function () { 3540 Keyboard.unbind(); 3541 }); 3542 /** 3543 * Remount component 3544 * - on updating to reflect potential changes in settings 3545 */ 3546 3547 Events.on('update', function () { 3548 Keyboard.mount(); 3549 }); 3550 /** 3551 * Destroy binder: 3552 * - on destroying to remove listeners 3553 */ 3554 3555 Events.on('destroy', function () { 3556 Binder.destroy(); 3557 }); 3558 return Keyboard; 3559 } 3560 3561 function Autoplay (Glide, Components, Events) { 3562 /** 3563 * Instance of the binder for DOM Events. 3564 * 3565 * @type {EventsBinder} 3566 */ 3567 var Binder = new EventsBinder(); 3568 var Autoplay = { 3569 /** 3570 * Initializes autoplaying and events. 3571 * 3572 * @return {Void} 3573 */ 3574 mount: function mount() { 3575 this.enable(); 3576 this.start(); 3577 3578 if (Glide.settings.hoverpause) { 3579 this.bind(); 3580 } 3581 }, 3582 3583 /** 3584 * Enables autoplaying 3585 * 3586 * @returns {Void} 3587 */ 3588 enable: function enable() { 3589 this._e = true; 3590 }, 3591 3592 /** 3593 * Disables autoplaying. 3594 * 3595 * @returns {Void} 3596 */ 3597 disable: function disable() { 3598 this._e = false; 3599 }, 3600 3601 /** 3602 * Starts autoplaying in configured interval. 3603 * 3604 * @param {Boolean|Number} force Run autoplaying with passed interval regardless of `autoplay` settings 3605 * @return {Void} 3606 */ 3607 start: function start() { 3608 var _this = this; 3609 3610 if (!this._e) { 3611 return; 3612 } 3613 3614 this.enable(); 3615 3616 if (Glide.settings.autoplay) { 3617 if (isUndefined(this._i)) { 3618 this._i = setInterval(function () { 3619 _this.stop(); 3620 3621 Components.Run.make('>'); 3622 3623 _this.start(); 3624 3625 Events.emit('autoplay'); 3626 }, this.time); 3627 } 3628 } 3629 }, 3630 3631 /** 3632 * Stops autorunning of the glide. 3633 * 3634 * @return {Void} 3635 */ 3636 stop: function stop() { 3637 this._i = clearInterval(this._i); 3638 }, 3639 3640 /** 3641 * Stops autoplaying while mouse is over glide's area. 3642 * 3643 * @return {Void} 3644 */ 3645 bind: function bind() { 3646 var _this2 = this; 3647 3648 Binder.on('mouseover', Components.Html.root, function () { 3649 if (_this2._e) { 3650 _this2.stop(); 3651 } 3652 }); 3653 Binder.on('mouseout', Components.Html.root, function () { 3654 if (_this2._e) { 3655 _this2.start(); 3656 } 3657 }); 3658 }, 3659 3660 /** 3661 * Unbind mouseover events. 3662 * 3663 * @returns {Void} 3664 */ 3665 unbind: function unbind() { 3666 Binder.off(['mouseover', 'mouseout'], Components.Html.root); 3667 } 3668 }; 3669 define(Autoplay, 'time', { 3670 /** 3671 * Gets time period value for the autoplay interval. Prioritizes 3672 * times in `data-glide-autoplay` attrubutes over options. 3673 * 3674 * @return {Number} 3675 */ 3676 get: function get() { 3677 var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay'); 3678 3679 if (autoplay) { 3680 return toInt(autoplay); 3681 } 3682 3683 return toInt(Glide.settings.autoplay); 3684 } 3685 }); 3686 /** 3687 * Stop autoplaying and unbind events: 3688 * - on destroying, to clear defined interval 3689 * - on updating via API to reset interval that may changed 3690 */ 3691 3692 Events.on(['destroy', 'update'], function () { 3693 Autoplay.unbind(); 3694 }); 3695 /** 3696 * Stop autoplaying: 3697 * - before each run, to restart autoplaying 3698 * - on pausing via API 3699 * - on destroying, to clear defined interval 3700 * - while starting a swipe 3701 * - on updating via API to reset interval that may changed 3702 */ 3703 3704 Events.on(['run.before', 'swipe.start', 'update'], function () { 3705 Autoplay.stop(); 3706 }); 3707 Events.on(['pause', 'destroy'], function () { 3708 Autoplay.disable(); 3709 Autoplay.stop(); 3710 }); 3711 /** 3712 * Start autoplaying: 3713 * - after each run, to restart autoplaying 3714 * - on playing via API 3715 * - while ending a swipe 3716 */ 3717 3718 Events.on(['run.after', 'swipe.end'], function () { 3719 Autoplay.start(); 3720 }); 3721 /** 3722 * Start autoplaying: 3723 * - after each run, to restart autoplaying 3724 * - on playing via API 3725 * - while ending a swipe 3726 */ 3727 3728 Events.on(['play'], function () { 3729 Autoplay.enable(); 3730 Autoplay.start(); 3731 }); 3732 /** 3733 * Remount autoplaying: 3734 * - on updating via API to reset interval that may changed 3735 */ 3736 3737 Events.on('update', function () { 3738 Autoplay.mount(); 3739 }); 3740 /** 3741 * Destroy a binder: 3742 * - on destroying glide instance to clearup listeners 3743 */ 3744 3745 Events.on('destroy', function () { 3746 Binder.destroy(); 3747 }); 3748 return Autoplay; 3749 } 3750 3751 /** 3752 * Sorts keys of breakpoint object so they will be ordered from lower to bigger. 3753 * 3754 * @param {Object} points 3755 * @returns {Object} 3756 */ 3757 3758 function sortBreakpoints(points) { 3759 if (isObject(points)) { 3760 return sortKeys(points); 3761 } else { 3762 warn("Breakpoints option must be an object"); 3763 } 3764 3765 return {}; 3766 } 3767 3768 function Breakpoints (Glide, Components, Events) { 3769 /** 3770 * Instance of the binder for DOM Events. 3771 * 3772 * @type {EventsBinder} 3773 */ 3774 var Binder = new EventsBinder(); 3775 /** 3776 * Holds reference to settings. 3777 * 3778 * @type {Object} 3779 */ 3780 3781 var settings = Glide.settings; 3782 /** 3783 * Holds reference to breakpoints object in settings. Sorts breakpoints 3784 * from smaller to larger. It is required in order to proper 3785 * matching currently active breakpoint settings. 3786 * 3787 * @type {Object} 3788 */ 3789 3790 var points = sortBreakpoints(settings.breakpoints); 3791 /** 3792 * Cache initial settings before overwritting. 3793 * 3794 * @type {Object} 3795 */ 3796 3797 var defaults = Object.assign({}, settings); 3798 var Breakpoints = { 3799 /** 3800 * Matches settings for currectly matching media breakpoint. 3801 * 3802 * @param {Object} points 3803 * @returns {Object} 3804 */ 3805 match: function match(points) { 3806 if (typeof window.matchMedia !== 'undefined') { 3807 for (var point in points) { 3808 if (points.hasOwnProperty(point)) { 3809 if (window.matchMedia("(max-width: ".concat(point, "px)")).matches) { 3810 return points[point]; 3811 } 3812 } 3813 } 3814 } 3815 3816 return defaults; 3817 } 3818 }; 3819 /** 3820 * Overwrite instance settings with currently matching breakpoint settings. 3821 * This happens right after component initialization. 3822 */ 3823 3824 Object.assign(settings, Breakpoints.match(points)); 3825 /** 3826 * Update glide with settings of matched brekpoint: 3827 * - window resize to update slider 3828 */ 3829 3830 Binder.on('resize', window, throttle(function () { 3831 Glide.settings = mergeOptions(settings, Breakpoints.match(points)); 3832 }, Glide.settings.throttle)); 3833 /** 3834 * Resort and update default settings: 3835 * - on reinit via API, so breakpoint matching will be performed with options 3836 */ 3837 3838 Events.on('update', function () { 3839 points = sortBreakpoints(points); 3840 defaults = Object.assign({}, settings); 3841 }); 3842 /** 3843 * Unbind resize listener: 3844 * - on destroying, to bring markup to its initial state 3845 */ 3846 3847 Events.on('destroy', function () { 3848 Binder.off('resize', window); 3849 }); 3850 return Breakpoints; 3851 } 3852 3853 var COMPONENTS = { 3854 // Required 3855 Html: Html, 3856 Translate: Translate, 3857 Transition: Transition, 3858 Direction: Direction, 3859 Peek: Peek, 3860 Sizes: Sizes, 3861 Gaps: Gaps, 3862 Move: Move, 3863 Clones: Clones, 3864 Resize: Resize, 3865 Build: Build, 3866 Run: Run, 3867 // Optional 3868 Swipe: Swipe, 3869 Images: Images, 3870 Anchors: Anchors, 3871 Controls: Controls, 3872 Keyboard: Keyboard, 3873 Autoplay: Autoplay, 3874 Breakpoints: Breakpoints 3875 }; 3876 3877 var Glide = /*#__PURE__*/function (_Core) { 3878 _inherits(Glide, _Core); 3879 3880 var _super = _createSuper(Glide); 3881 3882 function Glide() { 3883 _classCallCheck(this, Glide); 3884 3885 return _super.apply(this, arguments); 3886 } 3887 3888 _createClass(Glide, [{ 3889 key: "mount", 3890 value: function mount() { 3891 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 3892 return _get(_getPrototypeOf(Glide.prototype), "mount", this).call(this, Object.assign({}, COMPONENTS, extensions)); 3893 } 3894 }]); 3895 3896 return Glide; 3897 }(Glide$1); 3898 3899 return Glide; 3900 3901}));
3902 3903/*jshint browser:true */ 3904/*! 3905* FitVids 1.1 3906* 3907* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com 3908* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ 3909* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ 3910* 3911*/ 3912 3913;(function( $ ){ 3914 3915 'use strict'; 3916 3917 $.fn.fitVids = function( options ) { 3918 var settings = { 3919 customSelector: null, 3920 ignore: null 3921 }; 3922 3923 if(!document.getElementById('fit-vids-style')) { 3924 // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js 3925 var head = document.head || document.getElementsByTagName('head')[0]; 3926 var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}'; 3927 var div = document.createElement("div"); 3928 div.innerHTML = '<p>
3928x</p><style id="fit-vids-style">' + css + '</style>'; 3929 head.appendChild(div.childNodes[1]); 3930 } 3931 3932 if ( options ) { 3933 $.extend( settings, options ); 3934 } 3935 3936 return this.each(function(){ 3937 var selectors = [ 3938 'iframe[src*="player.vimeo.com"]', 3939 'iframe[src*="youtube.com"]', 3940 'iframe[src*="youtube-nocookie.com"]', 3941 'iframe[src*="kickstarter.com"][src*="video.html"]', 3942 'object', 3943 'embed' 3944 ]; 3945 3946 if (settings.customSelector) { 3947 selectors.push(settings.customSelector); 3948 } 3949 3950 var ignoreList = '.fitvidsignore'; 3951 3952 if(settings.ignore) { 3953 ignoreList = ignoreList + ', ' + settings.ignore; 3954 } 3955 3956 var $allVideos = $(this).find(selectors.join(',')); 3957 $allVideos = $allVideos.not('object object'); // SwfObj conflict patch 3958 $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video. 3959 3960 $allVideos.each(function(){ 3961 var $this = $(this); 3962 if($this.parents(ignoreList).length > 0) { 3963 return; // Disable FitVids on this video. 3964 } 3965 if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } 3966 if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width')))) 3967 { 3968 $this.attr('height', 9); 3969 $this.attr('width', 16); 3970 } 3971 var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), 3972 width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), 3973 aspectRatio = height / width; 3974 if(!$this.attr('name')){ 3975 var videoName = 'fitvid' + $.fn.fitVids._count; 3976 $this.attr('name', videoName); 3977 $.fn.fitVids._count++; 3978 } 3979 $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%'); 3980 $this.removeAttr('height').removeAttr('width'); 3981 }); 3982 }); 3983 }; 3984 3985 // Internal counter for unique video names. 3986 $.fn.fitVids._count = 0; 3987 3988// Works with either jQuery or Zepto 3989})( window.jQuery || window.Zepto ); 3990 3991/*! Lity - v2.4.1 - 2020-04-26 3992* http://sorgalla.com/lity/ 3993* Copyright (c) 2015-2020 Jan Sorgalla; Licensed MIT */ 3994 3995!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return b(a,c)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=b(a,require("jquery")):a.lity=b(a,a.jQuery||a.Zepto)}("undefined"!=typeof window?window:this,function(a,b){"use strict";function c(a){var b=B();return N&&a.length?(a.one(N,b.resolve),setTimeout(b.resolve,500)):b.resolve(),b.promise()}function d(a,c,d){if(1===arguments.length)return b.extend({},a);if("string"==typeof c){if(void 0===d)return void 0===a[c]?null:a[c];a[c]=d}else b.extend(a,c);return this}function e(a){for(var b,c=decodeURI(a.split("#")[0]).split("&"),d={},e=0,f=c.length;e<f;e++)c[e]&&(b=c[e].split("="),d[b[0]]=b[1]);return d}function f(a,c){return a+(a.indexOf("?")>-1?"&":"?")+b.param(c)}function g(a,b){var c=a.indexOf("#");return-1===c?b:(c>0&&(a=a.substr(c)),b+a)}function h(a){return b('<span class="lity-error"></span>').append(a)}function i(a,c){var d=c.opener()&&c.opener().data("lity-desc")||"Image with no description",e=b('<img src="'+a+'" alt="'+d+'"/>'),f=B(),g=function(){f.reject(h("Failed loading image"))};return e.on("load",function(){if(0===this.naturalWidth)return g();f.resolve(e)}).on("error",g),f.promise()}function j(a,c){var d,e,f;try{d=b(a)}catch(a){return!1}return!!d.length&&(e=b('<i style="display:none !important"></i>'),f=d.hasClass("lity-hide"),c.element().one("lity:remove",function(){e.before(d).remove(),f&&!d.closest(".lity-content").length&&d.addClass("lity-hide")}),d.removeClass("lity-hide").after(e))}function k(a){var c=J.exec(a);return!!c&&o(g(a,f("https://www.youtube"+(c[2]||"")+".com/embed/"+c[4],b.extend({autoplay:1},e(c[5]||"")))))}function l(a){var c=K.exec(a);return!!c&&o(g(a,f("https://player.vimeo.com/video/"+c[3],b.extend({autoplay:1},e(c[4]||"")))))}function m(a){var c=M.exec(a);return!!c&&(0!==a.indexOf("http")&&(a="https:"+a),o(g(a,f("https://www.facebook.com/plugins/video.php?href="+a,b.extend({autoplay:1},e(c[4]||""))))))}function n(a){var b=L.exec(a);return!!b&&o(g(a,f("https://www.google."+b[3]+"/maps?"+b[6],{output:b[6].indexOf("layer=c")>0?"svembed":"embed"})))}function o(a){return'<div class="lity-iframe-container"><iframe frameborder="0" allowfullscreen allow="autoplay; fullscreen" src="'+a+'"/></div>'}function p(){return z.documentElement.clientHeight?z.documentElement.clientHeight:Math.round(A.height())}function q(a){var b=v();b&&(27===a.keyCode&&b.options("esc")&&b.close(),9===a.keyCode&&r(a,b))}function r(a,b){var c=b.element().find(G),d=c.index(z.activeElement);a.shiftKey&&d<=0?(c.get(c.length-1).focus(),a.preventDefault()):a.shiftKey||d!==c.length-1||(c.get(0).focus(),a.preventDefault())}function s(){b.each(D,function(a,b){b.resize()})}function t(a){1===D.unshift(a)&&(C.addClass("lity-active"),A.on({resize:s,keydown:q})),b("body >
3995 *").not(a.element()).addClass("lity-hidden").each(function(){var a=b(this);void 0===a.data(F)&&a.data(F,a.attr(E)||null)}).attr(E,"true")}function u(a){var c;a.element().attr(E,"true"),1===D.length&&(C.removeClass("lity-active"),A.off({resize:s,keydown:q})),D=b.grep(D,function(b){return a!==b}),c=D.length?D[0].element():b(".lity-hidden"),c.removeClass("lity-hidden").each(function(){var a=b(this),c=a.data(F);c?a.attr(E,c):a.removeAttr(E),a.removeData(F)})}function v(){return 0===D.length?null:D[0]}function w(a,c,d,e){var f,g="inline",h=b.extend({},d);return e&&h[e]?(f=h[e](a,c),g=e):(b.each(["inline","iframe"],function(a,b){delete h[b],h[b]=d[b]}),b.each(h,function(b,d){return!d||(!(!d.test||d.test(a,c))||(f=d(a,c),!1!==f?(g=b,!1):void 0))})),{handler:g,content:f||""}}function x(a,e,f,g){function h(a){k=b(a).css("max-height",p()+"px"),j.find(".lity-loader").each(function(){var a=b(this);c(a).always(function(){a.remove()})}),j.removeClass("lity-loading").find(".lity-content").empty().append(k),m=!0,k.trigger("lity:ready",[l])}var i,j,k,l=this,m=!1,n=!1;e=b.extend({},H,e),j=b(e.template),l.element=function(){return j},l.opener=function(){return f},l.options=b.proxy(d,l,e),l.handlers=b.proxy(d,l,e.handlers),l.resize=function(){m&&!n&&k.css("max-height",p()+"px").trigger("lity:resize",[l])},l.close=function(){if(m&&!n){n=!0,u(l);var a=B();if(g&&(z.activeElement===j[0]||b.contains(j[0],z.activeElement)))try{g.focus()}catch(a){}return k.trigger("lity:close",[l]),j.removeClass("lity-opened").addClass("lity-closed"),c(k.add(j)).always(function(){k.trigger("lity:remove",[l]),j.remove(),j=void 0,a.resolve()}),a.promise()}},i=w(a,l,e.handlers,e.handler),j.attr(E,"false").addClass("lity-loading lity-opened lity-"+i.handler).appendTo("body").focus().on("click","[data-lity-close]",function(a){b(a.target).is("[data-lity-close]")&&l.close()}).trigger("lity:open",[l]),t(l),b.when(i.content).always(h)}function y(a,c,d){a.preventDefault?(a.preventDefault(),d=b(this),a=d.data("lity-target")||d.attr("href")||d.attr("src")):d=b(d);var e=new x(a,b.extend({},d.data("lity-options")||d.data("lity"),c),d,z.activeElement);if(!a.preventDefault)return e}var z=a.document,A=b(a),B=b.Deferred,C=b("html"),D=[],E="aria-hidden",F="lity-"+E,G='a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),iframe,object,embed,[contenteditable],[tabindex]:not([tabindex^="-"])',H={esc:!0,handler:null,handlers:{image:i,inline:j,youtube:k,vimeo:l,googlemaps:n,facebookvideo:m,iframe:o},template:'<div class="lity" role="dialog" aria-label="Dialog Window (Press escape to close)" tabindex="-1"><div class="lity-wrap" data-lity-close role="document"><div class="lity-loader" aria-hidden="true">Loading...</div><div class="lity-container"><div class="lity-content"></div><button class="lity-close" type="button" aria-label="Close (Press escape to close)" data-lity-close>×</button></div></div></div>'},I=/(^data:image\/)|(\.(png|jpe?g|gif|svg|webp|bmp|ico|tiff?)(\?\S*)?$)/i,J=/(youtube(-nocookie)?\.com|youtu\.be)\/(watch\?v=|v\/|u\/|embed\/?)?([\w-]{11})(.*)?/i,K=/(vimeo(pro)?.com)\/(?:[^\d]+)?(\d+)\??(.*)?$/,L=/((maps|www)\.)?google\.([^\/\?]+)\/?((maps\/?)?\?)(.*)/i,M=/(facebook\.com)\/([a-z0-9_-]*)\/videos\/([0-9]*)(.*)?$/i,N=function(){var a=z.createElement("div"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return b[c];return!1}();return i.test=function(a){return I.test(a)},y.version="2.4.1",y.options=b.proxy(d,y,H),y.handlers=b.proxy(d,y,H.handlers),y.current=v,b(z).on("click.lity","[data-lity]",y),y}); 3996// window.addEventListener("DOMContentLoaded", () => { 3997// let vh_hero = window.innerHeight * 0.01; 3998// document.documentElement.style.setProperty("--vh-hero", `${vh}px`); 3999// }); 4000// window.addEventListener("orientationchange", () => { 4001// setTimeout(() => { 4002// let vh_hero = window.innerHeight * 0.01; 4003// document.documentElement.style.setProperty("--vh-hero", `${vh}px`); 4004// }, 500); 4005// }); 4006 4007jQuery(document).ready(function ($) { 4008 /* init animations (https://github.com/michalsnik/aos/tree/v2) */ 4009 AOS.init(); 4010
4011 /* Open external links in a new tab (skip celtra.com and wpenginepowered.com) */ 4012 (function () { 4013 var internal = /(^|\.)(celtra\.com|wpenginepowered\.com)$/i; 4014 document.querySelectorAll('a[href]').forEach(function (a) { 4015 var href = a.getAttribute('href'); 4016 if (!href || /^(mailto:|tel:|javascript:|#)/i.test(href)) return; 4017 var url; 4018 try { url = new URL(a.href, window.location.href); } catch (e) { return; } 4019 if (url.protocol !== 'http:' && url.protocol !== 'https:') return; 4020 if (url.hostname === window.location.hostname || internal.test(url.hostname)) return; 4021 if (!a.hasAttribute('target')) a.setAttribute('target', '_blank'); 4022 var rel = (a.getAttribute('rel') || '').split(/\s+/).filter(Boolean); 4023 ['noopener', 'noreferrer'].forEach(function (r) { 4024 if (rel.indexOf(r) === -1) rel.push(r); 4025 }); 4026 a.setAttribute('rel', rel.join(' ')); 4027 }); 4028 })(); 4029 4030 /* animate in words in events hero */ 4031 if ($(".block-events-hero").length) { 4032 $(".text strong").each(function () { 4033 let strongElement = $(this); 4034 let text = strongElement.text(); 4035 let letters = text 4036 .split("") 4037 .map(char => `<span>${char}</span>`) 4038 .join(""); 4039 strongElement.html(letters); 4040 }); 4041 let isAnimating = false; 4042 let lastScrollTop = 0; 4043 $(window).on("scroll", function () { 4044 let currentScroll = $(this).scrollTop(); 4045 let scrollingDown = currentScroll > lastScrollTop; 4046 if (isAnimating) return; 4047 $(".text strong").each(function () { 4048 let strongElement = $(this); 4049 let rect = strongElement[0].getBoundingClientRect(); 4050 let triggerPoint = window.innerHeight - 300; 4051 let spans = strongElement.find("span"); 4052 if ( 4053 scrollingDown && 4054 rect.top < triggerPoint && 4055 !strongElement.hasClass("animated") 4056 ) { 4057 isAnimating = true; 4058 spans.each(function (index) { 4059 setTimeout(() => { 4060 $(this).addClass("active"); 4061 if (index === spans.length - 1) { 4062 setTimeout(() => { 4063 isAnimating = false; 4064 }, 200); 4065 } 4066 }, index * 50); 4067 }); 4068 strongElement.addClass("animated"); 4069 } else if (!scrollingDown && rect.top > triggerPoint) { 4070 spans.removeClass("active"); 4071 strongElement.removeClass("animated"); 4072 } 4073 }); 4074 lastScrollTop = currentScroll; 4075 }); 4076 } 4077 4078 /* fitvids (https://github.com/davatron5000/FitVids.js) */ 4079 $(".block-video, .post-content").fitVids(); 4080 4081 /* smooth scroll to resources */ 4082 if ($(".page-resources").length) { 4083 if (window.scrollY === 0) { 4084 const url = new URL(document.location); 4085 const params = new URLSearchParams(url.search); 4086 if (params.has("_resource_type")) { 4087 $("html, body").animate( 4088 { 4089 scrollTop: $("#show").offset().top - 150 4090 }, 4091 1000 4092 ); 4093 } 4094 } 4095 } 4096 4097 /* quote slider with continuous scroll */ 4098 if ($(".block-quote-slider").length) { 4099 let isMobile = window.matchMedia("(max-width: 767px)").matches; 4100 if (isMobile) { 4101 const cardsQuotes = $(".block-quote-slider .scrolling-content"); 4102 const scrollbarThumb = $( 4103 ".block-quote-slider .custom-scrollbar .scrollbar-thumb" 4104 ); 4105 const scrollbar = $(".block-quote-slider .custom-scrollbar"); 4106 function updateScrollbar() { 4107 const scrollLeft = cardsQuotes.scrollLeft(); 4108 const scrollWidth = cardsQuotes[0].scrollWidth; 4109 const clientWidth = cardsQuotes[0].clientWidth; 4110 const denominator = scrollWidth - clientWidth; 4111 const scrollPercentage = denominator > 0 ? scrollLeft / denominator : 0; 4112 const scrollbarWidth = scrollbar.width(); 4113 const thumbWidth = scrollbarThumb.width(); 4114 const newLeft = scrollPercentage * (scrollbarWidth - thumbWidth); 4115 scrollbarThumb.css("transform", `translateX(${newLeft}px)`); 4116 if (scrollLeft > 0) { 4117 $(cardsQuotes).parent(".quotes").addClass("shade-before"); 4118 } else { 4119 $(cardsQuotes).parent(".quotes").removeClass("shade-before"); 4120 } 4121 if (scrollLeft > 0 && scrollPercentage < 1) { 4122 $(cardsQuotes).parent(".quotes").addClass("shade-after"); 4123 } else { 4124 $(cardsQuotes).parent(".quotes").removeClass("shade-after"); 4125 } 4126 } 4127 function updateCardsScroll(event) { 4128 const scrollbarWidth = scrollbar.width(); 4129 const thumbWidth = scrollbarThumb.width(); 4130 const maxScrollLeft = 4131 cardsQuotes[0].scrollWidth - cardsQuotes[0].clientWidth; 4132 const newLeft = Math.min( 4133 Math.max(0, event.pageX - scrollbar.offset().left - thumbWidth / 2), 4134 scrollbarWidth - thumbWidth 4135 ); 4136 const scrollPercentage = newLeft / (scrollbarWidth - thumbWidth); 4137 const newScrollLeft = scrollPercentage * maxScrollLeft; 4138 cardsQuotes.scrollLeft(newScrollLeft); 4139 } 4140 cardsQuotes.on("scroll", updateScrollbar); 4141 let isDragging = false;
4142 scrollbarThumb.on("mousedown", function (event) { 4143 isDragging = true; 4144 $("body").addClass("scrollbar-dragging"); 4145 $(document).on("mousemove", updateCardsScroll); 4146 $(document).on("mouseup", function () { 4147 isDragging = false; 4148 $("body").removeClass("scrollbar-dragging"); 4149 $(document).off("mousemove", updateCardsScroll); 4150 }); 4151 }); 4152 $(window).on("resize", updateScrollbar); 4153 updateScrollbar(); 4154 } else { 4155 const quoteSlider = $(".block-quote-slider .scrolling-content"); 4156 const quoteCard = $(".block-quote-slider .card"); 4157 const quoteSliderContainer = $(".block-quote-slider .quotes"); 4158 4159 if (!quoteSlider.length || !quoteCard.length) return; 4160 4161 // Function to calculate and set container height 4162 function setContainerHeight() { 4163 let maxHeight = 0; 4164 quoteCard.each(function () { 4165 const cardHeight = $(this).outerHeight(); 4166 if (cardHeight > maxHeight) { 4167 maxHeight = cardHeight; 4168 } 4169 }); 4170 quoteSliderContainer.height(maxHeight); 4171 } 4172 4173 // Set height initially and after images load 4174 setContainerHeight(); 4175 $(window).on("load", setContainerHeight); 4176 $(window).on("resize", setContainerHeight); 4177 4178 quoteSlider.append(quoteSlider.html()); 4179 let scrollPosition = 0; 4180 const cardWidth = quoteCard.outerWidth(true); 4181 const totalWidth = cardWidth * quoteCard.length; 4182 const speed = 0.5; 4183 let isPaused = false; 4184 let isDragging = false; 4185 let startX, 4186 currentTranslate, 4187 previousTranslate = 0; 4188 function continuousScroll() { 4189 if (!isPaused && !isDragging) { 4190 scrollPosition += speed; 4191 if (scrollPosition >= totalWidth) { 4192 scrollPosition = 0; 4193 } 4194 quoteSlider.css("transform", `translateX(-${scrollPosition}px)`); 4195 } 4196 requestAnimationFrame(continuousScroll); 4197 } 4198 quoteSliderContainer.hover( 4199 function () { 4200 isPaused = true; 4201 }, 4202 function () { 4203 isPaused = false; 4204 } 4205 ); 4206 quoteSlider.on("mousedown touchstart", function (e) { 4207 isDragging = true; 4208 isPaused = true; 4209 startX = e.pageX || e.originalEvent.touches[0].pageX; 4210 previousTranslate = scrollPosition; 4211 }); 4212 quoteSlider.on("mousemove touchmove", function (e) { 4213 if (!isDragging) return; 4214 const currentX = e.pageX || e.originalEvent.touches[0].pageX; 4215 const deltaX = currentX - startX; 4216 scrollPosition = previousTranslate - deltaX; 4217 if (scrollPosition < 0) { 4218 scrollPosition += totalWidth; 4219 } else if (scrollPosition >= totalWidth) { 4220 scrollPosition -= totalWidth; 4221 } 4222 quoteSlider.css("transform", `translateX(-${scrollPosition}px)`); 4223 }); 4224 quoteSlider.on("mouseup touchend mouseleave", function () { 4225 isDragging = false; 4226 isPaused = false; 4227 }); 4228 quoteSlider.on("mousedown", function (e) { 4229 e.preventDefault(); 4230 }); 4231 quoteSlider.css({ 4232 display: "flex", 4233 width: `${cardWidth * quoteCard.length * 2}px`, 4234 cursor: "grab" 4235 }); 4236 continuousScroll(); 4237 } 4238 } 4239 4240 /* glide carousel */ 4241 if ($(".glide-carousel-nav").length) {
4242 $(".glide-carousel-nav li:first-child a").addClass("active"); 4243 } 4244 4245 /* glide swap */ 4246 if ($(".glide-swap").length) { 4247 const glideSwap = new Glide(".glide-swap", { 4248 type: "slider", 4249 perView: 4, 4250 focusAt: "center", 4251 peek: 0, 4252 rewind: false, 4253 animationDuration: 200, 4254 dragThreshold: 1, 4255 swipeThreshold: 1, 4256 bound: true, 4257 breakpoints: { 4258 768: { 4259 perView: 1, 4260 bound: true, 4261 peek: 40, 4262 animationDuration: 200 4263 }, 4264 960: { 4265 perView: 1, 4266 bound: true, 4267 peek: 180, 4268 animationDuration: 200 4269 } 4270 } 4271 }).mount(); 4272 4273 const slides = $(".glide__slide .card"); 4274 let desktopHoverTimeouts = []; 4275 let isMobileInitialized = false; 4276 let isDesktopInitialized = false; 4277 let observerTriggered = false; 4278 4279 function isDesktop() { 4280 return window.innerWidth >= 960; 4281 } 4282 4283 function isMobile() { 4284 return window.innerWidth < 960; 4285 } 4286 4287 function clearDesktopHoverEffects() { 4288 desktopHoverTimeouts.forEach(timeout => clearTimeout(timeout)); 4289 desktopHoverTimeouts = []; 4290 $(".cards-wrap").removeClass("active"); 4291 } 4292 4293 function initDesktopHoverEffects() { 4294 if (isDesktopInitialized) return; 4295 isDesktopInitialized = true; 4296 4297 clearDesktopHoverEffects(); 4298 const hoverEffectTimeout = setTimeout(() => { 4299 $(".cards-wrap").addClass("active"); 4300 let index = 0; 4301 4302 function showHoverEffect() { 4303 let currentSlide = slides.eq(index); 4304 currentSlide.find(".image-default").css({ 4305 opacity: 0, 4306 visibility: "hidden" 4307 }); 4308 currentSlide 4309 .find(".image-hover") 4310 .css({ 4311 opacity: 0, 4312 visibility: "visible", 4313 display: "block" 4314 }) 4315 .animate({ opacity: 1 }, 500); 4316 currentSlide 4317 .find(".image-default") 4318 .css({ 4319 opacity: 1, 4320 visibility: "hidden", 4321 display: "none" 4322 }) 4323 .animate({ opacity: 0 }, 500); 4324 4325 index++; 4326 if (index < slides.length) { 4327 const nextTimeout = setTimeout(showHoverEffect, 150); 4328 desktopHoverTimeouts.push(nextTimeout); 4329 } 4330 } 4331 4332 showHoverEffect(); 4333 }, 500); 4334 desktopHoverTimeouts.push(hoverEffectTimeout); 4335 4336 const resetEffectTimeout = setTimeout(() => { 4337 let index = 0; 4338 function resetHover() { 4339 let currentSlide = slides.eq(index); 4340 currentSlide.find(".image-hover").css({ 4341 opacity: 0, 4342 visibility: "hidden" 4343 }); 4344 currentSlide 4345 .find(".image-default") 4346 .css({ 4347 opacity: 0, 4348 visibility: "visible", 4349 display: "block" 4350 }) 4351 .animate({ opacity: 1 }, 500); 4352 currentSlide 4353 .find(".image-hover") 4354 .css({ 4355 opacity: 1, 4356 visibility: "hidden", 4357 display: "none" 4358 }) 4359 .animate({ opacity: 0 }, 500); 4360 4361 index++; 4362 if (index < slides.length) { 4363 const nextTimeout = setTimeout(resetHover, 150); 4364 desktopHoverTimeouts.push(nextTimeout); 4365 } else { 4366 $(".cards-wrap").removeClass("active"); 4367 } 4368 } 4369 resetHover(); 4370 }, 2500); 4371 desktopHoverTimeouts.push(resetEffectTimeout); 4372 } 4373 4374 function initMobileSlideHandler() { 4375 if (isMobileInitialized) return; 4376 isMobileInitialized = true; 4377 4378 setTimeout(() => { 4379 $(".glide__slide:first-child").addClass("glide__slide--fadein"); 4380 }, 400); 4381 4382 function handleSwapSlides() { 4383 glideSwap.on("move", function () { 4384 const currentIndex = glideSwap.index; 4385 setTimeout(() => { 4386 $(".glide__slide") 4387 .eq(currentIndex) 4388 .addClass("glide__slide--fadein"); 4389 }, 400); 4390 }); 4391 } 4392 handleSwapSlides(); 4393 $(window).off("resize", handleSwapSlides); 4394 $(window).on("resize", handleSwapSlides); 4395 } 4396 4397 function handleIntersection(entries, observer) {
4398 entries.forEach(entry => { 4399 if (entry.isIntersecting && !observerTriggered) { 4400 observerTriggered = true; 4401 if (isDesktop()) { 4402 initDesktopHoverEffects(); 4403 } else if (isMobile()) { 4404 initMobileSlideHandler(); 4405 } 4406 observer.disconnect(); 4407 } 4408 }); 4409 } 4410 4411 const observer = new IntersectionObserver(handleIntersection, { 4412 root: null, 4413 rootMargin: "100px", 4414 threshold: 0.1 4415 }); 4416 4417 observer.observe(document.querySelector(".glide-swap")); 4418 4419 $(window).on("resize", function () { 4420 if (observerTriggered) { 4421 if (isDesktop() && !isDesktopInitialized) { 4422 isMobileInitialized = false; 4423 clearDesktopHoverEffects(); 4424 initDesktopHoverEffects(); 4425 } else if (isMobile() && !isMobileInitialized) { 4426 clearDesktopHoverEffects(); 4427 isDesktopInitialized = false; 4428 initMobileSlideHandler(); 4429 } 4430 } 4431 }); 4432 } 4433 4434 /* glide case */ 4435 if ($(".glide-case").length) { 4436 const glideCase = new Glide(".glide-case", { 4437 type: "slider", 4438 perView: 4, 4439 focusAt: "center", 4440 peek: 0, 4441 rewind: false, 4442 animationDuration: 200, 4443 dragThreshold: 1, 4444 swipeThreshold: 1, 4445 bound: true, 4446 breakpoints: { 4447 768: { 4448 perView: 1, 4449 bound: true, 4450 peek: 1, 4451 animationDuration: 200 4452 }, 4453 960: { 4454 perView: 2, 4455 bound: true, 4456 peek: 1, 4457 animationDuration: 200 4458 } 4459 } 4460 }).mount(); 4461 function handleCaseSlides() { 4462 const isDesktop = window.innerWidth >= 960; 4463 glideCase.on("move", function () { 4464 const currentIndex = glideCase.index; 4465 $(".cards-wrap").toggleClass( 4466 "fade", 4467 currentIndex > 0 && currentIndex !== 3 4468 ); 4469 }); 4470 } 4471 handleCaseSlides(); 4472 $(window).on("resize", handleCaseSlides); 4473 } 4474 4475 /* glide stats */ 4476 if ($(".glide-stats").length) { 4477 const glideStats = new Glide(".glide-stats", { 4478 type: "slider", 4479 perView: 3, 4480 focusAt: "center", 4481 peek: 0, 4482 rewind: false, 4483 animationDuration: 200, 4484 dragThreshold: 1, 4485 swipeThreshold: 1, 4486 bound: true, 4487 breakpoints: { 4488 960: { 4489 perView: 1, 4490 bound: true, 4491 peek: 0, // Ensure no space appears on smaller screens 4492 animationDuration: 200 4493 } 4494 } 4495 }).mount(); 4496 function handleStatsSlides() { 4497 const isDesktop = window.innerWidth >= 960; 4498 glideStats.on("move", function () { 4499 const currentIndex = glideStats.index; 4500 $(".cards-wrap").toggleClass( 4501 "fade", 4502 currentIndex > 0 && currentIndex !== 3 4503 ); 4504 }); 4505 } 4506 handleStatsSlides(); 4507 $(window).on("resize", handleStatsSlides); 4508 } 4509 4510 /* block logos with continuous scroll */ 4511 if ($(".block-logos").length) { 4512 const logoSlider = $(".block-logos .scrolling-content"); 4513 const logoCards = $(".block-logos .logo"); 4514 const logoSliderContainer = $(".block-logos .logos"); 4515 4516 if (!logoSlider.length || !logoCards.length) return; 4517 4518 // duplicate content for continuous scroll 4519 logoSlider.append(logoSlider.html()); 4520 4521 let scrollPosition = 0; 4522 let isPaused = false; 4523 let isDragging = false; 4524 let startX, 4525 currentTranslate, 4526 previousTranslate = 0; 4527 4528 // calculate total width dynamically 4529 const totalWidth = logoCards.toArray().reduce((total, card) => { 4530 return total + $(card).outerWidth(true); 4531 }, 0); 4532 4533 // set dynamic width for the scrolling content 4534 logoSlider.css({ 4535 width: `${totalWidth * 2}px`, 4536 display: "flex", 4537 cursor: "grab" 4538 }); 4539 4540 // scroll function 4541 const speed = 0.5; // Adjust scroll speed 4542 function continuousScroll() { 4543 if (!isPaused && !isDragging) { 4544 scrollPosition += speed; 4545 if (scrollPosition >= totalWidth) { 4546 scrollPosition = 0; 4547 } 4548 logoSlider.css("transform", `translateX(-${scrollPosition}px)`); 4549 } 4550 requestAnimationFrame(continuousScroll); 4551 } 4552 4553 // hover to pause 4554 logoSliderContainer.hover( 4555 () => (isPaused = true), 4556 () => (isPaused = false) 4557 ); 4558 4559 // drag to scroll functionality 4560 logoSlider.on("mousedown touchstart", function (e) { 4561 isDragging = true; 4562 isPaused = true; 4563 startX = e.pageX || e.originalEvent.touches[0].pageX; 4564 previousTranslate = scrollPosition; 4565 }); 4566 4567 logoSlider.on("mousemove touchmove", function (e) { 4568 if (!isDragging) return; 4569 const currentX = e.pageX || e.originalEvent.touches[0].pageX; 4570 const deltaX = currentX - startX; 4571 scrollPosition = previousTranslate - deltaX; 4572 if (scrollPosition < 0) { 4573 scrollPosition += totalWidth; 4574 } else if (scrollPosition >= totalWidth) { 4575 scrollPosition -= totalWidth; 4576 } 4577 logoSlider.css("transform", `translateX(-${scrollPosition}px)`); 4578 }); 4579 4580 logoSlider.on("mouseup touchend mouseleave", function () { 4581 isDragging = false;
4582 isPaused = false; 4583 }); 4584 4585 // prevent default drag behavior 4586 logoSlider.on("mousedown", function (e) { 4587 e.preventDefault(); 4588 }); 4589 4590 // start the scroll 4591 continuousScroll(); 4592 } 4593 4594 /* glide carousel */ 4595 const glideCarousel = new Glide(".glide-carousel", { 4596 type: "slider", 4597 perView: 1, 4598 breakpoints: { 4599 767: { 4600 perView: 1, 4601 rewind: false 4602 } 4603 } 4604 }); 4605 $(".glide-carousel-nav a").on("click", function (e) { 4606 e.preventDefault(); 4607 $(this) 4608 .addClass("active") 4609 .parent("li") 4610 .siblings("li") 4611 .children("a") 4612 .removeClass("active"); 4613 const index = $(this).data("glide-load"); 4614 glideCarousel.go(`=${index}`); 4615 }); 4616 glideCarousel.on("run.after", () => { 4617 const activeIndex = glideCarousel.index; 4618 $(".glide-carousel-nav a") 4619 .removeClass("active") 4620 .eq(activeIndex) 4621 .addClass("active"); 4622 }); 4623 if ($(".glide-carousel").length) { 4624 glideCarousel.mount(); 4625 } 4626 4627 /* anchor to content */ 4628 if ( 4629 $(".cpt_solution-creative-automation").length || 4630 $(".cpt_solution-creative-enablement").length 4631 ) { 4632 const urlParams = new URLSearchParams(window.location.search); 4633 const sectionValue = urlParams.get("section"); 4634 4635 if (sectionValue && $("#" + sectionValue).length) { 4636 $(window).on("load", function () { 4637 $("html, body").animate( 4638 { scrollTop: $("#" + sectionValue).offset().top - 50 }, 4639 0 4640 ); 4641 }); 4642 } 4643 } 4644 4645 if ($("#services").length) { 4646 const urlParams = new URLSearchParams(window.location.search); 4647 const serviceValue = urlParams.get("service"); 4648 if (serviceValue) { 4649 if (serviceValue == "success-management") { 4650 glideCarousel.go("=0"); 4651 } else if (serviceValue == "technical-services") { 4652 glideCarousel.go("=1"); 4653 } else if (serviceValue == "consulting-training") { 4654 glideCarousel.go("=2"); 4655 } else if (serviceValue == "creative-services") { 4656 glideCarousel.go("=3"); 4657 } 4658 $("html, body").animate( 4659 { 4660 scrollTop: $("#services").offset().top - 400 4661 }, 4662 0 4663 ); 4664 } 4665 } 4666 4667 /* open content on block-list */ 4668 if ($(".block-list").length) { 4669 $(".block-list li").on("click", function (e) { 4670 if ($(this).hasClass("active")) { 4671 $(this).removeClass("active").children("main").slideUp(200, "swing"); 4672 } else { 4673 $(this).addClass("active").children("main").slideDown(200, "swing"); 4674 $(this) 4675 .siblings("li") 4676 .removeClass("active") 4677 .children("main") 4678 .slideUp(200, "swing"); 4679 } 4680 }); 4681 } 4682 4683 /* block-resources-filter */ 4684 $(".block-resources-filter .filter-title").on("click", function (e) { 4685 $(this).toggleClass("active").next(".filter-cats").toggle(); 4686 e.preventDefault(); 4687 }); 4688 $( 4689 ".block-resources-filter .open-filters, .block-collections-filter .open-filters" 4690 ).on("click", function (e) { 4691 $(this) 4692 .toggleClass("active") 4693 .parent("h2") 4694 .siblings(".filters-wrap") 4695 .toggleClass("active"); 4696 e.preventDefault(); 4697 }); 4698 $(".filters-wrap .view").on("click", function (e) { 4699 $(".filters-wrap, .block-resources-filter .open-filters").removeClass( 4700 "active" 4701 ); 4702 $("html, body").animate( 4703 { 4704 scrollTop: $("#show").offset().top - 150 4705 }, 4706 1000 4707 ); 4708 e.preventDefault(); 4709 }); 4710 4711 /* block-video */ 4712 if ($(".block-video").length) { 4713 $(".block-video .block-video-inner video").on("click", function (e) { 4714 var video = $(this).get(0); 4715 if (video.paused === false) { 4716 video.pause(); 4717 } else { 4718 video.play(); 4719 } 4720 return false; 4721 }); 4722 $(".block-video .play, .block-video video").on("click", function (e) { 4723 $(".block-video .play").fadeOut(); 4724 $(".block-video video").attr("controls", "controls"); 4725 var video = $(this).next("video").get(0); 4726 if (video.paused === false) { 4727 video.pause(); 4728 } else { 4729 video.play(); 4730 } 4731 return false; 4732 }); 4733 } 4734 4735 /* block-bento modal */ 4736 let vw = $(window).width(); 4737 function measureBentoModalHeight($box) { 4738 // Measure modal's natural content height while it's still hidden/inactive. 4739 var $modal = $box.find(".modal"); 4740 var $img = $box.find(".box-image"); 4741 var prev = { 4742 visibility: $modal[0].style.visibility, 4743 opacity: $modal[0].style.opacity, 4744 height: $modal[0].style.height, 4745 }; 4746 $modal.css({ visibility: "hidden", opacity: 0, height: "auto" }); 4747 var natural = $modal.outerHeight(); 4748 // Restore inline styles for animation; the caller sets final height after. 4749 $modal.css(prev); 4750 return Math.max(natural, $img.outerHeight() - 26); 4751 } 4752 function updateActiveBentoModals() { 4753 $(".block-bento .box.has-modal.active").each(function () { 4754 var $box = $(this); 4755 var $img = $box.find(".box-image"); 4756 var $modal = $box.find(".modal"); 4757 if (vw > 960) { 4758 // Briefly clear inline heights so we can re-measure natural sizes 4759 $modal.css("height", ""); 4760 $img.css("height", ""); 4761 var h = measureBentoModalHeight($box); 4762 $img.css("height", h); 4763 $modal.css("height", h - 30); 4764 } else { 4765 $modal.css("height", "auto"); 4766 $img.css("height", ""); 4767 } 4768 }); 4769 } 4770 var bentoResizeTimer; 4771 $(window).on("resize", function () { 4772 vw = $(window).width(); 4773 clearTimeout(bentoResizeTimer); 4774 bentoResizeTimer = setTimeout(updateActiveBentoModals, 100); 4775 }); 4776 $(".block-bento .box.has-modal").on("click", function (e) { 4777 if ( 4778 $(e.target).closest(".close-btn").length > 0 || 4779 $(e.target).closest(".modal a").length > 0 4780 ) 4781 return; 4782 var $box = $(this); 4783 var $img = $box.find(".box-image"); 4784 var $modal = $box.find(".modal"); 4785 if (vw > 960) { 4786 if (!$box.hasClass("active")) { 4787 var h = measureBentoModalHeight($box); 4788 $img.css("height", h); 4789 $modal.css("height", h - 30); 4790 $box.addClass("active"); 4791 } else { 4792 $box.removeClass("active"); 4793 $modal.css("height", 0); 4794 $img.css("height", ""); 4795 } 4796 } else { 4797 if (!$box.hasClass("active")) { 4798 $modal.css("height", "auto"); 4799 $box.addClass("active"); 4800 } else { 4801 $box.removeClass("active"); 4802 $modal.css("height", 0); 4803 } 4804 } 4805 }); 4806 $(".block-bento .modal .close-btn").on("click", function (e) { 4807 e.preventDefault(); 4808 var $box = $(this).closest(".box-box"); 4809 $box.removeClass("active"); 4810 $box.find(".box-image, .modal").css("height", ""); 4811 }); 4812 4813 /* block-stats info */ 4814 $(".block-stats .info").hover( 4815 function () { 4816 let position = $(this).position(); 4817 $(".block-stats .info-modal") 4818 .css("left", position.left - 150) 4819 .css("top", position.top - 180) 4820 .fadeIn(); 4821 }, 4822 function () { 4823 $(".info-modal").hide(); 4824 } 4825 ); 4826 4827 $(".block-stats .close").on("click", function (e) { 4828 $(this).parent(".info-modal").hide(); 4829 e.preventDefault(); 4830 }); 4831 4832 /* open menu */ 4833 $(".nav-open").on("click", function (e) { 4834 if ($(".mega").hasClass("active")) { 4835 $(".mega").removeClass("active"); 4836 $("body").removeClass("noscroll"); 4837 } else { 4838 $(".mega").addClass("active"); 4839 $("body").addClass("noscroll"); 4840 } 4841 e.preventDefault(); 4842 }); 4843 4844 /* close announcement */ 4845 $(".block-announcement .close").on("click", function (e) { 4846 $(".block-announcement").fadeOut(); 4847 e.preventDefault(); 4848 }); 4849 4850 /* set nav height on mobile */ 4851 function setVh() { 4852 const vh = window.innerHeight * 0.01; 4853 document.documentElement.style.setProperty("--vh", `${vh}px`); 4854 } 4855 setVh(); 4856 $(window).on("resize", function () { 4857 setVh(); 4858 }); 4859 4860 /* mega dropdown menu */ 4861 $(".mega > span").each(function () { 4862 const $span = $(this); 4863 const $megaDrop = $span.find(".mega-drop"); 4864 4865 // Desktop: hover behavior 4866 $span.on("mouseenter", function () { 4867 if (window.innerWidth >= 1259) { 4868 $span.addClass("nav-active"); 4869 $(".main").addClass("menu-open"); 4870 $span.attr("aria-expanded", "true"); 4871 $megaDrop.stop(true, true).delay(100).fadeIn(100); 4872 } 4873 }); 4874 $span.on("mouseleave", function () { 4875 if (window.innerWidth >= 1259) { 4876 $span.removeClass("nav-active"); 4877 $(".main").removeClass("menu-open"); 4878 $span.attr("aria-expanded", "false"); 4879 $megaDrop.stop(true, true).delay(100).fadeOut(500); 4880 } 4881 }); 4882 4883 // Mobile: click to toggle 4884 $span.on("click", function (e) { 4885 if (window.innerWidth < 1259) { 4886 // Check if click is on a link inside the dropdown 4887 var $clickedLink = $(e.target).is("a") 4888 ? $(e.target) 4889 : $(e.target).closest("a"); 4890 if ($clickedLink.length && $clickedLink.closest(".mega-drop").length) { 4891 // It's a link inside the dropdown - allow it to work normally 4892 return; 4893 } 4894 4895 e.preventDefault(); 4896 if ($span.hasClass("nav-active")) { 4897 $span.removeClass("nav-active"); 4898 $span.attr("aria-expanded", "false"); 4899 $megaDrop.slideUp(300); 4900 } else { 4901 // Close other open dropdowns 4902 $(".mega > span") 4903 .not($span) 4904 .removeClass("nav-active") 4905 .attr("aria-expanded", "false") 4906 .find(".mega-drop") 4907 .slideUp(300); 4908 $span.addClass("nav-active"); 4909 $span.attr("aria-expanded", "true"); 4910 $megaDrop.slideDown(300); 4911 // Scroll within .mega container to top of nav-active menu 4912 setTimeout(function () { 4913 var $mega = $(".mega"); 4914 var spanOffsetTop = $span.position().top; 4915 $mega.stop().animate( 4916 { 4917 scrollTop: $mega.scrollTop() + spanOffsetTop 4918 }, 4919 600 4920 ); 4921 }, 350); 4922 } 4923 } 4924 }); 4925 }); 4926 4927 /* mega dropdown menu */ 4928 $(".mega > span:not(.menu-signin):not(.menu-demo)").on( 4929 "mouseenter", 4930 function () { 4931 $(".main").addClass("shade"); 4932 } 4933 ); 4934 $(".mega > span:not(.menu-signin):not(.menu-demo)").on( 4935 "mouseleave", 4936 function () { 4937 $(".main").removeClass("shade"); 4938 } 4939 ); 4940 4941 /* block-accordion */ 4942 if ($(".accordion").length) { 4943 function setAccordionHeight(parentItem) {
4944 const answer = parentItem.find(".item-answer")[0]; 4945 if (answer) { 4946 const answerHeight = answer.scrollHeight; 4947 parentItem.find(".item-answer").css("max-height", `${answerHeight}px`); 4948 } 4949 } 4950 $(".item-question").on("click", function () { 4951 const parentItem = $(this).parent(".item"); 4952 if (parentItem.hasClass("accordion-active")) { 4953 parentItem.removeClass("accordion-active"); 4954 parentItem.find(".item-answer").css("max-height", "0"); 4955 } else { 4956 $(".item") 4957 .removeClass("accordion-active") 4958 .find(".item-answer") 4959 .css("max-height", "0"); 4960 parentItem.addClass("accordion-active"); 4961 setAccordionHeight(parentItem); 4962 } 4963 }); 4964 $(window).on("resize", function () { 4965 const activeItem = $(".item.accordion-active"); 4966 if (activeItem.length) { 4967 setAccordionHeight(activeItem); 4968 } 4969 }); 4970 } 4971 4972 /* block-toggle-legacy hotspot */ 4973 $(".hotspot-control").on("click", function () { 4974 if ($(this).parent(".hotspot").hasClass("active")) { 4975 $(this) 4976 .parent(".hotspot") 4977 .parent(".hotspots") 4978 .siblings("picture") 4979 .removeClass("shade"); 4980 } else { 4981 $(this) 4982 .parent(".hotspot") 4983 .parent(".hotspots") 4984 .siblings("picture") 4985 .addClass("shade"); 4986 } 4987 $(this).parent(".hotspot").toggleClass("active"); 4988 $(this).parent(".hotspot").siblings(".hotspot").removeClass("active"); 4989 $(this).children(".open").toggle(); 4990 $(this).children(".close").toggle(); 4991 const $hotspotText = $(this).closest(".hotspot").find(".hotspot-text"); 4992 $hotspotText.toggleClass("visible"); 4993 const textHeight = $hotspotText.outerHeight(); 4994 if ($(this).parent(".hotspot").hasClass("pos-top")) { 4995 $hotspotText.css("top", `-${textHeight}px`); 4996 } else if ( 4997 $(this).parent(".hotspot").hasClass("pos-left") || 4998 $(this).parent(".hotspot").hasClass("pos-right") 4999 ) { 5000 const controlHeight = $(this).outerHeight(); 5001 const verticalAlignTop = 5002 $(this).position().top + controlHeight / 2 - textHeight / 2; 5003 $hotspotText.css({ 5004 top: `${verticalAlignTop}px` 5005 }); 5006 } 5007 }); 5008 5009 /* block-toggle-legacy */ 5010 if ($(".block-toggle-legacy").length) { 5011 const updateBehaviorLegacy = function () { 5012 const isDesktop = window.innerWidth > 1208; 5013 if (isDesktop) { 5014 $(".block-toggle-legacy .item-text a").css("color", ""); 5015 $(".block-toggle-legacy .item-text p").css("display", ""); 5016 $(".block-toggle-legacy .item-text li") 5017 .off("mouseenter") 5018 .on("click", function () {
5019 const index = $(this).children("a").data("count"); 5020 const $item = $(this).closest(".item"); 5021 const $imageWraps = $item.find(".image-wrap"); 5022 const $targetImageWrap = $item.find(`.image-wrap.image-${index}`); 5023 if (!$targetImageWrap.hasClass("active")) { 5024 $imageWraps.stop(true, true).hide().removeClass("active"); 5025 $targetImageWrap.fadeIn().addClass("active"); 5026 $(this) 5027 .siblings() 5028 .removeClass("active") 5029 .children("p") 5030 .slideUp(200, "swing"); 5031 $(this).addClass("active"); 5032 $(this).children("p").slideDown(200, "swing"); 5033 } 5034 }); 5035 } else { 5036 $(".block-toggle-legacy .item-text li").off("mouseenter"); 5037 $(".block-toggle-legacy .item-text a") 5038 .off("click") 5039 .on("click", function (e) { 5040 e.preventDefault(); 5041 const $li = $(this).closest("li"); 5042 const $siblings = $li.siblings(); 5043 const $imageWraps = $li.closest(".item").find(".image-wrap"); 5044 const $p = $li.find("p"); 5045 const $hotspots = $li.find(".hotspots"); 5046 if ($li.hasClass("active")) { 5047 $li.removeClass("active"); 5048 $p.hide().removeClass("visible"); 5049 $hotspots.hide().removeClass("visible"); 5050 } else { 5051 $siblings 5052 .removeClass("active") 5053 .find("p, .hotspots") 5054 .hide() 5055 .removeClass("visible"); 5056 $imageWraps.hide().removeClass("active"); 5057 $li.addClass("active"); 5058 $p.show().addClass("visible"); 5059 $hotspots.show().addClass("visible"); 5060 $li 5061 .closest(".item") 5062 .find(".image-wrap:first-child") 5063 .show() 5064 .addClass("active"); 5065 $("html, body").animate( 5066 { scrollTop: $li.offset().top - 180 }, 5067 400 5068 ); 5069 } 5070 }); 5071 } 5072 }; 5073 updateBehaviorLegacy(); 5074 const $firstItem = $(".block-toggle-legacy .item:first-child"); 5075 const $firstLi = $firstItem.find("ul li:first-child"); 5076 $firstItem.addClass("active"); 5077 $firstLi.addClass("active").children("p").css("display", "block"); 5078 $firstItem 5079 .find(".item-image .image-wrap:first-child") 5080 .show() 5081 .addClass("active"); 5082 } 5083 5084 /* block-toggle */ 5085 if ($(".block-toggle").length) { 5086 const updateBehavior = function () { 5087 const isDesktop = window.innerWidth > 1208; 5088 if (isDesktop) { 5089 $(".block-toggle .item-text a").css("color", ""); 5090 $(".block-toggle .item-text p").css("display", ""); 5091 $(".block-toggle .item-text li") 5092 .off("mouseenter") 5093 .on("click", function () {
5094 const index = $(this).children("a").data("count"); 5095 const $item = $(this).closest(".item"); 5096 const $imageWraps = $item.find(".image-wrap"); 5097 const $targetImageWrap = $item.find(`.image-wrap.image-${index}`); 5098 if (!$targetImageWrap.hasClass("active")) { 5099 $imageWraps.stop(true, true).hide().removeClass("active"); 5100 $targetImageWrap.show().addClass("active"); 5101 $(this) 5102 .siblings() 5103 .removeClass("active") 5104 .children("p") 5105 .slideUp(200, "swing"); 5106 $(this).addClass("active"); 5107 $(this).children("p").slideDown(200, "swing"); 5108 } 5109 }); 5110 } else { 5111 $(".block-toggle .item-text li").off("mouseenter"); 5112 $(".block-toggle .item-text a") 5113 .off("click") 5114 .on("click", function (e) { 5115 e.preventDefault(); 5116 const $li = $(this).closest("li"); 5117 const $siblings = $li.siblings(); 5118 const $imageWraps = $li.closest(".item").find(".image-wrap"); 5119 const $p = $li.find("p"); 5120 const $hotspots = $li.find(".hotspots"); 5121 if ($li.hasClass("active")) { 5122 $li.removeClass("active"); 5123 $p.hide().removeClass("visible"); 5124 $hotspots.hide().removeClass("visible"); 5125 } else { 5126 $siblings 5127 .removeClass("active") 5128 .find("p, .hotspots") 5129 .hide() 5130 .removeClass("visible"); 5131 $imageWraps.hide().removeClass("active"); 5132 $li.addClass("active"); 5133 $p.show().addClass("visible"); 5134 $hotspots.show().addClass("visible"); 5135 $li 5136 .closest(".item") 5137 .find(".image-wrap:first-child") 5138 .show() 5139 .addClass("active"); 5140 $("html, body").animate( 5141 { scrollTop: $li.offset().top - 180 }, 5142 400 5143 ); 5144 } 5145 }); 5146 } 5147 } 5148 updateBehavior(); 5149 const $firstItem = $(".block-toggle .item:first-child"); 5150 const $firstLi = $firstItem.find("ul li:first-child"); 5151 $firstItem.addClass("active"); 5152 $firstLi.addClass("active").children("p").css("display", "block"); 5153 $firstItem 5154 .find(".item-image .image-wrap:first-child") 5155 .show() 5156 .addClass("active"); 5157 } 5158 5159 /* hero video: re-evaluate <source media> on viewport breakpoint change so the 5160 desktop/mobile variant swaps correctly when crossing 768px */ 5161 if ($(".block-hero video").length) { 5162 var heroVideoMq = window.matchMedia("(min-width: 768px)"); 5163 var swapHeroVideoSources = function () { 5164 $(".block-hero video").each(function () { 5165 var v = this; 5166 var t = v.currentTime; 5167 v.load(); 5168 v.addEventListener( 5169 "loadedmetadata", 5170 function () { 5171 try { v.currentTime = t; } catch (e) {} 5172 var p = v.play(); 5173 if (p && typeof p.catch === "function") p.catch(function () {}); 5174 }, 5175 { once: true } 5176 ); 5177 }); 5178 }; 5179 if (typeof heroVideoMq.addEventListener === "function") { 5180 heroVideoMq.addEventListener("change", swapHeroVideoSources); 5181 } else if (typeof heroVideoMq.addListener === "function") { 5182 heroVideoMq.addListener(swapHeroVideoSources); 5183 } 5184 } 5185 5186 /* smooth scroll anchor links â native scrollIntoView so scroll-margin-top is respected */ 5187 $('a[href*="#"]') 5188 .not("[data-lity]") 5189 .not('[href="#"]') 5190 .not(".toc-stick *") 5191 .not(".tours-nav a") 5192 .not('[href*="#toggle-"]') 5193 .on("click", function (e) { 5194 if ( 5195 location.pathname.replace(/^\//, "") !== 5196 this.pathname.replace(/^\//, "") || 5197 location.hostname !== this.hostname 5198 ) return; 5199 5200 var hash = this.hash.slice(1); 5201 if (!hash) return; 5202 5203 var target = 5204 document.getElementById(hash) || 5205 document.getElementsByName(hash)[0]; 5206 if (!target) return; 5207 5208 e.preventDefault(); 5209 target.scrollIntoView({ behavior: "smooth", block: "start" }); 5210 }); 5211 5212 /* table of contents on resources */ 5213 $('.toc-stick a[href*="#"]').on("click", function (e) { 5214 e.preventDefault(); 5215 if ( 5216 location.pathname.replace(/^\//, "") == 5217 this.pathname.replace(/^\//, "") && 5218 location.hostname == this.hostname 5219 ) { 5220 var target = $(this.hash); 5221 target = target.length ? target : $("[name=" + this.hash.slice(1) + "]"); 5222 if (target.length) { 5223 $("html, body").animate( 5224 { 5225 scrollTop: target.offset().top - 130 5226 }, 5227 1000 5228 ); 5229 return false;
5230 } 5231 } 5232 }); 5233 5234 /* turn off position sticky if it's too long */ 5235 if ($(".post-content").length) { 5236 const stickyHeight = $(".toc-stick").height(); 5237 const viewportHeight = window.innerHeight; 5238 if (stickyHeight > viewportHeight) { 5239 $(".toc-stick").css("position", "relative").css("top", "0"); 5240 } 5241 } 5242 5243 /* carousel toggle */ 5244 if ($(".block-carousel-toggle").length) { 5245 $(".block-carousel-toggle a").on("click", function (e) { 5246 let target = $(this).attr("href"); 5247 if (target == "#carousel-b") { 5248 $("#carousel-b").addClass("tab-active"); 5249 $("#carousel-a").hide(); 5250 } 5251 if (target == "#carousel-a") { 5252 $("#carousel-b").removeClass("tab-active"); 5253 $("#carousel-a").show(); 5254 } 5255 $(this).addClass("nav-active").siblings().removeClass("nav-active"); 5256 e.preventDefault(); 5257 }); 5258 } 5259 5260 /* custom scrollbar */ 5261 function setupCustomScrollbar( 5262 cardsSelector, 5263 scrollbarSelector, 5264 thumbSelector 5265 ) { 5266 const cards = $(cardsSelector); 5267 const scrollbarThumb = $(thumbSelector); 5268 const scrollbar = $(scrollbarSelector); 5269 function updateScrollbar() { 5270 const scrollLeft = cards.scrollLeft(); 5271 const scrollWidth = cards[0].scrollWidth; 5272 const clientWidth = cards[0].clientWidth; 5273 const denominator = scrollWidth - clientWidth; 5274 const scrollPercentage = denominator > 0 ? scrollLeft / denominator : 0; 5275 const scrollbarWidth = scrollbar.width(); 5276 const thumbWidth = scrollbarThumb.width(); 5277 const newLeft = scrollPercentage * (scrollbarWidth - thumbWidth); 5278 scrollbarThumb.css("transform", `translateX(${newLeft}px)`); 5279 if (scrollLeft > 0) { 5280 $(cards).parent(".cards-wrapper").addClass("shade-before"); 5281 } else { 5282 $(cards).parent(".cards-wrapper").removeClass("shade-before"); 5283 } 5284 if (scrollLeft > 0 && scrollPercentage < 1) { 5285 $(cards).parent(".cards-wrapper").addClass("shade-after"); 5286 } else { 5287 $(cards).parent(".cards-wrapper").removeClass("shade-after"); 5288 } 5289 } 5290 function updateCardsScroll(event) { 5291 const scrollbarWidth = scrollbar.width(); 5292 const thumbWidth = scrollbarThumb.width(); 5293 const maxScrollLeft = cards[0].scrollWidth - cards[0].clientWidth; 5294 const newLeft = Math.min( 5295 Math.max(0, event.pageX - scrollbar.offset().left - thumbWidth / 2), 5296 scrollbarWidth - thumbWidth 5297 ); 5298 const scrollPercentage = newLeft / (scrollbarWidth - thumbWidth); 5299 const newScrollLeft = scrollPercentage * maxScrollLeft; 5300 cards.scrollLeft(newScrollLeft); 5301 } 5302 cards.on("scroll", updateScrollbar); 5303 let isDragging = false; 5304 scrollbarThumb.on("mousedown", function (event) { 5305 isDragging = true; 5306 $("body").addClass("scrollbar-dragging"); 5307 $(document).on("mousemove", updateCardsScroll); 5308 $(document).on("mouseup", function () { 5309 isDragging = false; 5310 $("body").removeClass("scrollbar-dragging"); 5311 $(document).off("mousemove", updateCardsScroll); 5312 }); 5313 }); 5314 $(window).on("resize", updateScrollbar); 5315 updateScrollbar(); 5316 } 5317 5318 function setupCustomSpacing(block) {
5319 let containerPaddingLeft = 5320 parseInt($(block + " .container").css("padding-left"), 10) || 0; // Get padding-left and ensure it's a number 5321 let containerOffsetLeft = 5322 $(block + " .container").offset().left + containerPaddingLeft - 20; // Subtract 20px 5323 $(block + " .cards-wrapper .card-first").css( 5324 "flex-basis", 5325 containerOffsetLeft + "px" 5326 ); 5327 $(block + " .cards-wrapper").css("visibility", "visible"); 5328 } 5329 5330 if ($(".block-testimonials").length) { 5331 setupCustomSpacing(".block-testimonials"); 5332 setupCustomScrollbar( 5333 ".block-testimonials .cards", 5334 ".block-testimonials .custom-scrollbar", 5335 ".block-testimonials .custom-scrollbar .scrollbar-thumb" 5336 ); 5337 $(window).resize(function () { 5338 setupCustomSpacing(".block-testimonials"); 5339 }); 5340 } 5341 5342 if ($(".block-screens").length) { 5343 setupCustomSpacing(".block-screens"); 5344 setupCustomScrollbar( 5345 ".block-screens .cards", 5346 ".block-screens .custom-scrollbar", 5347 ".block-screens .custom-scrollbar .scrollbar-thumb" 5348 ); 5349 $(window).resize(function () { 5350 setupCustomSpacing(".block-screens"); 5351 }); 5352 5353 $(".block-screens .cards").each(function () { 5354 const cards = this; 5355 let isDown = false; 5356 let startX = 0; 5357 let startScroll = 0; 5358 let moved = 0; 5359 5360 cards.addEventListener("mousedown", function (e) { 5361 if (e.button !== 0) return; 5362 isDown = true; 5363 moved = 0; 5364 startX = e.pageX; 5365 startScroll = cards.scrollLeft; 5366 cards.classList.add("is-dragging"); 5367 }); 5368 5369 cards.addEventListener("mousemove", function (e) { 5370 if (!isDown) return; 5371 const dx = e.pageX - startX; 5372 moved = Math.max(moved, Math.abs(dx)); 5373 cards.scrollLeft = startScroll - dx; 5374 }); 5375 5376 const endDrag = function () { 5377 if (!isDown) return; 5378 isDown = false; 5379 cards.classList.remove("is-dragging"); 5380 if (moved > 5) { 5381 const suppress = function (e) { 5382 e.preventDefault(); 5383 e.stopPropagation(); 5384 cards.removeEventListener("click", suppress, true); 5385 }; 5386 cards.addEventListener("click", suppress, true); 5387 } 5388 }; 5389 5390 cards.addEventListener("mouseup", endDrag); 5391 cards.addEventListener("mouseleave", endDrag); 5392 }); 5393 } 5394 5395 if ($(".block-timeline").length) { 5396 setupCustomSpacing(".block-timeline"); 5397 setupCustomScrollbar( 5398 ".block-timeline .cards", 5399 ".block-timeline .custom-scrollbar", 5400 ".block-timeline .custom-scrollbar .scrollbar-thumb" 5401 ); 5402 $(window).resize(function () { 5403 setupCustomSpacing(".block-timeline"); 5404 }); 5405 } 5406 5407 if ($(".block-cards-resources").length) { 5408 setupCustomScrollbar( 5409 ".block-cards-resources .cards", 5410 ".block-cards-resources .custom-scrollbar", 5411 ".block-cards-resources .custom-scrollbar .scrollbar-thumb" 5412 ); 5413 } 5414 5415 if ($(".related").length) { 5416 setupCustomScrollbar( 5417 ".related .cards", 5418 ".related .custom-scrollbar", 5419 ".related .custom-scrollbar .scrollbar-thumb" 5420 ); 5421 } 5422 5423 if ($(".block-team").length) { 5424 setupCustomScrollbar( 5425 ".block-team .cards", 5426 ".block-team .custom-scrollbar", 5427 ".block-team .custom-scrollbar .scrollbar-thumb" 5428 ); 5429 } 5430 5431 if ($(".block-event-team").length) { 5432 setupCustomScrollbar( 5433 ".block-event-team .cards", 5434 ".block-event-team .custom-scrollbar", 5435 ".block-event-team .custom-scrollbar .scrollbar-thumb" 5436 ); 5437 } 5438 5439 if ($(".block-resources .cards-featured").length) { 5440 setupCustomScrollbar( 5441 ".block-resources .cards-featured", 5442 ".block-resources .custom-scrollbar", 5443 ".block-resources .custom-scrollbar .scrollbar-thumb" 5444 ); 5445 } 5446 5447 if ($(".block-cards-solutions .cards").length) { 5448 setupCustomScrollbar( 5449 ".block-cards-solutions .cards", 5450 ".block-cards-solutions .custom-scrollbar", 5451 ".block-cards-solutions .custom-scrollbar .scrollbar-thumb" 5452 ); 5453 } 5454 5455 if ($(".block-stats-slider .stats-slider").length) { 5456 setupCustomScrollbar( 5457 ".block-stats-slider .stats-slider", 5458 ".block-stats-slider .custom-scrollbar", 5459 ".block-stats-slider .custom-scrollbar .scrollbar-thumb" 5460 ); 5461 } 5462 5463 if ($(".block-events-highlights").length) { 5464 setupCustomScrollbar( 5465 ".block-events-highlights .cards", 5466 ".block-events-highlights .custom-scrollbar", 5467 ".block-events-highlights .custom-scrollbar .scrollbar-thumb" 5468 ); 5469 } 5470 5471 if ($(".event-register").length) { 5472 setupCustomScrollbar( 5473 ".event-register .cards", 5474 ".event-register .custom-scrollbar", 5475 ".event-register .custom-scrollbar .scrollbar-thumb" 5476 ); 5477 } 5478 5479 /* modal scrolling */ 5480 if ( 5481 $(".block-team").length || 5482 $(".block-collections").length || 5483 $(".block-event-schedule").length || 5484 $(".block-event-team").length || 5485 $(".page-cannes .block-hero").length 5486 ) { 5487 function updateModalHeight() {
5488 let vh = window.innerHeight * 0.01; 5489 $("html").css("--vh", `${vh}px`); 5490 } 5491 updateModalHeight(); 5492 $(window).on("resize orientationchange", function () { 5493 updateModalHeight(); 5494 }); 5495 $(document).on("lity:open", function () { 5496 $("body").css("overflow", "hidden"); 5497 }); 5498 5499 $(document).on("lity:close", function () { 5500 $("body").css("overflow", ""); 5501 }); 5502 } 5503 5504 // click gated pdf download link to trigger download 5505 if ($(".gated-form-thanks").length) { 5506 $(".gated-form-thanks a").get(0).click(); 5507 } 5508 5509 // add form-submitted on lity open (if form submitted) 5510 $(document).on("lity:open", function (event, instance) { 5511 var $content = $(instance.element()); 5512 setTimeout(function () { 5513 if ($content.find(".form-submitted").length) { 5514 $(".lity-wrap").addClass("form-submitted"); 5515 } else { 5516 $(".lity-wrap").removeClass("form-submitted"); 5517 } 5518 }, 50); 5519 }); 5520 5521 /* block-workflow */ 5522 if ($(".block-workflow").length) { 5523 var tourSrcMap = {}; 5524 $(".tour").each(function () { 5525 var tourId = $(this).attr("id"); 5526 var $iframe = $(this).find(".tour-wrap iframe"); 5527 if ($iframe.length) { 5528 tourSrcMap[tourId] = $iframe.attr("src"); 5529 } 5530 }); 5531 $(".tour").hide().first().css("display", "flex"); 5532 $(".tours-nav a").removeClass("active").first().addClass("active"); 5533 $(".tours-nav a").on("click", function (e) { 5534 e.preventDefault(); 5535 var targetId = $(this).attr("href").replace("#", ""); 5536 $(".tour").hide(); 5537 $(".tour").each(function () { 5538 var $tour = $(this); 5539 var tourId = $tour.attr("id"); 5540 if (tourId !== targetId) { 5541 var $iframe = $tour.find(".tour-wrap iframe"); 5542 var originalSrc = tourSrcMap[tourId]; 5543 if ($iframe.length && originalSrc) { 5544 var iframeProps = { 5545 src: originalSrc, 5546 title: $iframe.attr("title"), 5547 allow: $iframe.attr("allow"), 5548 loading: $iframe.attr("loading"), 5549 frameborder: 0, 5550 allowfullscreen: true, 5551 style: $iframe.attr("style") 5552 }; 5553 $iframe.remove(); 5554 var $iframeWrap = $tour.find(".tour-wrap").first(); 5555 setTimeout(function () { 5556 $iframeWrap.append($("<iframe>", iframeProps)); 5557 }, 20); 5558 } 5559 } 5560 }); 5561 $("#" + targetId).css("display", "flex"); 5562 $(".tours-nav a").removeClass("active"); 5563 $(this).addClass("active"); 5564 }); 5565 } 5566 5567 /* block-scrolly-panel */ 5568 if ($(".block-scrolly-panel").length) { 5569 var $panels = $(".block-scrolly-panel"); 5570 function checkPanels() { 5571 $panels.each(function () { 5572 var $panel = $(this); 5573 if ($panel.hasClass("is-visible")) return; 5574 var top = $panel.offset().top; 5575 var scrollTop = $(window).scrollTop(); 5576 if (scrollTop + 400 >= top) { 5577 $panel.addClass("is-visible"); 5578 } 5579 }); 5580 } 5581 $(window).on("scroll resize", checkPanels); 5582 checkPanels(); 5583 } 5584 5585 /* block-scrolly-boxes */ 5586 if ($(".block-scrolly-boxes").length) { 5587 $(".block-scrolly-boxes").each(function () { 5588 var $section = $(this); 5589 var $colB = $section.find(".block-scrolly-boxes-b"); 5590 var $timeline = $colB.find(".timeline"); 5591 var $fill = $timeline.find(".timeline-fill"); 5592 var $boxes = $colB.find(".box"); 5593 5594 var START_OFFSET = 300; 5595 var lastST = $(window).scrollTop(); 5596 5597 function clamp(n, min, max) { 5598 return Math.max(min, Math.min(max, n)); 5599 } 5600 function getCircleOffsetPx(el) { 5601 var v = getComputedStyle(el).getPropertyValue("--circle-offset").trim(); 5602 var px = parseFloat(v || "40"); 5603 return isNaN(px) ? 40 : px; 5604 } 5605 function update() { 5606 var scrollTop = $(window).scrollTop(); 5607 var winH = $(window).height(); 5608 var scrollingUp = scrollTop < lastST; 5609 5610 var colTop = $colB.offset().top; 5611 var measureLine = scrollTop + START_OFFSET; 5612 5613 var colH = $colB.outerHeight(true); 5614 var p = clamp((measureLine - colTop) / colH, 0, 1); 5615 5616 var trackH = $timeline.height(); 5617 var fillHeight = p * trackH; 5618 $fill.css("--tl-progress", p.toFixed(4)); 5619 5620 $boxes.each(function () { 5621 var $box = $(this); 5622 var circleOffset = getCircleOffsetPx(this); 5623 var circleY = $box.position().top + circleOffset; 5624 5625 if (fillHeight >= circleY) { 5626 $box.addClass("is-active"); 5627 } else if (scrollingUp) { 5628 $box.removeClass("is-active"); 5629 } 5630 }); 5631 lastST = scrollTop; 5632 } 5633 var ticking = false;
5634 function onScrollResize() { 5635 if (!ticking) { 5636 requestAnimationFrame(function () { 5637 update(); 5638 ticking = false; 5639 }); 5640 ticking = true; 5641 } 5642 } 5643 $(window).on("scroll resize", onScrollResize); 5644 update(); 5645 }); 5646 } 5647});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.