text: /*! @preserve sweet-scroll v3.0.1 - tsuyoshiwada | MIT License */
  (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define(factory) :
      (global.SweetScroll = factory());
  }(this, (function () { 'use strict';
  
      /*! *****************************************************************************
      Copyright (c) Microsoft Corporation. All rights reserved.
      Licensed under the Apache License, Version 2.0 (the "License"); you may not use
      this file except in compliance with the License. You may obtain a copy of the
      License at http://www.apache.org/licenses/LICENSE-2.0
  
      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
      MERCHANTABLITY OR NON-INFRINGEMENT.
  
      See the Apache Version 2.0 License for specific language governing permissions
      and limitations under the License.
      ***************************************************************************** */
  
      var __assign = Object.assign || function __assign(t) {
          for (var s, i = 1, n = arguments.length; i < n; i++) {
              s = arguments[i];
              for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
          }
          return t;
      };
  
      // @link https://github.com/JedWatson/exenv/blob/master/index.js
      var canUseDOM = !!(typeof window !== 'undefined' &&
          window.document &&
          window.document.createElement);
      var canUseHistory = !canUseDOM
          ? false
          : (window.history &&
              'pushState' in window.history &&
              window.location.protocol !== 'file:');
      var canUsePassiveOption = (function () {
          var support = false;
          if (!canUseDOM) {
              return support;
          }
          /* tslint:disable:no-empty */
          try {
              window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
                  get: function () {
                      support = true;
                  },
              }));
          }
          catch (e) { }
          /* tslint:enable */
          return support;
      })();
  
      var isString = function (obj) { return typeof obj === 'string'; };
      var isFunction = function (obj) { return typeof obj === 'function'; };
      var isArray = function (obj) { return Array.isArray(obj); };
      var isNumeric = function (obj) { return !isArray(obj) && ((obj - parseFloat(obj)) + 1) >= 0; };
      var isElement = function (obj) { return obj instanceof Element; };
      var hasProp = function (obj, key) { return (obj && obj.hasOwnProperty(key)); };
  
      var raf = canUseDOM ? window.requestAnimationFrame.bind(window) : null;
      var caf = canUseDOM ? window.cancelAnimationFrame.bind(window) : null;
  
      /* tslint:disable:curly */
      /* tslint:disable:no-conditional-assignment */
      var cos = Math.cos, sin = Math.sin, pow = Math.pow, sqrt = Math.sqrt, PI = Math.PI;
      var easings = {
          linear: function (p) { return p; },
          easeInQuad: function (_, t, b, c, d) { return (c * (t /= d) * t + b); },
          easeOutQuad: function (_, t, b, c, d) { return (-c * (t /= d) * (t - 2) + b); },
          easeInOutQuad: function (_, t, b, c, d) { return ((t /= d / 2) < 1 ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b); },
          easeInCubic: function (_, t, b, c, d) { return (c * (t /= d) * t * t + b); },
          easeOutCubic: function (_, t, b, c, d) { return (c * ((t = t / d - 1) * t * t + 1) + b); },
          easeInOutCubic: function (_, t, b, c, d) { return ((t /= d / 2) < 1 ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b); },
          easeInQuart: function (_, t, b, c, d) { return (c * (t /= d) * t * t * t + b); },
          easeOutQuart: function (_, t, b, c, d) { return (-c * ((t = t / d - 1) * t * t * t - 1) + b); },
          easeInOutQuart: function (_, t, b, c, d) { return ((t /= d / 2) < 1 ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b); },
          easeInQuint: function (_, t, b, c, d) { return (c * (t /= d) * t * t * t * t + b); },
          easeOutQuint: function (_, t, b, c, d) { return (c * ((t = t / d - 1) * t * t * t * t + 1) + b); },
          easeInOutQuint: function (_, t, b, c, d) { return ((t /= d / 2) < 1 ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b); },
          easeInSine: function (_, t, b, c, d) { return (-c * cos(t / d * (PI / 2)) + c + b); },
          easeOutSine: function (_, t, b, c, d) { return (c * sin(t / d * (PI / 2)) + b); },
          easeInOutSine: function (_, t, b, c, d) { return (-c / 2 * (cos(PI * t / d) - 1) + b); },
          easeInExpo: function (_, t, b, c, d) { return ((t === 0) ? b : c * pow(2, 10 * (t / d - 1)) + b); },
          easeOutExpo: function (_, t, b, c, d) { return ((t === d) ? b + c : c * (-pow(2, -10 * t / d) + 1) + b); },
          easeInOutExpo: function (_, t, b, c, d) {
              if (t === 0)
                  return b;
              if (t === d)
                  return b + c;
              if ((t /= d / 2) < 1)
                  return c / 2 * pow(2, 10 * (t - 1)) + b;
              return c / 2 * (-pow(2, -10 * --t) + 2) + b;
          },
          easeInCirc: function (_, t, b, c, d) { return (-c * (sqrt(1 - (t /= d) * t) - 1) + b); },
          easeOutCirc: function (_, t, b, c, d) { return (c * sqrt(1 - (t = t / d - 1) * t) + b); },
          easeInOutCirc: function (_, t, b, c, d) { return ((t /= d / 2) < 1 ? -c / 2 * (sqrt(1 - t * t) - 1) + b : c / 2 * (sqrt(1 - (t -= 2) * t) + 1) + b); },
      };
  
      var directionMethodMap = {
          y: 'scrollTop',
          x: 'scrollLeft',
      };
      var directionPropMap = {
          y: 'pageYOffset',
          x: 'pageXOffset',
      };
      var getScroll = function ($el, direction) { return ($el[directionMethodMap[direction]]); };
      var setScroll = function ($el, offset, direction) {
          $el[directionMethodMap[direction]] = offset;
      };
      var getOffset = function ($el, $context) {
          var rect = $el.getBoundingClientRect();
          if (rect.width || rect.height) {
              var scroll_1 = { top: 0, left: 0 };
              var $ctx = void 0;
              if (isRootContainer($context)) {
                  $ctx = document.documentElement;
                  scroll_1.top = window[directionPropMap.y];
                  scroll_1.left = window[directionPropMap.x];
              }
              else {
                  $ctx = $context;
                  var cRect = $ctx.getBoundingClientRect();
                  scroll_1.top = (cRect.top * -1) + $ctx[directionMethodMap.y];
                  scroll_1.left = (cRect.left * -1) + $ctx[directionMethodMap.x];
              }
              return {
                  top: (rect.top + scroll_1.top) - $ctx.clientTop,
                  left: (rect.left + scroll_1.left) - $ctx.clientLeft,
              };
          }
          return rect;
      };
  
      var $$ = function (selector) { return (Array.prototype.slice.call((!selector ? [] : document.querySelectorAll(selector)))); };
      var $ = function (selector) { return ($$(selector).shift() || null); };
      var matches = function ($el, selector) {
          if (isElement(selector)) {
              return $el === selector;
          }
          var results = $$(selector);
          var i = results.length;
          // tslint:disable-next-line no-empty
          while (--i >= 0 && results[i] !== $el) { }
          return i > -1;
      };
      var isRootContainer = function ($el) { return ($el === document.documentElement || $el === document.body); };
      var findScrollable = function (selectors, direction) {
          var method = directionMethodMap[direction];
          var $elements = isElement(selectors) ? [selectors] : $$(selectors);
          var $div = document.createElement('div');
          for (var i = 0; i < $elements.length; i += 1) {
              var $el = $elements[i];
              var $result = null;
              if ($el[method] > 0) {
                  $result = $el;
              }
              else {
                  var outerWidth_1 = window.outerWidth, innerWidth_1 = window.innerWidth;
                  var zoom = outerWidth_1 ? outerWidth_1 / innerWidth_1 : 1;
                  $div.style.width = $el.clientWidth + 1 + "px";
                  $div.style.height = $el.clientHeight + 1 + "px";
                  $el.appendChild($div);
                  $el[method] = Math.max(1, 1.5 / zoom);
                  if ($el[method] > 0) {
                      $result = $el;
                  }
                  $el[method] = 0;
                  $el.removeChild($div);
              }
              if ($result) {
                  return $result;
              }
          }
          return null;
      };
  
      var getHeight = function ($el) { return (Math.max($el.scrollHeight, $el.clientHeight, $el.offsetHeight)); };
      var getWidth = function ($el) { return (Math.max($el.scrollWidth, $el.clientWidth, $el.offsetWidth)); };
      var getSize = function ($el) { return ({
          width: getWidth($el),
          height: getHeight($el),
      }); };
      var getViewportAndElementSizes = function ($el) {
          var isRoot = isRootContainer($el);
          return {
              viewport: {
                  width: isRoot
                      ? Math.min(window.innerWidth, document.documentElement.clientWidth)
                      : $el.clientWidth,
                  height: isRoot ? window.innerHeight : $el.clientHeight,
              },
              size: isRoot
                  ? {
                      width: Math.max(getWidth(document.body), getWidth(document.documentElement)),
                      height: Math.max(getHeight(document.body), getHeight(document.documentElement)),
                  }
                  : getSize($el),
          };
      };
  
      var wheelEventName = (function () {
          if (!canUseDOM) {
              return 'wheel';
          }
          return 'onwheel' in document ? 'wheel' : 'mousewheel';
      })();
      var eventName = function (name) { return (name === 'wheel' ? wheelEventName : name); };
      var apply = function ($el, method, event, listener, passive) {
          event.split(' ').forEach(function (name) {
              $el[method](eventName(name), listener, canUsePassiveOption ? { passive: passive } : false);
          });
      };
      var addEvent = function ($el, event, listener, passive) {
          apply($el, 'addEventListener', event, listener, passive);
      };
      var removeEvent = function ($el, event, listener, passive) {
          apply($el, 'removeEventListener', event, listener, passive);
      };
  
      var reRelativeToken = /^(\+|-)=(\d+(?:\.\d+)?)$/;
      var parseCoordinate = function (coordinate, enableVertical) {
          var res = { top: 0, left: 0, relative: false };
          // Object ({ top: {n}, left: {n} })
          if (hasProp(coordinate, 'top') || hasProp(coordinate, 'left')) {
              res = __assign({}, res, coordinate);
              // Array ([{n}, [{n}])
          }
          else if (isArray(coordinate)) {
              if (coordinate.length > 1) {
                  res.top = coordinate[0];
                  res.left = coordinate[1];
              }
              else if (coordinate.length === 1) {
                  res.top = enableVertical ? coordinate[0] : 0;
                  res.left = !enableVertical ? coordinate[0] : 0;
              }
              else {
                  return null;
              }
              // Number
          }
          else if (isNumeric(coordinate)) {
              if (enableVertical) {
                  res.top = coordinate;
              }
              else {
                  res.left = coordinate;
              }
              // String ('+={n}', '-={n}')
          }
          else if (isString(coordinate)) {
              var m = coordinate.trim().match(reRelativeToken);
              if (!m) {
                  return null;
              }
              var op = m[1];
              var val = parseInt(m[2], 10);
              if (op === '+') {
                  res.top = enableVertical ? val : 0;
                  res.left = !enableVertical ? val : 0;
              }
              else {
                  res.top = enableVertical ? -val : 0;
                  res.left = !enableVertical ? -val : 0;
              }
              res.relative = true;
          }
          else {
              return null;
          }
          return res;
      };
  
      var defaultOptions = {
          trigger: '[data-scroll]',
          header: '[data-scroll-header]',
          duration: 1000,
          easing: 'easeOutQuint',
          offset: 0,
          vertical: true,
          horizontal: false,
          cancellable: true,
          updateURL: false,
          preventDefault: true,
          stopPropagation: true,
          quickMode: false,
          // Callbacks
          before: null,
          after: null,
          cancel: null,
          complete: null,
          step: null,
      };
  
      var CONTAINER_CLICK_EVENT = 'click';
      var CONTAINER_STOP_EVENT = 'wheel touchstart touchmove';
      var SweetScroll = /** @class */ (function () {
          /**
           * Constructor
           */
          function SweetScroll(options, container) {
              var _this = this;
              this.ctx = {
                  $trigger: null,
                  opts: null,
                  progress: false,
                  pos: null,
                  startPos: null,
                  easing: null,
                  start: 0,
                  id: 0,
                  cancel: false,
                  hash: null,
              };
              /**
               * Handle each frame of the animation.
               */
              this.loop = function (time) {
                  var _a = _this, $el = _a.$el, ctx = _a.ctx;
                  if (!ctx.start) {
                      ctx.start = time;
                  }
                  if (!ctx.progress || !$el) {
                      _this.stop();
                      return;
                  }
                  var options = ctx.opts;
                  var offset = ctx.pos;
                  var start = ctx.start;
                  var startOffset = ctx.startPos;
                  var easing = ctx.easing;
                  var duration = options.duration;
                  var directionMap = { top: 'y', left: 'x' };
                  var timeElapsed = time - start;
                  var t = Math.min(1, Math.max(timeElapsed / duration, 0));
                  Object.keys(offset).forEach(function (key) {
                      var value = offset[key];
                      var initial = startOffset[key];
                      var delta = value - initial;
                      if (delta !== 0) {
                          var val = easing(t, duration * t, 0, 1, duration);
                          setScroll($el, Math.round(initial + delta * val), directionMap[key]);
                      }
                  });
                  if (timeElapsed <= duration) {
                      _this.hook(options, 'step', t);
                      ctx.id = SweetScroll.raf(_this.loop);
                  }
                  else {
                      _this.stop(true);
                  }
              };
              /**
               * Handling of container click event.
               */
              this.handleClick = function (e) {
                  var opts = _this.opts;
                  var $el = e.target;
                  for (; $el && $el !== document; $el = $el.parentNode) {
                      if (!matches($el, opts.trigger)) {
                          continue;
                      }
                      var dataOptions = JSON.parse($el.getAttribute('data-scroll-options') || '{}');
                      var data = $el.getAttribute('data-scroll');
                      var to = data || $el.getAttribute('href');
                      var options = __assign({}, opts, dataOptions);
                      var preventDefault = options.preventDefault, stopPropagation = options.stopPropagation, vertical = options.vertical, horizontal = options.horizontal;
                      if (preventDefault) {
                          e.preventDefault();
                      }
                      if (stopPropagation) {
                          e.stopPropagation();
                      }
                      // Passes the trigger element to callback
                      _this.ctx.$trigger = $el;
                      if (horizontal && vertical) {
                          _this.to(to, options);
                      }
                      else if (vertical) {
                          _this.toTop(to, options);
                      }
                      else if (horizontal) {
                          _this.toLeft(to, options);
                      }
                  }
              };
              /**
               * Handling of container stop events.
               */
              this.handleStop = function (e) {
                  var ctx = _this.ctx;
                  var opts = ctx.opts;
                  if (opts && opts.cancellable) {
                      ctx.cancel = true;
                      _this.stop();
                  }
                  else {
                      e.preventDefault();
                  }
              };
              var opts = __assign({}, defaultOptions, (options || {}));
              var vertical = opts.vertical, horizontal = opts.horizontal;
              var selector = container === undefined ? 'body,html' : container;
              var $container = null;
              if (canUseDOM) {
                  if (vertical) {
                      $container = findScrollable(selector, 'y');
                  }
                  if (!$container && horizontal) {
                      $container = findScrollable(selector, 'x');
                  }
              }
              if ($container) {
                  this.opts = opts;
                  this.$el = $container;
                  this.bind(true, false);
              }
          }
          /**
           * SweetScroll instance factory.
           */
          SweetScroll.create = function (options, container) {
              return new SweetScroll(options, container);
          };
          /**
           * Scroll animation to the specified position.
           */
          SweetScroll.prototype.to = function (distance, options) {
              if (!canUseDOM) {
                  return;
              }
              var _a = this, $el = _a.$el, ctx = _a.ctx, currentOptions = _a.opts;
              var $trigger = ctx.$trigger;
              var opts = __assign({}, currentOptions, options || {});
              var optOffset = opts.offset, vertical = opts.vertical, horizontal = opts.horizontal;
              var $header = isElement(opts.header) ? opts.header : $(opts.header);
              var hash = isString(distance) && /^#/.test(distance) ? distance : null;
              ctx.opts = opts; // Temporary options
              ctx.cancel = false; // Disable the call flag of `cancel`
              ctx.hash = hash;
              // Stop current animation
              this.stop();
              // Does not move if the container is not found
              if (!$el) {
                  return;
              }
              // Get scroll offset
              var offset = parseCoordinate(optOffset, vertical);
              var coordinate = parseCoordinate(distance, vertical);
              var scroll = { top: 0, left: 0 };
              if (coordinate) {
                  if (coordinate.relative) {
                      var current = getScroll($el, vertical ? 'y' : 'x');
                      scroll.top = vertical ? current + coordinate.top : coordinate.top;
                      scroll.left = !vertical ? current + coordinate.left : coordinate.left;
                  }
                  else {
                      scroll = coordinate;
                  }
              }
              else if (isString(distance) && distance !== '#') {
                  var $target = $(distance);
                  if (!$target) {
                      return;
                  }
                  scroll = getOffset($target, $el);
              }
              if (offset) {
                  scroll.top += offset.top;
                  scroll.left += offset.left;
              }
              if ($header) {
                  scroll.top = Math.max(0, scroll.top - getSize($header).height);
              }
              // Normalize scroll offset
              var _b = getViewportAndElementSizes($el), viewport = _b.viewport, size = _b.size;
              scroll.top = vertical
                  ? Math.max(0, Math.min(size.height - viewport.height, scroll.top))
                  : getScroll($el, 'y');
              scroll.left = horizontal
                  ? Math.max(0, Math.min(size.width - viewport.width, scroll.left))
                  : getScroll($el, 'x');
              // Call `before`
              // Stop scrolling when it returns false
              if (this.hook(opts, 'before', scroll, $trigger) === false) {
                  ctx.opts = null;
                  return;
              }
              // Set offset
              ctx.pos = scroll;
              // Run animation!!
              this.start(opts);
              // Bind stop events
              this.bind(false, true);
          };
          /**
           * Scroll animation to specified left position.
           */
          SweetScroll.prototype.toTop = function (distance, options) {
              this.to(distance, __assign({}, options || {}, { vertical: true, horizontal: false }));
          };
          /**
           * Scroll animation to specified top position.
           */
          SweetScroll.prototype.toLeft = function (distance, options) {
              this.to(distance, __assign({}, options || {}, { vertical: false, horizontal: true }));
          };
          /**
           * Scroll animation to specified element.
           */
          SweetScroll.prototype.toElement = function ($element, options) {
              var $el = this.$el;
              if (!canUseDOM || !$el) {
                  return;
              }
              this.to(getOffset($element, $el), options || {});
          };
          /**
           * Stop the current scroll animation.
           */
          SweetScroll.prototype.stop = function (gotoEnd) {
              if (gotoEnd === void 0) { gotoEnd = false; }
              var _a = this, $el = _a.$el, ctx = _a.ctx;
              var pos = ctx.pos;
              if (!$el || !ctx.progress) {
                  return;
              }
              SweetScroll.caf(ctx.id);
              ctx.progress = false;
              ctx.start = 0;
              ctx.id = 0;
              if (gotoEnd && pos) {
                  setScroll($el, pos.left, 'x');
                  setScroll($el, pos.top, 'y');
              }
              this.complete();
          };
          /**
           * Update options.
           */
          SweetScroll.prototype.update = function (options) {
              if (this.$el) {
                  var opts = __assign({}, this.opts, options);
                  this.stop();
                  this.unbind(true, true);
                  this.opts = opts;
                  this.bind(true, false);
              }
          };
          /**
           * Destroy instance.
           */
          SweetScroll.prototype.destroy = function () {
              if (this.$el) {
                  this.stop();
                  this.unbind(true, true);
                  this.$el = null;
              }
          };
          /**
           * Callback methods.
           */
          /* tslint:disable:no-empty */
          SweetScroll.prototype.onBefore = function (_, __) { return true; };
          SweetScroll.prototype.onStep = function (_) { };
          SweetScroll.prototype.onAfter = function (_, __) { };
          SweetScroll.prototype.onCancel = function () { };
          SweetScroll.prototype.onComplete = function (_) { };
          /* tslint:enable */
          /**
           * Start scrolling animation.
           */
          SweetScroll.prototype.start = function (opts) {
              var ctx = this.ctx;
              ctx.opts = opts;
              ctx.progress = true;
              ctx.easing = isFunction(opts.easing)
                  ? opts.easing
                  : easings[opts.easing];
              // Update start offset.
              var $container = this.$el;
              var offset = ctx.pos;
              var start = {
                  top: getScroll($container, 'y'),
                  left: getScroll($container, 'x'),
              };
              if (opts.quickMode) {
                  var _a = getViewportAndElementSizes($container).viewport, width = _a.width, height = _a.height;
                  if (Math.abs(start.top - offset.top) > height) {
                      start.top = start.top > offset.top ? offset.top + height : offset.top - height;
                  }
                  if (Math.abs(start.left - offset.left) > width) {
                      start.left = start.left > offset.left ? offset.left + width : offset.left - width;
                  }
              }
              ctx.startPos = start;
              // Loop
              ctx.id = SweetScroll.raf(this.loop);
          };
          /**
           * Handle the completion of scrolling animation.
           */
          SweetScroll.prototype.complete = function () {
              var _a = this, $el = _a.$el, ctx = _a.ctx;
              var hash = ctx.hash, cancel = ctx.cancel, opts = ctx.opts, pos = ctx.pos, $trigger = ctx.$trigger;
              if (!$el || !opts) {
                  return;
              }
              if (hash != null && hash !== window.location.hash) {
                  var updateURL = opts.updateURL;
                  if (canUseDOM && canUseHistory && updateURL !== false) {
                      window.history[updateURL === 'replace' ? 'replaceState' : 'pushState'](null, '', hash);
                  }
              }
              this.unbind(false, true);
              ctx.opts = null;
              ctx.$trigger = null;
              if (cancel) {
                  this.hook(opts, 'cancel');
              }
              else {
                  this.hook(opts, 'after', pos, $trigger);
              }
              this.hook(opts, 'complete', cancel);
          };
          /**
           * Callback function and method call.
           */
          SweetScroll.prototype.hook = function (options, type) {
              var args = [];
              for (var _i = 2; _i < arguments.length; _i++) {
                  args[_i - 2] = arguments[_i];
              }
              var callback = options[type];
              var callbackResult;
              var methodResult;
              // callback
              if (isFunction(callback)) {
                  callbackResult = callback.apply(this, args.concat([this]));
              }
              // method
              methodResult = this["on" + (type[0].toUpperCase() + type.slice(1))].apply(this, args);
              return callbackResult !== undefined ? callbackResult : methodResult;
          };
          /**
           * Bind events of container element.
           */
          SweetScroll.prototype.bind = function (click, stop) {
              var _a = this, $el = _a.$el, opts = _a.ctx.opts;
              if ($el) {
                  if (click) {
                      addEvent($el, CONTAINER_CLICK_EVENT, this.handleClick, false);
                  }
                  if (stop) {
                      addEvent($el, CONTAINER_STOP_EVENT, this.handleStop, opts ? opts.cancellable : true);
                  }
              }
          };
          /**
           * Unbind events of container element.
           */
          SweetScroll.prototype.unbind = function (click, stop) {
              var _a = this, $el = _a.$el, opts = _a.ctx.opts;
              if ($el) {
                  if (click) {
                      removeEvent($el, CONTAINER_CLICK_EVENT, this.handleClick, false);
                  }
                  if (stop) {
                      removeEvent($el, CONTAINER_STOP_EVENT, this.handleStop, opts ? opts.cancellable : true);
                  }
              }
          };
          /**
           * You can set Polyfill (or Ponyfill) for browsers that do not support requestAnimationFrame.
           */
          SweetScroll.raf = raf;
          SweetScroll.caf = caf;
          return SweetScroll;
      }());
  
      return SweetScroll;
  
  })));
  