import "core-js/modules/es.symbol";
import "core-js/modules/es.symbol.description";
import "core-js/modules/es.symbol.iterator";
import "core-js/modules/es.array.concat";
import "core-js/modules/es.array.filter";
import "core-js/modules/es.array.from";
import "core-js/modules/es.array.includes";
import "core-js/modules/es.array.index-of";
import "core-js/modules/es.array.iterator";
import "core-js/modules/es.array.join";
import "core-js/modules/es.array.map";
import "core-js/modules/es.array.slice";
import "core-js/modules/es.number.constructor";
import "core-js/modules/es.object.assign";
import "core-js/modules/es.object.entries";
import "core-js/modules/es.object.keys";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.promise";
import "core-js/modules/es.set";
import "core-js/modules/es.string.includes";
import "core-js/modules/es.string.iterator";
import "core-js/modules/es.string.match";
import "core-js/modules/es.string.split";
import "core-js/modules/es.string.starts-with";
import "core-js/modules/es.string.trim";
import "core-js/modules/web.dom-collections.for-each";
import "core-js/modules/web.dom-collections.iterator";
import "regenerator-runtime/runtime";

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { 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 _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

/*
 * Animate Plus v2.1.1
 * Copyright (c) 2017-2018 Benjamin De Cock
 * http://animateplus.com/license
 */
// logic
// =====
var first = function first(_ref) {
  var _ref2 = _slicedToArray(_ref, 1),
      item = _ref2[0];

  return item;
};

var computeValue = function computeValue(value, index) {
  return typeof value === 'function' ? value(index) : value;
}; // dom
// ===


var getElements = function getElements(elements) {
  if (Array.isArray(elements)) {
    return elements;
  }

  if (!elements || elements.nodeType) {
    return [elements];
  }

  return Array.from(typeof elements === 'string' ? document.querySelectorAll(elements) : elements);
};

var accelerate = function accelerate(_ref3, keyframes) {
  var style = _ref3.style;
  return style.willChange = keyframes ? keyframes.map(function (_ref4) {
    var property = _ref4.property;
    return property;
  }).join() : 'auto';
};

var createSVG = function createSVG(element, attributes) {
  return Object.entries(attributes).reduce(function (node, _ref5) {
    var _ref6 = _slicedToArray(_ref5, 2),
        attribute = _ref6[0],
        value = _ref6[1];

    node.setAttribute(attribute, value);
    return node;
  }, document.createElementNS('http://www.w3.org/2000/svg', element));
}; // motion blur
// ===========


var blurs = {
  axes: ['x', 'y'],
  count: 0,
  add: function add(_ref7) {
    var element = _ref7.element,
        blur = _ref7.blur;
    var id = "motion-blur-".concat(this.count++);
    var svg = createSVG('svg', {
      style: 'position: absolute; width: 0; height: 0'
    });
    var filter = createSVG('filter', this.axes.reduce(function (attributes, axis) {
      var offset = blur[axis] * 2;
      attributes[axis] = "-".concat(offset, "%");
      attributes[axis == 'x' ? 'width' : 'height'] = "".concat(100 + offset * 2, "%");
      return attributes;
    }, {
      id: id,
      'color-interpolation-filters': 'sRGB'
    }));
    var gaussian = createSVG('feGaussianBlur', {
      in: 'SourceGraphic'
    });
    filter.append(gaussian);
    svg.append(filter);
    element.style.filter = "url(\"#".concat(id, "\")");
    document.body.prepend(svg);
    return gaussian;
  }
};

var getDeviation = function getDeviation(blur, _ref8, curve) {
  var easing = _ref8.easing;
  var progress = blur * curve;
  var out = blur - progress;

  var deviation = function () {
    if (easing == 'linear') {
      return blur;
    }

    if (easing.startsWith('in-out')) {
      return (curve < 0.5 ? progress : out) * 2;
    }

    if (easing.startsWith('in')) {
      return progress;
    }

    return out;
  }();

  return Math.max(0, deviation);
};

var setDeviation = function setDeviation(_ref9, curve) {
  var blur = _ref9.blur,
      gaussian = _ref9.gaussian,
      easing = _ref9.easing;
  var values = blurs.axes.map(function (axis) {
    return getDeviation(blur[axis], easing, curve);
  });
  gaussian.setAttribute('stdDeviation', values.join());
};

var normalizeBlur = function normalizeBlur(blur) {
  var defaults = blurs.axes.reduce(function (object, axis) {
    object[axis] = 0;
    return object;
  }, {});
  return Object.assign(defaults, blur);
};

var clearBlur = function clearBlur(_ref10, _ref11) {
  var style = _ref10.style;
  var svg = _ref11.parentNode.parentNode;
  style.filter = 'none';
  svg.remove();
}; // color conversion
// ================


var hexPairs = function hexPairs(color) {
  var split = color.split('');
  var pairs = color.length < 5 ? split.map(function (string) {
    return string + string;
  }) : split.reduce(function (array, string, index) {
    if (index % 2) {
      array.push(split[index - 1] + string);
    }

    return array;
  }, []);

  if (pairs.length < 4) {
    pairs.push('ff');
  }

  return pairs;
};

var convert = function convert(color) {
  return hexPairs(color).map(function (string) {
    return parseInt(string, 16);
  });
};

var rgba = function rgba(hex) {
  var color = hex.slice(1);

  var _convert = convert(color),
      _convert2 = _slicedToArray(_convert, 4),
      r = _convert2[0],
      g = _convert2[1],
      b = _convert2[2],
      a = _convert2[3];

  return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(a / 255, ")");
}; // easing equations
// ================


var pi2 = Math.PI * 2;

var getOffset = function getOffset(strength, period) {
  return period / pi2 * Math.asin(1 / strength);
};

var easings = {
  linear: function linear(progress) {
    return progress;
  },
  'in-cubic': function inCubic(progress) {
    return Math.pow(progress, 3);
  },
  'in-quartic': function inQuartic(progress) {
    return Math.pow(progress, 4);
  },
  'in-quintic': function inQuintic(progress) {
    return Math.pow(progress, 5);
  },
  'in-exponential': function inExponential(progress) {
    return Math.pow(1024, progress - 1);
  },
  'in-circular': function inCircular(progress) {
    return 1 - Math.sqrt(1 - Math.pow(progress, 2));
  },
  'in-elastic': function inElastic(progress, amplitude, period) {
    var strength = Math.max(amplitude, 1);
    var offset = getOffset(strength, period);
    return -(strength * Math.pow(2, 10 * (progress -= 1)) * Math.sin((progress - offset) * pi2 / period));
  },
  'out-cubic': function outCubic(progress) {
    return Math.pow(--progress, 3) + 1;
  },
  'out-quartic': function outQuartic(progress) {
    return 1 - Math.pow(--progress, 4);
  },
  'out-quintic': function outQuintic(progress) {
    return Math.pow(--progress, 5) + 1;
  },
  'out-exponential': function outExponential(progress) {
    return 1 - Math.pow(2, -10 * progress);
  },
  'out-circular': function outCircular(progress) {
    return Math.sqrt(1 - Math.pow(--progress, 2));
  },
  'out-elastic': function outElastic(progress, amplitude, period) {
    var strength = Math.max(amplitude, 1);
    var offset = getOffset(strength, period);
    return strength * Math.pow(2, -10 * progress) * Math.sin((progress - offset) * pi2 / period) + 1;
  },
  'in-out-cubic': function inOutCubic(progress) {
    return (progress *= 2) < 1 ? 0.5 * Math.pow(progress, 3) : 0.5 * ((progress -= 2) * Math.pow(progress, 2) + 2);
  },
  'in-out-quartic': function inOutQuartic(progress) {
    return (progress *= 2) < 1 ? 0.5 * Math.pow(progress, 4) : -0.5 * ((progress -= 2) * Math.pow(progress, 3) - 2);
  },
  'in-out-quintic': function inOutQuintic(progress) {
    return (progress *= 2) < 1 ? 0.5 * Math.pow(progress, 5) : 0.5 * ((progress -= 2) * Math.pow(progress, 4) + 2);
  },
  'in-out-exponential': function inOutExponential(progress) {
    return (progress *= 2) < 1 ? 0.5 * Math.pow(1024, progress - 1) : 0.5 * (-Math.pow(2, -10 * (progress - 1)) + 2);
  },
  'in-out-circular': function inOutCircular(progress) {
    return (progress *= 2) < 1 ? -0.5 * (Math.sqrt(1 - Math.pow(progress, 2)) - 1) : 0.5 * (Math.sqrt(1 - (progress -= 2) * progress) + 1);
  },
  'in-out-elastic': function inOutElastic(progress, amplitude, period) {
    var strength = Math.max(amplitude, 1);
    var offset = getOffset(strength, period);
    return (progress *= 2) < 1 ? -0.5 * (strength * Math.pow(2, 10 * (progress -= 1)) * Math.sin((progress - offset) * pi2 / period)) : strength * Math.pow(2, -10 * (progress -= 1)) * Math.sin((progress - offset) * pi2 / period) * 0.5 + 1;
  }
};

var decomposeEasing = function decomposeEasing(string) {
  var _string$trim$split = string.trim().split(' '),
      _string$trim$split2 = _slicedToArray(_string$trim$split, 3),
      easing = _string$trim$split2[0],
      _string$trim$split2$ = _string$trim$split2[1],
      amplitude = _string$trim$split2$ === void 0 ? 1 : _string$trim$split2$,
      _string$trim$split2$2 = _string$trim$split2[2],
      period = _string$trim$split2$2 === void 0 ? 0.4 : _string$trim$split2$2;

  return {
    easing: easing,
    amplitude: amplitude,
    period: period
  };
};

var ease = function ease(_ref12, progress) {
  var easing = _ref12.easing,
      amplitude = _ref12.amplitude,
      period = _ref12.period;
  return easings[easing](progress, amplitude, period);
}; // keyframes composition
// =====================


var extractRegExp = /-?\d*\.?\d+/g;

var extractStrings = function extractStrings(value) {
  return value.split(extractRegExp);
};

var extractNumbers = function extractNumbers(value) {
  return value.match(extractRegExp).map(Number);
};

var sanitize = function sanitize(values) {
  return values.map(function (value) {
    var string = String(value);
    return string.startsWith('#') ? rgba(string) : string;
  });
};

var addPropertyKeyframes = function addPropertyKeyframes(property, values) {
  var animatable = sanitize(values);
  var strings = extractStrings(first(animatable));
  var numbers = animatable.map(extractNumbers);
  var round = first(strings).startsWith('rgb');
  return {
    property: property,
    strings: strings,
    numbers: numbers,
    round: round
  };
};

var createAnimationKeyframes = function createAnimationKeyframes(keyframes, index) {
  return Object.entries(keyframes).map(function (_ref13) {
    var _ref14 = _slicedToArray(_ref13, 2),
        property = _ref14[0],
        values = _ref14[1];

    return addPropertyKeyframes(property, computeValue(values, index));
  });
};

var getCurrentValue = function getCurrentValue(from, to, easing) {
  return from + (to - from) * easing;
};

var recomposeValue = function recomposeValue(_ref15, strings, round, easing) {
  var _ref16 = _slicedToArray(_ref15, 2),
      from = _ref16[0],
      to = _ref16[1];

  return strings.reduce(function (style, string, index) {
    var previous = index - 1;
    var value = getCurrentValue(from[previous], to[previous], easing);
    return style + (round && index < 4 ? Math.round(value) : value) + string;
  });
};

var createStyles = function createStyles(keyframes, easing) {
  return keyframes.reduce(function (styles, _ref17) {
    var property = _ref17.property,
        numbers = _ref17.numbers,
        strings = _ref17.strings,
        round = _ref17.round;
    styles[property] = recomposeValue(numbers, strings, round, easing);
    return styles;
  }, {});
};

var reverseKeyframes = function reverseKeyframes(keyframes) {
  return keyframes.forEach(function (_ref18) {
    var numbers = _ref18.numbers;
    return numbers.reverse();
  });
}; // animation tracking
// ==================


var rAF = {
  all: new Set(),
  add: function add(object) {
    if (this.all.add(object).size < 2) requestAnimationFrame(tick);
  }
};
var paused = {};

var trackTime = function trackTime(timing, now) {
  if (!timing.startTime) timing.startTime = now;
  timing.elapsed = now - timing.startTime;
};

var resetTime = function resetTime(object) {
  return object.startTime = 0;
};

var getProgress = function getProgress(_ref19) {
  var elapsed = _ref19.elapsed,
      duration = _ref19.duration;
  return duration > 0 ? Math.min(elapsed / duration, 1) : 1;
};

var setSpeed = function setSpeed(speed, value, index) {
  return speed > 0 ? computeValue(value, index) / speed : 0;
};

var addAnimations = function addAnimations(options, resolve) {
  var _options$elements = options.elements,
      elements = _options$elements === void 0 ? null : _options$elements,
      _options$easing = options.easing,
      easing = _options$easing === void 0 ? 'out-elastic' : _options$easing,
      _options$duration = options.duration,
      duration = _options$duration === void 0 ? 1000 : _options$duration,
      _options$delay = options.delay,
      timeout = _options$delay === void 0 ? 0 : _options$delay,
      _options$speed = options.speed,
      speed = _options$speed === void 0 ? 1 : _options$speed,
      _options$loop = options.loop,
      loop = _options$loop === void 0 ? false : _options$loop,
      _options$optimize = options.optimize,
      optimize = _options$optimize === void 0 ? false : _options$optimize,
      _options$direction = options.direction,
      direction = _options$direction === void 0 ? 'normal' : _options$direction,
      _options$blur = options.blur,
      blur = _options$blur === void 0 ? null : _options$blur,
      _options$change = options.change,
      change = _options$change === void 0 ? null : _options$change,
      rest = _objectWithoutProperties(options, ["elements", "easing", "duration", "delay", "speed", "loop", "optimize", "direction", "blur", "change"]);

  var last = {
    totalDuration: -1
  };
  getElements(elements).forEach(
  /*#__PURE__*/
  function () {
    var _ref20 = _asyncToGenerator(
    /*#__PURE__*/
    regeneratorRuntime.mark(function _callee(element, index) {
      var keyframes, animation, animationTimeout, totalDuration;
      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              keyframes = createAnimationKeyframes(rest, index);
              animation = {
                element: element,
                keyframes: keyframes,
                loop: loop,
                optimize: optimize,
                direction: direction,
                change: change,
                easing: decomposeEasing(easing),
                duration: setSpeed(speed, duration, index)
              };
              animationTimeout = setSpeed(speed, timeout, index);
              totalDuration = animationTimeout + animation.duration;

              if (direction != 'normal') {
                reverseKeyframes(keyframes);
              }

              if (element) {
                if (optimize) {
                  accelerate(element, keyframes);
                }

                if (blur) {
                  animation.blur = normalizeBlur(computeValue(blur, index));
                  animation.gaussian = blurs.add(animation);
                }
              }

              if (totalDuration > last.totalDuration) {
                last.animation = animation;
                last.totalDuration = totalDuration;
              }

              if (!animationTimeout) {
                _context.next = 10;
                break;
              }

              _context.next = 10;
              return delay(animationTimeout);

            case 10:
              rAF.add(animation);

            case 11:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    return function (_x, _x2) {
      return _ref20.apply(this, arguments);
    };
  }());
  var animation = last.animation;
  if (!animation) return;
  animation.end = resolve;
  animation.options = options;
};

var tick = function tick(now) {
  var all = rAF.all;
  all.forEach(function (object) {
    trackTime(object, now);
    var progress = getProgress(object);
    var element = object.element,
        keyframes = object.keyframes,
        loop = object.loop,
        optimize = object.optimize,
        direction = object.direction,
        change = object.change,
        easing = object.easing,
        duration = object.duration,
        gaussian = object.gaussian,
        end = object.end,
        options = object.options; // object is an animation

    if (direction) {
      var curve = progress;

      switch (progress) {
        case 0:
          if (direction == 'alternate') reverseKeyframes(keyframes);
          break;

        case 1:
          if (loop) {
            resetTime(object);
          } else {
            all.delete(object);
            if (optimize && element) accelerate(element);
            if (gaussian) clearBlur(element, gaussian);
          }

          if (end) end(options);
          break;

        default:
          curve = ease(easing, progress);
      }

      if (gaussian) setDeviation(object, curve);
      if (change && end) change(curve);
      if (element) Object.assign(element.style, createStyles(keyframes, curve));
      return;
    } // object is a delay


    if (progress < 1) return;
    all.delete(object);
    end(duration);
  });
  if (all.size) requestAnimationFrame(tick);
};

document.addEventListener('visibilitychange', function () {
  var now = performance.now();

  if (document.hidden) {
    var _all = rAF.all;
    paused.time = now;
    paused.all = new Set(_all);

    _all.clear();

    return;
  }

  var all = paused.all,
      time = paused.time;
  if (!all) return;
  var elapsed = now - time;
  requestAnimationFrame(function () {
    return all.forEach(function (object) {
      object.startTime += elapsed;
      rAF.add(object);
    });
  });
}); // exports
// =======

export default (function (options) {
  return new Promise(function (resolve) {
    return addAnimations(options, resolve);
  });
});
export var delay = function delay(duration) {
  return new Promise(function (resolve) {
    return rAF.add({
      duration: duration,
      end: resolve
    });
  });
};
export var stop = function stop(elements) {
  var all = rAF.all;
  var nodes = getElements(elements);
  all.forEach(function (object) {
    if (nodes.includes(object.element)) all.delete(object);
  });
  return nodes;
};