diff --git a/dist/scrolltosmooth.js b/dist/scrolltosmooth.js index 7cf647e..89985a0 100644 --- a/dist/scrolltosmooth.js +++ b/dist/scrolltosmooth.js @@ -1,11 +1,72 @@ /** * Vanilla JS Smooth Scroll * Author: Bastian Fießinger - * Version: 2.1.2 + * Version: 2.1.3 */ var scrollToSmooth = (function() { "use strict"; + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _slicedToArray(arr, i) { + return ( + _arrayWithHoles(arr) || + _iterableToArrayLimit(arr, i) || + _nonIterableRest() + ); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArrayLimit(arr, i) { + if ( + !( + Symbol.iterator in Object(arr) || + Object.prototype.toString.call(arr) === "[object Arguments]" + ) + ) { + return; + } + + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for ( + var _i = arr[Symbol.iterator](), _s; + !(_n = (_s = _i.next()).done); + _n = true + ) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + function linear(elapsed, initialValue, amountOfChange, duration) { return (amountOfChange * elapsed) / duration + initialValue; } @@ -450,450 +511,476 @@ var scrollToSmooth = (function() { easeInOutBounce: easeInOutBounce, }); - class scrollToSmooth { - constructor(nodes, settings) { - this.elements; - const d = document; - const w = window; - let scrollAnimationFrame; - - let _$ = s => d.querySelector(s); - - let _$$ = s => d.querySelectorAll(s); - /** - * Basic Helper function to check if an Element is an instance of Node - * - * @param {any} domNode either a dom node or querySelector - * - * @returns {boolean} either true or false - */ - - let isDomElement = domNode => { - if ( - domNode instanceof Node || - domNode instanceof NodeList || - domNode instanceof HTMLCollection - ) { - return true; + var scrollToSmooth = function scrollToSmooth(nodes, settings) { + var _this = this; + + _classCallCheck(this, scrollToSmooth); + + this.elements; + var d = document; + var w = window; + var scrollAnimationFrame; + + var _$ = function _$(s) { + return d.querySelector(s); + }; + + var _$$ = function _$$(s) { + return d.querySelectorAll(s); + }; + /** + * Basic Helper function to check if an Element is an instance of Node + * + * @param {any} domNode either a dom node or querySelector + * + * @returns {boolean} either true or false + */ + + var isDomElement = function isDomElement(domNode) { + if ( + domNode instanceof Node || + domNode instanceof NodeList || + domNode instanceof HTMLCollection + ) { + return true; + } + + return false; + }; + /** + * Check this.elements and declare them based on their value + */ + + if (isDomElement(nodes)) { + this.elements = nodes; + } else { + this.elements = _$$(nodes); + } + /** + * Check if a selector exists on the current page + * + * @param {selector} selector + * + * @returns {boolean} true if the selector exists + */ + + var validateSelector = function validateSelector(selector) { + var selectorValid = true; // Validate if the target is a valid selector + + try { + if (isDomElement(selector)) { + selector; + } else { + _$(selector); } + } catch (e) { + selectorValid = false; + } - return false; - }; - /** - * Check this.elements and declare them based on their value - */ + return selectorValid; + }; + /** + * Get the current Timestamp + */ + + var getTime = function getTime() { + return w.performance && "now" in w.performance + ? performance.now() + : new Date().getTime(); + }; + /** + * Determine element baseURI + * + * @param {HTMLElement} el + * + * @returns {string} + */ + + var getBaseURI = function getBaseURI(el) { + var sanitizeBaseURIRegex = new RegExp("(" + location.hash + ")?$"); + var elBaseURI = el.baseURI || document.URL; // Remove Trailing Slash and Hash Parameters from the baseURI + + var baseURI = elBaseURI.replace(sanitizeBaseURIRegex, ""); + return baseURI; + }; + /** + * Determine the target Element of a link + * + * @param {HTMLElement} el + * + * @returns {HTMLElement} targetSelector + */ + + var getTargetElement = function getTargetElement(el) { + var baseURI = getBaseURI(el); + var target = + _this.settings.targetAttribute === "href" + ? el.href.replace(baseURI, "") + : el.getAttribute(_this.settings.targetAttribute); // Top on Empty Hash + + if (_this.settings.topOnEmptyHash && target == "#") { + target = "body"; + } - if (isDomElement(nodes)) { - this.elements = nodes; - } else { - this.elements = _$$(nodes); + return target; + }; + /** + * Get document's height + * + * @returns {number} + */ + + var getDocHeight = function getDocHeight() { + return Math.max( + d.body.scrollHeight, + d.body.offsetHeight, + d.body.clientHeight, + d.documentElement.scrollHeight, + d.documentElement.offsetHeight, + d.documentElement.clientHeight + ); + }; + /** + * Build Default Settings Object + */ + + var defaults = { + targetAttribute: "href", + duration: 400, + durationRelative: false, + durationMin: null, + durationMax: null, + easing: "linear", + onScrollStart: null, + onScrollUpdate: null, + onScrollEnd: null, + fixedHeader: null, + topOnEmptyHash: true, + }; + /** + * Basic Helper Function to merge user defined settings with the defaults Object + * + * @param {object} args Arguments to check + * + * @returns {object} Merged Settings Object + */ + + var extendSettings = function extendSettings() { + var merged = {}; + + for ( + var _len = arguments.length, args = new Array(_len), _key = 0; + _key < _len; + _key++ + ) { + args[_key] = arguments[_key]; } - /** - * Check if a selector exists on the current page - * - * @param {selector} selector - * - * @returns {boolean} true if the selector exists - */ - - let validateSelector = selector => { - let selectorValid = true; // Validate if the target is a valid selector - - try { - if (isDomElement(selector)) { - selector; - } else { - _$(selector); + + Array.prototype.forEach.call(args, function(obj) { + for (var key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + return; } - } catch (e) { - selectorValid = false; - } - return selectorValid; - }; - /** - * Get the current Timestamp - */ - - let getTime = () => - w.performance && "now" in w.performance - ? performance.now() - : new Date().getTime(); - /** - * Determine element baseURI - * - * @param {HTMLElement} el - * - * @returns {string} - */ - - let getBaseURI = el => { - let sanitizeBaseURIRegex = new RegExp("(" + location.hash + ")?$"); - let elBaseURI = el.baseURI || document.URL; // Remove Trailing Slash and Hash Parameters from the baseURI - - let baseURI = elBaseURI.replace(sanitizeBaseURIRegex, ""); - return baseURI; - }; - /** - * Determine the target Element of a link - * - * @param {HTMLElement} el - * - * @returns {HTMLElement} targetSelector - */ - - let getTargetElement = el => { - let baseURI = getBaseURI(el); - let target = - this.settings.targetAttribute === "href" - ? el.href.replace(baseURI, "") - : el.getAttribute(this.settings.targetAttribute); // Top on Empty Hash - - if (this.settings.topOnEmptyHash && target == "#") { - target = "body"; + merged[key] = obj[key]; } - - return target; - }; - /** - * Get document's height - * - * @returns {number} - */ - - let getDocHeight = () => { - return Math.max( - d.body.scrollHeight, - d.body.offsetHeight, - d.body.clientHeight, - d.documentElement.scrollHeight, - d.documentElement.offsetHeight, - d.documentElement.clientHeight - ); - }; - /** - * Build Default Settings Object - */ - - const defaults = { - targetAttribute: "href", - duration: 400, - durationRelative: false, - durationMin: null, - durationMax: null, - easing: "linear", - onScrollStart: null, - onScrollUpdate: null, - onScrollEnd: null, - fixedHeader: null, - topOnEmptyHash: true, - }; - /** - * Basic Helper Function to merge user defined settings with the defaults Object - * - * @param {object} args Arguments to check - * - * @returns {object} Merged Settings Object - */ - - const extendSettings = (...args) => { - var merged = {}; - Array.prototype.forEach.call(args, obj => { - for (var key in obj) { - if (!Object.prototype.hasOwnProperty.call(obj, key)) { - return; - } - - merged[key] = obj[key]; + }); + return merged; + }; + /** + * Build the final Settings Object + */ + + this.settings = extendSettings(defaults, settings || {}); + /** + * Maximize Browser Support of requestAnimationFrame + */ + + var reqAnimFrame = + w.requestAnimationFrame || + w.mozRequestAnimationFrame || + w.webkitRequestAnimationFrame || + w.msRequestAnimationFrame; + var cancelAnimFrame = w.cancelAnimationFrame || w.mozCancelAnimationFrame; + /** + * Get all scrollto elements that have target attributes related to the current page + * + * @returns {array} Array with all links found + */ + + var linkCollector = function linkCollector() { + var links = []; + Array.prototype.forEach.call(_this.elements, function(el) { + var baseURI = getBaseURI(el); + var targetSelector = getTargetElement(el); // Check if the selector is found on the page + + if (validateSelector(targetSelector)) { + // Handle href attributes + if ( + _this.settings.targetAttribute === "href" && + el.href.indexOf(baseURI) != -1 && + el.href.indexOf("#") != -1 && + (el.hash != "" || _this.settings.topOnEmptyHash) + ) { + links.push(el); + } else if (_this.settings.targetAttribute !== "href") { + links.push(el); } - }); - return merged; - }; - /** - * Build the final Settings Object - */ - - this.settings = extendSettings(defaults, settings || {}); - /** - * Maximize Browser Support of requestAnimationFrame - */ - - const reqAnimFrame = - w.requestAnimationFrame || - w.mozRequestAnimationFrame || - w.webkitRequestAnimationFrame || - w.msRequestAnimationFrame; - const cancelAnimFrame = - w.cancelAnimationFrame || w.mozCancelAnimationFrame; - /** - * Get all scrollto elements that have target attributes related to the current page - * - * @returns {array} Array with all links found - */ - - const linkCollector = () => { - let links = []; - Array.prototype.forEach.call(this.elements, el => { - let baseURI = getBaseURI(el); - let targetSelector = getTargetElement(el); // Check if the selector is found on the page - - if (validateSelector(targetSelector)) { - // Handle href attributes - if ( - this.settings.targetAttribute === "href" && - el.href.indexOf(baseURI) != -1 && - el.href.indexOf("#") != -1 && - (el.hash != "" || this.settings.topOnEmptyHash) - ) { - links.push(el); - } else if (this.settings.targetAttribute !== "href") { - links.push(el); - } - } - }); - return links; - }; - /** - * Handler for the click event - * - * @param {object} e The current Event - * - * @returns {void} - */ - - const clickHandler = e => { - // Prevent Default Behaviour of how the browser would treat the click event - e.preventDefault(); - - let currentTarget = _$(getTargetElement(e.target)); - - if (!currentTarget || !validateSelector(currentTarget)) { - return; - } // Start Scrolling - - this.scrollTo(currentTarget); - }; - /** - * Animate scrolling - * - * @param {number} distFromTop Distance to be scrolled from top - * @param {number} startPos Distance from top when the animation has started - * @param {number} startTime The time in ms when the animation has started - * - * @returns {void} - */ - - const scrollToTarget = (distFromTop, startPos, startTime) => { - const now = getTime(); - const elapsed = now - startTime; - let duration = Math.max(1, this.settings.duration); - const distToScroll = distFromTop - startPos; - const scrollPx = distToScroll < 0 ? distToScroll * -1 : distToScroll; - - if (this.settings.durationRelative) { - let durationRelativePx = - typeof this.settings.durationRelative == "number" - ? this.settings.durationRelative - : 1000; - duration = Math.max( - this.settings.duration, - scrollPx * (duration / durationRelativePx) - ); - } // Set a minimum duration - - if (this.settings.durationMin && duration < this.settings.durationMin) { - duration = this.settings.durationMin; - } // Set a maximum duration - - if (this.settings.durationMax && duration > this.settings.durationMax) { - duration = this.settings.durationMax; } - - const timeFunction = Easings[this.settings.easing]( - elapsed, - startPos, - distToScroll, - duration + }); + return links; + }; + /** + * Handler for the click event + * + * @param {object} e The current Event + * + * @returns {void} + */ + + var clickHandler = function clickHandler(e) { + // Prevent Default Behaviour of how the browser would treat the click event + e.preventDefault(); + + var currentTarget = _$(getTargetElement(e.target)); + + if (!currentTarget || !validateSelector(currentTarget)) { + return; + } // Start Scrolling + + _this.scrollTo(currentTarget); + }; + /** + * Animate scrolling + * + * @param {number} distFromTop Distance to be scrolled from top + * @param {number} startPos Distance from top when the animation has started + * @param {number} startTime The time in ms when the animation has started + * + * @returns {void} + */ + + var scrollToTarget = function scrollToTarget( + distFromTop, + startPos, + startTime + ) { + var now = getTime(); + var elapsed = now - startTime; + var duration = Math.max(1, _this.settings.duration); + var distToScroll = distFromTop - startPos; + var scrollPx = distToScroll < 0 ? distToScroll * -1 : distToScroll; + + if (_this.settings.durationRelative) { + var durationRelativePx = + typeof _this.settings.durationRelative == "number" + ? _this.settings.durationRelative + : 1000; + duration = Math.max( + _this.settings.duration, + scrollPx * (duration / durationRelativePx) ); - let curScrollPosition = - window.pageYOffset || d.body.scrollTop || d.documentElement.scrollTop; // Callback onScrollUpdate + } // Set a minimum duration - if (this.settings.onScrollUpdate) { - this.settings.onScrollUpdate({ - startPosition: startPos, - currentPosition: curScrollPosition, - endPosition: distFromTop, - }); - } + if (_this.settings.durationMin && duration < _this.settings.durationMin) { + duration = _this.settings.durationMin; + } // Set a maximum duration - window.scroll(0, Math.ceil(timeFunction)); + if (_this.settings.durationMax && duration > _this.settings.durationMax) { + duration = _this.settings.durationMax; + } - if (elapsed > duration) { - // Callback onScrollEnd - if (this.settings.onScrollEnd) { - this.settings.onScrollEnd({ - startPosition: startPos, - endPosition: distFromTop, - }); - } // Stop when the element is reached + var timeFunction = Easings[_this.settings.easing]( + elapsed, + startPos, + distToScroll, + duration + ); - return; - } + var curScrollPosition = + window.pageYOffset || d.body.scrollTop || d.documentElement.scrollTop; // Callback onScrollUpdate - scrollAnimationFrame = reqAnimFrame(() => { - scrollToTarget(distFromTop, startPos, startTime); - }); - }; - /** - * Add and remove Events - * - * @param {string} action The current state - * @param {array} linksFiltered Array with all available Smooth Scroll Links - */ - - const handleEvents = (action, linksFiltered) => { - Array.prototype.forEach.call(linksFiltered, link => { - if (action == "add") { - link.addEventListener("click", clickHandler); - } else if (action == "remove") { - link.removeEventListener("click", clickHandler, false); - } + if (_this.settings.onScrollUpdate) { + _this.settings.onScrollUpdate({ + startPosition: startPos, + currentPosition: curScrollPosition, + endPosition: distFromTop, }); - }; - /** - * Bind Events - * - * @param {array} linksFiltered Array of anchor Elements - * - * @returns {void} - */ - - const BindEvents = linksFiltered => { - handleEvents("add", linksFiltered); // Cancel Animation on User Scroll Interaction - - let cancelAnimationOnEvents = ["mousewheel", "wheel", "touchstart"]; - cancelAnimationOnEvents.forEach(ev => { - window.addEventListener(ev, () => { - this.cancelScroll(); + } + + window.scroll(0, Math.ceil(timeFunction)); + + if (elapsed > duration) { + // Callback onScrollEnd + if (_this.settings.onScrollEnd) { + _this.settings.onScrollEnd({ + startPosition: startPos, + endPosition: distFromTop, }); - }); - }; - /** - * Remove Events - * - * @param {array} linksFiltered Array of anchor Elements - * - * @returns {void} - */ - - const RemoveEvents = linksFiltered => { - // Do nothing if the plugin is not already initialized - if (!this.settings) { - return; - } + } // Stop when the element is reached - handleEvents("remove", linksFiltered); - }; - /** - * Method: init - */ - - this.init = () => { - // Destroy any existing initialization - this.destroy(); // Bind Events - - BindEvents.call(this, linkCollector()); - }; - /** - * Method: destroy - */ - - this.destroy = () => { - // Remove Events - RemoveEvents.call(this, linkCollector()); - }; - /** - * Method: scrollTo - */ - - this.scrollTo = currentTarget => { - if (!currentTarget) { - return; - } // Do nothing if the selector is no Element of the DOM - - if (!validateSelector(currentTarget)) { - return; - } + return; + } - if (!isDomElement(currentTarget)) { - currentTarget = _$(currentTarget); + scrollAnimationFrame = reqAnimFrame(function() { + scrollToTarget(distFromTop, startPos, startTime); + }); + }; + /** + * Add and remove Events + * + * @param {string} action The current state + * @param {array} linksFiltered Array with all available Smooth Scroll Links + */ + + var handleEvents = function handleEvents(action, linksFiltered) { + Array.prototype.forEach.call(linksFiltered, function(link) { + if (action == "add") { + link.addEventListener("click", clickHandler); + } else if (action == "remove") { + link.removeEventListener("click", clickHandler, false); } + }); + }; + /** + * Bind Events + * + * @param {array} linksFiltered Array of anchor Elements + * + * @returns {void} + */ + + var BindEvents = function BindEvents(linksFiltered) { + handleEvents("add", linksFiltered); // Cancel Animation on User Scroll Interaction + + var cancelAnimationOnEvents = ["mousewheel", "wheel", "touchstart"]; + cancelAnimationOnEvents.forEach(function(ev) { + window.addEventListener(ev, function() { + _this.cancelScroll(); + }); + }); + }; + /** + * Remove Events + * + * @param {array} linksFiltered Array of anchor Elements + * + * @returns {void} + */ + + var RemoveEvents = function RemoveEvents(linksFiltered) { + // Do nothing if the plugin is not already initialized + if (!_this.settings) { + return; + } - const windowStartPos = - window.pageYOffset || d.body.scrollTop || d.documentElement.scrollTop; - const startTime = getTime(); - const docHeight = getDocHeight(); - const winHeight = - w.innerHeight || - d.documentElement.clientHeight || - d.getElementsByTagName("body")[0].clientHeight; - const targetOffset = currentTarget.offsetTop; - let distFromTop = Math.ceil( - docHeight - targetOffset < winHeight - ? docHeight - winHeight - : targetOffset - ); + handleEvents("remove", linksFiltered); + }; + /** + * Method: init + */ + + this.init = function() { + // Destroy any existing initialization + _this.destroy(); // Bind Events + + BindEvents.call(_this, linkCollector()); + }; + /** + * Method: destroy + */ + + this.destroy = function() { + // Remove Events + RemoveEvents.call(_this, linkCollector()); + }; + /** + * Method: scrollTo + */ + + this.scrollTo = function(currentTarget) { + if (!currentTarget) { + return; + } // Do nothing if the selector is no Element of the DOM + + if (!validateSelector(currentTarget)) { + return; + } - if (this.settings.fixedHeader !== null) { - const fixedHeader = _$(this.settings.fixedHeader); + if (!isDomElement(currentTarget)) { + currentTarget = _$(currentTarget); + } - if (fixedHeader.tagName) { - distFromTop -= Math.ceil( - fixedHeader.getBoundingClientRect().height - ); - } - } // Distance can't be negative + var windowStartPos = + window.pageYOffset || d.body.scrollTop || d.documentElement.scrollTop; + var startTime = getTime(); + var docHeight = getDocHeight(); + var winHeight = + w.innerHeight || + d.documentElement.clientHeight || + d.getElementsByTagName("body")[0].clientHeight; + var targetOffset = currentTarget.offsetTop; + var distFromTop = Math.ceil( + docHeight - targetOffset < winHeight + ? docHeight - winHeight + : targetOffset + ); - distFromTop = distFromTop < 0 ? 0 : distFromTop; // Callback onScrollStart + if (_this.settings.fixedHeader !== null) { + var fixedHeader = _$(_this.settings.fixedHeader); - if (this.settings.onScrollStart) { - this.settings.onScrollStart({ - startPosition: windowStartPos, - endPosition: distFromTop, - }); - } // Start Scroll Animation - - scrollToTarget(distFromTop, windowStartPos, startTime); - }; - /** - * Method: cancelScroll - */ - - this.cancelScroll = () => { - // Do nothing if no scroll Event has fired - if (!scrollAnimationFrame) { - return; + if (fixedHeader.tagName) { + distFromTop -= Math.ceil(fixedHeader.getBoundingClientRect().height); } + } // Distance can't be negative - cancelAnimFrame(scrollAnimationFrame); - }; - /** - * Method: update - * - * @param {object} obj The settings to be updated from the original instance - */ - - this.update = obj => { - if (!(obj instanceof Object)) { - return; - } + distFromTop = distFromTop < 0 ? 0 : distFromTop; // Callback onScrollStart - for (let [key, value] of Object.entries(obj)) { - this.settings[key] = value; - } - }; - } - } + if (_this.settings.onScrollStart) { + _this.settings.onScrollStart({ + startPosition: windowStartPos, + endPosition: distFromTop, + }); + } // Start Scroll Animation + + scrollToTarget(distFromTop, windowStartPos, startTime); + }; + /** + * Method: cancelScroll + */ + + this.cancelScroll = function() { + // Do nothing if no scroll Event has fired + if (!scrollAnimationFrame) { + return; + } + + cancelAnimFrame(scrollAnimationFrame); + }; + /** + * Method: update + * + * @param {object} obj The settings to be updated from the original instance + */ + + this.update = function(obj) { + if (!(obj instanceof Object)) { + return; + } + + for ( + var _i = 0, _Object$entries = Object.entries(obj); + _i < _Object$entries.length; + _i++ + ) { + var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), + key = _Object$entries$_i[0], + value = _Object$entries$_i[1]; + + _this.settings[key] = value; + } + }; + }; return scrollToSmooth; })(); diff --git a/dist/scrolltosmooth.min.js b/dist/scrolltosmooth.min.js index 1caaacb..3a52f74 100644 --- a/dist/scrolltosmooth.min.js +++ b/dist/scrolltosmooth.min.js @@ -1,6 +1,6 @@ /** * Vanilla JS Smooth Scroll * Author: Bastian Fießinger - * Version: 2.1.2 + * Version: 2.1.3 */ -var scrollToSmooth=function(){"use strict";function t(t,n,i,r){return i-e(r-t,0,i,r)+n}function e(t,e,n,i){return(t/=i)<1/2.75?n*(7.5625*t*t)+e:t<2/2.75?n*(7.5625*(t-=1.5/2.75)*t+.75)+e:t<2.5/2.75?n*(7.5625*(t-=2.25/2.75)*t+.9375)+e:n*(7.5625*(t-=2.625/2.75)*t+.984375)+e}var n=Object.freeze({__proto__:null,linear:function(t,e,n,i){return n*t/i+e},easeInQuad:function(t,e,n,i){return n*(t/=i)*t+e},easeOutQuad:function(t,e,n,i){return-n*(t/=i)*(t-2)+e},easeInOutQuad:function(t,e,n,i){return(t/=i/2)<1?n/2*t*t+e:-n/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,n,i){return n*(t/=i)*t*t+e},easeOutCubic:function(t,e,n,i){return n*((t=t/i-1)*t*t+1)+e},easeInOutCubic:function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t+e:n/2*((t-=2)*t*t+2)+e},easeInQuart:function(t,e,n,i){return n*(t/=i)*t*t*t+e},easeOutQuart:function(t,e,n,i){return-n*((t=t/i-1)*t*t*t-1)+e},easeInOutQuart:function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t*t+e:-n/2*((t-=2)*t*t*t-2)+e},easeInQuint:function(t,e,n,i){return n*(t/=i)*t*t*t*t+e},easeOutQuint:function(t,e,n,i){return n*((t=t/i-1)*t*t*t*t+1)+e},easeInOutQuint:function(t,e,n,i){return(t/=i/2)<1?n/2*t*t*t*t*t+e:n/2*((t-=2)*t*t*t*t+2)+e},easeInSine:function(t,e,n,i){return-n*Math.cos(t/i*(Math.PI/2))+n+e},easeOutSine:function(t,e,n,i){return n*Math.sin(t/i*(Math.PI/2))+e},easeInOutSine:function(t,e,n,i){return-n/2*(Math.cos(Math.PI*t/i)-1)+e},easeInExpo:function(t,e,n,i){return 0===t?e:n*Math.pow(2,10*(t/i-1))+e},easeOutExpo:function(t,e,n,i){return t===i?e+n:n*(1-Math.pow(2,-10*t/i))+e},easeInOutExpo:function(t,e,n,i){return 0===t?e:t===i?e+n:(t/=i/2)<1?n/2*Math.pow(2,10*(t-1))+e:n/2*(2-Math.pow(2,-10*--t))+e},easeInCirc:function(t,e,n,i){return-n*(Math.sqrt(1-(t/=i)*t)-1)+e},easeOutCirc:function(t,e,n,i){return n*Math.sqrt(1-(t=t/i-1)*t)+e},easeInOutCirc:function(t,e,n,i){return(t/=i/2)<1?-n/2*(Math.sqrt(1-t*t)-1)+e:n/2*(Math.sqrt(1-(t-=2)*t)+1)+e},easeInElastic:function(t,e,n,i){var r=1.70158,s=0,a=n;return 0===t?e:1==(t/=i)?e+n:(s||(s=.3*i),ai.querySelector(t),o=t=>t instanceof Node||t instanceof NodeList||t instanceof HTMLCollection;var u;o(t)?this.elements=t:this.elements=(u=t,i.querySelectorAll(u));let c=t=>{let e=!0;try{o(t)||a(t)}catch(t){e=!1}return e},l=()=>r.performance&&"now"in r.performance?performance.now():(new Date).getTime(),h=t=>{let e=new RegExp("("+location.hash+")?$");return(t.baseURI||document.URL).replace(e,"")},f=t=>{let e=h(t),n="href"===this.settings.targetAttribute?t.href.replace(e,""):t.getAttribute(this.settings.targetAttribute);return this.settings.topOnEmptyHash&&"#"==n&&(n="body"),n};this.settings=((...t)=>{var e={};return Array.prototype.forEach.call(t,t=>{for(var n in t){if(!Object.prototype.hasOwnProperty.call(t,n))return;e[n]=t[n]}}),e})({targetAttribute:"href",duration:400,durationRelative:!1,durationMin:null,durationMax:null,easing:"linear",onScrollStart:null,onScrollUpdate:null,onScrollEnd:null,fixedHeader:null,topOnEmptyHash:!0},e||{});const d=r.requestAnimationFrame||r.mozRequestAnimationFrame||r.webkitRequestAnimationFrame||r.msRequestAnimationFrame,g=r.cancelAnimationFrame||r.mozCancelAnimationFrame,m=()=>{let t=[];return Array.prototype.forEach.call(this.elements,e=>{let n=h(e),i=f(e);c(i)&&("href"!==this.settings.targetAttribute||-1==e.href.indexOf(n)||-1==e.href.indexOf("#")||""==e.hash&&!this.settings.topOnEmptyHash?"href"!==this.settings.targetAttribute&&t.push(e):t.push(e))}),t},M=t=>{t.preventDefault();let e=a(f(t.target));e&&c(e)&&this.scrollTo(e)},p=(t,e,r)=>{const a=l()-r;let o=Math.max(1,this.settings.duration);const u=t-e,c=u<0?-1*u:u;if(this.settings.durationRelative){let t="number"==typeof this.settings.durationRelative?this.settings.durationRelative:1e3;o=Math.max(this.settings.duration,c*(o/t))}this.settings.durationMin&&othis.settings.durationMax&&(o=this.settings.durationMax);const h=n[this.settings.easing](a,e,u,o);let f=window.pageYOffset||i.body.scrollTop||i.documentElement.scrollTop;this.settings.onScrollUpdate&&this.settings.onScrollUpdate({startPosition:e,currentPosition:f,endPosition:t}),window.scroll(0,Math.ceil(h)),a>o?this.settings.onScrollEnd&&this.settings.onScrollEnd({startPosition:e,endPosition:t}):s=d(()=>{p(t,e,r)})},O=(t,e)=>{Array.prototype.forEach.call(e,e=>{"add"==t?e.addEventListener("click",M):"remove"==t&&e.removeEventListener("click",M,!1)})},I=t=>{O("add",t);["mousewheel","wheel","touchstart"].forEach(t=>{window.addEventListener(t,()=>{this.cancelScroll()})})},E=t=>{this.settings&&O("remove",t)};this.init=()=>{this.destroy(),I.call(this,m())},this.destroy=()=>{E.call(this,m())},this.scrollTo=t=>{if(!t)return;if(!c(t))return;o(t)||(t=a(t));const e=window.pageYOffset||i.body.scrollTop||i.documentElement.scrollTop,n=l(),s=Math.max(i.body.scrollHeight,i.body.offsetHeight,i.body.clientHeight,i.documentElement.scrollHeight,i.documentElement.offsetHeight,i.documentElement.clientHeight),u=r.innerHeight||i.documentElement.clientHeight||i.getElementsByTagName("body")[0].clientHeight,h=t.offsetTop;let f=Math.ceil(s-h{s&&g(s)},this.update=t=>{if(t instanceof Object)for(let[e,n]of Object.entries(t))this.settings[e]=n}}}}(); +var scrollToSmooth=function(){"use strict";function t(t,n){return function(t){if(Array.isArray(t))return t}(t)||function(t,n){if(!(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t)))return;var e=[],r=!0,i=!1,o=void 0;try{for(var a,u=t[Symbol.iterator]();!(r=(a=u.next()).done)&&(e.push(a.value),!n||e.length!==n);r=!0);}catch(t){i=!0,o=t}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return e}(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function n(t,n,r,i){return r-e(i-t,0,r,i)+n}function e(t,n,e,r){return(t/=r)<1/2.75?e*(7.5625*t*t)+n:t<2/2.75?e*(7.5625*(t-=1.5/2.75)*t+.75)+n:t<2.5/2.75?e*(7.5625*(t-=2.25/2.75)*t+.9375)+n:e*(7.5625*(t-=2.625/2.75)*t+.984375)+n}var r=Object.freeze({__proto__:null,linear:function(t,n,e,r){return e*t/r+n},easeInQuad:function(t,n,e,r){return e*(t/=r)*t+n},easeOutQuad:function(t,n,e,r){return-e*(t/=r)*(t-2)+n},easeInOutQuad:function(t,n,e,r){return(t/=r/2)<1?e/2*t*t+n:-e/2*(--t*(t-2)-1)+n},easeInCubic:function(t,n,e,r){return e*(t/=r)*t*t+n},easeOutCubic:function(t,n,e,r){return e*((t=t/r-1)*t*t+1)+n},easeInOutCubic:function(t,n,e,r){return(t/=r/2)<1?e/2*t*t*t+n:e/2*((t-=2)*t*t+2)+n},easeInQuart:function(t,n,e,r){return e*(t/=r)*t*t*t+n},easeOutQuart:function(t,n,e,r){return-e*((t=t/r-1)*t*t*t-1)+n},easeInOutQuart:function(t,n,e,r){return(t/=r/2)<1?e/2*t*t*t*t+n:-e/2*((t-=2)*t*t*t-2)+n},easeInQuint:function(t,n,e,r){return e*(t/=r)*t*t*t*t+n},easeOutQuint:function(t,n,e,r){return e*((t=t/r-1)*t*t*t*t+1)+n},easeInOutQuint:function(t,n,e,r){return(t/=r/2)<1?e/2*t*t*t*t*t+n:e/2*((t-=2)*t*t*t*t+2)+n},easeInSine:function(t,n,e,r){return-e*Math.cos(t/r*(Math.PI/2))+e+n},easeOutSine:function(t,n,e,r){return e*Math.sin(t/r*(Math.PI/2))+n},easeInOutSine:function(t,n,e,r){return-e/2*(Math.cos(Math.PI*t/r)-1)+n},easeInExpo:function(t,n,e,r){return 0===t?n:e*Math.pow(2,10*(t/r-1))+n},easeOutExpo:function(t,n,e,r){return t===r?n+e:e*(1-Math.pow(2,-10*t/r))+n},easeInOutExpo:function(t,n,e,r){return 0===t?n:t===r?n+e:(t/=r/2)<1?e/2*Math.pow(2,10*(t-1))+n:e/2*(2-Math.pow(2,-10*--t))+n},easeInCirc:function(t,n,e,r){return-e*(Math.sqrt(1-(t/=r)*t)-1)+n},easeOutCirc:function(t,n,e,r){return e*Math.sqrt(1-(t=t/r-1)*t)+n},easeInOutCirc:function(t,n,e,r){return(t/=r/2)<1?-e/2*(Math.sqrt(1-t*t)-1)+n:e/2*(Math.sqrt(1-(t-=2)*t)+1)+n},easeInElastic:function(t,n,e,r){var i=1.70158,o=0,a=e;return 0===t?n:1==(t/=r)?n+e:(o||(o=.3*r),ao.settings.durationMax&&(c=o.settings.durationMax);var g=r[o.settings.easing](u,e,l,c),m=window.pageYOffset||s.body.scrollTop||s.documentElement.scrollTop;o.settings.onScrollUpdate&&o.settings.onScrollUpdate({startPosition:e,currentPosition:m,endPosition:n}),window.scroll(0,Math.ceil(g)),u>c?o.settings.onScrollEnd&&o.settings.onScrollEnd({startPosition:e,endPosition:n}):a=p((function(){t(n,e,i)}))}(m,n,e)}},this.cancelScroll=function(){a&&M(a)},this.update=function(n){if(n instanceof Object)for(var e=0,r=Object.entries(n);e