/*!
 * FilePondPluginImagePreview 4.6.11
 * Licensed under MIT, https://opensource.org/licenses/MIT/
 * Please visit https://pqina.nl/filepond/ for details.
 */

/* eslint-disable */

(function(global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined'
      ? (module.exports = factory())
      : typeof define === 'function' && define.amd
      ? define(factory)
      : ((global = global || self),
        (global.FilePondPluginImagePreview = factory()));
  })(this, function() {
    'use strict';
  
    // test if file is of type image and can be viewed in canvas
    var isPreviewableImage = function isPreviewableImage(file) {
      return /^image/.test(file.type);
    };
  
    function _typeof(obj) {
      if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
        _typeof = function(obj) {
          return typeof obj;
        };
      } else {
        _typeof = function(obj) {
          return obj &&
            typeof Symbol === 'function' &&
            obj.constructor === Symbol &&
            obj !== Symbol.prototype
            ? 'symbol'
            : typeof obj;
        };
      }
  
      return _typeof(obj);
    }
  
    var REACT_ELEMENT_TYPE;
  
    function _jsx(type, props, key, children) {
      if (!REACT_ELEMENT_TYPE) {
        REACT_ELEMENT_TYPE =
          (typeof Symbol === 'function' &&
            Symbol.for &&
            Symbol.for('react.element')) ||
          0xeac7;
      }
  
      var defaultProps = type && type.defaultProps;
      var childrenLength = arguments.length - 3;
  
      if (!props && childrenLength !== 0) {
        props = {
          children: void 0
        };
      }
  
      if (props && defaultProps) {
        for (var propName in defaultProps) {
          if (props[propName] === void 0) {
            props[propName] = defaultProps[propName];
          }
        }
      } else if (!props) {
        props = defaultProps || {};
      }
  
      if (childrenLength === 1) {
        props.children = children;
      } else if (childrenLength > 1) {
        var childArray = new Array(childrenLength);
  
        for (var i = 0; i < childrenLength; i++) {
          childArray[i] = arguments[i + 3];
        }
  
        props.children = childArray;
      }
  
      return {
        $$typeof: REACT_ELEMENT_TYPE,
        type: type,
        key: key === undefined ? null : '' + key,
        ref: null,
        props: props,
        _owner: null
      };
    }
  
    function _asyncIterator(iterable) {
      var method;
  
      if (typeof Symbol === 'function') {
        if (Symbol.asyncIterator) {
          method = iterable[Symbol.asyncIterator];
          if (method != null) return method.call(iterable);
        }
  
        if (Symbol.iterator) {
          method = iterable[Symbol.iterator];
          if (method != null) return method.call(iterable);
        }
      }
  
      throw new TypeError('Object is not async iterable');
    }
  
    function _AwaitValue(value) {
      this.wrapped = value;
    }
  
    function _AsyncGenerator(gen) {
      var front, back;
  
      function send(key, arg) {
        return new Promise(function(resolve, reject) {
          var request = {
            key: key,
            arg: arg,
            resolve: resolve,
            reject: reject,
            next: null
          };
  
          if (back) {
            back = back.next = request;
          } else {
            front = back = request;
            resume(key, arg);
          }
        });
      }
  
      function resume(key, arg) {
        try {
          var result = gen[key](arg);
          var value = result.value;
          var wrappedAwait = value instanceof _AwaitValue;
          Promise.resolve(wrappedAwait ? value.wrapped : value).then(
            function(arg) {
              if (wrappedAwait) {
                resume('next', arg);
                return;
              }
  
              settle(result.done ? 'return' : 'normal', arg);
            },
            function(err) {
              resume('throw', err);
            }
          );
        } catch (err) {
          settle('throw', err);
        }
      }
  
      function settle(type, value) {
        switch (type) {
          case 'return':
            front.resolve({
              value: value,
              done: true
            });
            break;
  
          case 'throw':
            front.reject(value);
            break;
  
          default:
            front.resolve({
              value: value,
              done: false
            });
            break;
        }
  
        front = front.next;
  
        if (front) {
          resume(front.key, front.arg);
        } else {
          back = null;
        }
      }
  
      this._invoke = send;
  
      if (typeof gen.return !== 'function') {
        this.return = undefined;
      }
    }
  
    if (typeof Symbol === 'function' && Symbol.asyncIterator) {
      _AsyncGenerator.prototype[Symbol.asyncIterator] = function() {
        return this;
      };
    }
  
    _AsyncGenerator.prototype.next = function(arg) {
      return this._invoke('next', arg);
    };
  
    _AsyncGenerator.prototype.throw = function(arg) {
      return this._invoke('throw', arg);
    };
  
    _AsyncGenerator.prototype.return = function(arg) {
      return this._invoke('return', arg);
    };
  
    function _wrapAsyncGenerator(fn) {
      return function() {
        return new _AsyncGenerator(fn.apply(this, arguments));
      };
    }
  
    function _awaitAsyncGenerator(value) {
      return new _AwaitValue(value);
    }
  
    function _asyncGeneratorDelegate(inner, awaitWrap) {
      var iter = {},
        waiting = false;
  
      function pump(key, value) {
        waiting = true;
        value = new Promise(function(resolve) {
          resolve(inner[key](value));
        });
        return {
          done: false,
          value: awaitWrap(value)
        };
      }
  
      if (typeof Symbol === 'function' && Symbol.iterator) {
        iter[Symbol.iterator] = function() {
          return this;
        };
      }
  
      iter.next = function(value) {
        if (waiting) {
          waiting = false;
          return value;
        }
  
        return pump('next', value);
      };
  
      if (typeof inner.throw === 'function') {
        iter.throw = function(value) {
          if (waiting) {
            waiting = false;
            throw value;
          }
  
          return pump('throw', value);
        };
      }
  
      if (typeof inner.return === 'function') {
        iter.return = function(value) {
          return pump('return', value);
        };
      }
  
      return iter;
    }
  
    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 _classCallCheck(instance, Constructor) {
      if (!(instance instanceof Constructor)) {
        throw new TypeError('Cannot call a class as a function');
      }
    }
  
    function _defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ('value' in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }
  
    function _createClass(Constructor, protoProps, staticProps) {
      if (protoProps) _defineProperties(Constructor.prototype, protoProps);
      if (staticProps) _defineProperties(Constructor, staticProps);
      return Constructor;
    }
  
    function _defineEnumerableProperties(obj, descs) {
      for (var key in descs) {
        var desc = descs[key];
        desc.configurable = desc.enumerable = true;
        if ('value' in desc) desc.writable = true;
        Object.defineProperty(obj, key, desc);
      }
  
      if (Object.getOwnPropertySymbols) {
        var objectSymbols = Object.getOwnPropertySymbols(descs);
  
        for (var i = 0; i < objectSymbols.length; i++) {
          var sym = objectSymbols[i];
          var desc = descs[sym];
          desc.configurable = desc.enumerable = true;
          if ('value' in desc) desc.writable = true;
          Object.defineProperty(obj, sym, desc);
        }
      }
  
      return obj;
    }
  
    function _defaults(obj, defaults) {
      var keys = Object.getOwnPropertyNames(defaults);
  
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var value = Object.getOwnPropertyDescriptor(defaults, key);
  
        if (value && value.configurable && obj[key] === undefined) {
          Object.defineProperty(obj, key, value);
        }
      }
  
      return obj;
    }
  
    function _defineProperty(obj, key, value) {
      if (key in obj) {
        Object.defineProperty(obj, key, {
          value: value,
          enumerable: true,
          configurable: true,
          writable: true
        });
      } else {
        obj[key] = value;
      }
  
      return obj;
    }
  
    function _extends() {
      _extends =
        Object.assign ||
        function(target) {
          for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
  
            for (var key in source) {
              if (Object.prototype.hasOwnProperty.call(source, key)) {
                target[key] = source[key];
              }
            }
          }
  
          return target;
        };
  
      return _extends.apply(this, arguments);
    }
  
    function _objectSpread(target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i] != null ? arguments[i] : {};
        var ownKeys = Object.keys(source);
  
        if (typeof Object.getOwnPropertySymbols === 'function') {
          ownKeys = ownKeys.concat(
            Object.getOwnPropertySymbols(source).filter(function(sym) {
              return Object.getOwnPropertyDescriptor(source, sym).enumerable;
            })
          );
        }
  
        ownKeys.forEach(function(key) {
          _defineProperty(target, key, source[key]);
        });
      }
  
      return target;
    }
  
    function _inherits(subClass, superClass) {
      if (typeof superClass !== 'function' && superClass !== null) {
        throw new TypeError('Super expression must either be null or a function');
      }
  
      subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
          value: subClass,
          writable: true,
          configurable: true
        }
      });
      if (superClass) _setPrototypeOf(subClass, superClass);
    }
  
    function _inheritsLoose(subClass, superClass) {
      subClass.prototype = Object.create(superClass.prototype);
      subClass.prototype.constructor = subClass;
      subClass.__proto__ = superClass;
    }
  
    function _getPrototypeOf(o) {
      _getPrototypeOf = Object.setPrototypeOf
        ? Object.getPrototypeOf
        : function _getPrototypeOf(o) {
            return o.__proto__ || Object.getPrototypeOf(o);
          };
      return _getPrototypeOf(o);
    }
  
    function _setPrototypeOf(o, p) {
      _setPrototypeOf =
        Object.setPrototypeOf ||
        function _setPrototypeOf(o, p) {
          o.__proto__ = p;
          return o;
        };
  
      return _setPrototypeOf(o, p);
    }
  
    function isNativeReflectConstruct() {
      if (typeof Reflect === 'undefined' || !Reflect.construct) return false;
      if (Reflect.construct.sham) return false;
      if (typeof Proxy === 'function') return true;
  
      try {
        Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));
        return true;
      } catch (e) {
        return false;
      }
    }
  
    function _construct(Parent, args, Class) {
      if (isNativeReflectConstruct()) {
        _construct = Reflect.construct;
      } else {
        _construct = function _construct(Parent, args, Class) {
          var a = [null];
          a.push.apply(a, args);
          var Constructor = Function.bind.apply(Parent, a);
          var instance = new Constructor();
          if (Class) _setPrototypeOf(instance, Class.prototype);
          return instance;
        };
      }
  
      return _construct.apply(null, arguments);
    }
  
    function _isNativeFunction(fn) {
      return Function.toString.call(fn).indexOf('[native code]') !== -1;
    }
  
    function _wrapNativeSuper(Class) {
      var _cache = typeof Map === 'function' ? new Map() : undefined;
  
      _wrapNativeSuper = function _wrapNativeSuper(Class) {
        if (Class === null || !_isNativeFunction(Class)) return Class;
  
        if (typeof Class !== 'function') {
          throw new TypeError(
            'Super expression must either be null or a function'
          );
        }
  
        if (typeof _cache !== 'undefined') {
          if (_cache.has(Class)) return _cache.get(Class);
  
          _cache.set(Class, Wrapper);
        }
  
        function Wrapper() {
          return _construct(Class, arguments, _getPrototypeOf(this).constructor);
        }
  
        Wrapper.prototype = Object.create(Class.prototype, {
          constructor: {
            value: Wrapper,
            enumerable: false,
            writable: true,
            configurable: true
          }
        });
        return _setPrototypeOf(Wrapper, Class);
      };
  
      return _wrapNativeSuper(Class);
    }
  
    function _instanceof(left, right) {
      if (
        right != null &&
        typeof Symbol !== 'undefined' &&
        right[Symbol.hasInstance]
      ) {
        return right[Symbol.hasInstance](left);
      } else {
        return left instanceof right;
      }
    }
  
    function _interopRequireDefault(obj) {
      return obj && obj.__esModule
        ? obj
        : {
            default: obj
          };
    }
  
    function _interopRequireWildcard(obj) {
      if (obj && obj.__esModule) {
        return obj;
      } else {
        var newObj = {};
  
        if (obj != null) {
          for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
              var desc =
                Object.defineProperty && Object.getOwnPropertyDescriptor
                  ? Object.getOwnPropertyDescriptor(obj, key)
                  : {};
  
              if (desc.get || desc.set) {
                Object.defineProperty(newObj, key, desc);
              } else {
                newObj[key] = obj[key];
              }
            }
          }
        }
  
        newObj.default = obj;
        return newObj;
      }
    }
  
    function _newArrowCheck(innerThis, boundThis) {
      if (innerThis !== boundThis) {
        throw new TypeError('Cannot instantiate an arrow function');
      }
    }
  
    function _objectDestructuringEmpty(obj) {
      if (obj == null) throw new TypeError('Cannot destructure undefined');
    }
  
    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 _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 _assertThisInitialized(self) {
      if (self === void 0) {
        throw new ReferenceError(
          "this hasn't been initialised - super() hasn't been called"
        );
      }
  
      return self;
    }
  
    function _possibleConstructorReturn(self, call) {
      if (call && (typeof call === 'object' || typeof call === 'function')) {
        return call;
      }
  
      return _assertThisInitialized(self);
    }
  
    function _superPropBase(object, property) {
      while (!Object.prototype.hasOwnProperty.call(object, property)) {
        object = _getPrototypeOf(object);
        if (object === null) break;
      }
  
      return object;
    }
  
    function _get(target, property, receiver) {
      if (typeof Reflect !== 'undefined' && Reflect.get) {
        _get = Reflect.get;
      } else {
        _get = function _get(target, property, receiver) {
          var base = _superPropBase(target, property);
  
          if (!base) return;
          var desc = Object.getOwnPropertyDescriptor(base, property);
  
          if (desc.get) {
            return desc.get.call(receiver);
          }
  
          return desc.value;
        };
      }
  
      return _get(target, property, receiver || target);
    }
  
    function set(target, property, value, receiver) {
      if (typeof Reflect !== 'undefined' && Reflect.set) {
        set = Reflect.set;
      } else {
        set = function set(target, property, value, receiver) {
          var base = _superPropBase(target, property);
  
          var desc;
  
          if (base) {
            desc = Object.getOwnPropertyDescriptor(base, property);
  
            if (desc.set) {
              desc.set.call(receiver, value);
              return true;
            } else if (!desc.writable) {
              return false;
            }
          }
  
          desc = Object.getOwnPropertyDescriptor(receiver, property);
  
          if (desc) {
            if (!desc.writable) {
              return false;
            }
  
            desc.value = value;
            Object.defineProperty(receiver, property, desc);
          } else {
            _defineProperty(receiver, property, value);
          }
  
          return true;
        };
      }
  
      return set(target, property, value, receiver);
    }
  
    function _set(target, property, value, receiver, isStrict) {
      var s = set(target, property, value, receiver || target);
  
      if (!s && isStrict) {
        throw new Error('failed to set property');
      }
  
      return value;
    }
  
    function _taggedTemplateLiteral(strings, raw) {
      if (!raw) {
        raw = strings.slice(0);
      }
  
      return Object.freeze(
        Object.defineProperties(strings, {
          raw: {
            value: Object.freeze(raw)
          }
        })
      );
    }
  
    function _taggedTemplateLiteralLoose(strings, raw) {
      if (!raw) {
        raw = strings.slice(0);
      }
  
      strings.raw = raw;
      return strings;
    }
  
    function _temporalRef(val, name) {
      if (val === _temporalUndefined) {
        throw new ReferenceError(name + ' is not defined - temporal dead zone');
      } else {
        return val;
      }
    }
  
    function _readOnlyError(name) {
      throw new Error('"' + name + '" is read-only');
    }
  
    function _classNameTDZError(name) {
      throw new Error(
        'Class "' + name + '" cannot be referenced in computed property keys.'
      );
    }
  
    var _temporalUndefined = {};
  
    function _slicedToArray(arr, i) {
      return (
        _arrayWithHoles(arr) ||
        _iterableToArrayLimit(arr, i) ||
        _nonIterableRest()
      );
    }
  
    function _slicedToArrayLoose(arr, i) {
      return (
        _arrayWithHoles(arr) ||
        _iterableToArrayLimitLoose(arr, i) ||
        _nonIterableRest()
      );
    }
  
    function _toArray(arr) {
      return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
    }
  
    function _toConsumableArray(arr) {
      return (
        _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread()
      );
    }
  
    function _arrayWithoutHoles(arr) {
      if (Array.isArray(arr)) {
        for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++)
          arr2[i] = arr[i];
  
        return arr2;
      }
    }
  
    function _arrayWithHoles(arr) {
      if (Array.isArray(arr)) return arr;
    }
  
    function _iterableToArray(iter) {
      if (
        Symbol.iterator in Object(iter) ||
        Object.prototype.toString.call(iter) === '[object Arguments]'
      )
        return Array.from(iter);
    }
  
    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 _iterableToArrayLimitLoose(arr, i) {
      var _arr = [];
  
      for (
        var _iterator = arr[Symbol.iterator](), _step;
        !(_step = _iterator.next()).done;
  
      ) {
        _arr.push(_step.value);
  
        if (i && _arr.length === i) break;
      }
  
      return _arr;
    }
  
    function _nonIterableSpread() {
      throw new TypeError('Invalid attempt to spread non-iterable instance');
    }
  
    function _nonIterableRest() {
      throw new TypeError('Invalid attempt to destructure non-iterable instance');
    }
  
    function _skipFirstGeneratorNext(fn) {
      return function() {
        var it = fn.apply(this, arguments);
        it.next();
        return it;
      };
    }
  
    function _toPrimitive(input, hint) {
      if (typeof input !== 'object' || input === null) return input;
      var prim = input[Symbol.toPrimitive];
  
      if (prim !== undefined) {
        var res = prim.call(input, hint || 'default');
        if (typeof res !== 'object') return res;
        throw new TypeError('@@toPrimitive must return a primitive value.');
      }
  
      return (hint === 'string' ? String : Number)(input);
    }
  
    function _toPropertyKey(arg) {
      var key = _toPrimitive(arg, 'string');
  
      return typeof key === 'symbol' ? key : String(key);
    }
  
    function _initializerWarningHelper(descriptor, context) {
      throw new Error(
        'Decorating class property failed. Please ensure that ' +
          'proposal-class-properties is enabled and set to use loose mode. ' +
          'To use proposal-class-properties in spec mode with decorators, wait for ' +
          'the next major version of decorators in stage 2.'
      );
    }
  
    function _initializerDefineProperty(target, property, descriptor, context) {
      if (!descriptor) return;
      Object.defineProperty(target, property, {
        enumerable: descriptor.enumerable,
        configurable: descriptor.configurable,
        writable: descriptor.writable,
        value: descriptor.initializer
          ? descriptor.initializer.call(context)
          : void 0
      });
    }
  
    function _applyDecoratedDescriptor(
      target,
      property,
      decorators,
      descriptor,
      context
    ) {
      var desc = {};
      Object.keys(descriptor).forEach(function(key) {
        desc[key] = descriptor[key];
      });
      desc.enumerable = !!desc.enumerable;
      desc.configurable = !!desc.configurable;
  
      if ('value' in desc || desc.initializer) {
        desc.writable = true;
      }
  
      desc = decorators
        .slice()
        .reverse()
        .reduce(function(desc, decorator) {
          return decorator(target, property, desc) || desc;
        }, desc);
  
      if (context && desc.initializer !== void 0) {
        desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
        desc.initializer = undefined;
      }
  
      if (desc.initializer === void 0) {
        Object.defineProperty(target, property, desc);
        desc = null;
      }
  
      return desc;
    }
  
    var id = 0;
  
    function _classPrivateFieldLooseKey(name) {
      return '__private_' + id++ + '_' + name;
    }
  
    function _classPrivateFieldLooseBase(receiver, privateKey) {
      if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
        throw new TypeError('attempted to use private field on non-instance');
      }
  
      return receiver;
    }
  
    function _classPrivateFieldGet(receiver, privateMap) {
      if (!privateMap.has(receiver)) {
        throw new TypeError('attempted to get private field on non-instance');
      }
  
      var descriptor = privateMap.get(receiver);
  
      if (descriptor.get) {
        return descriptor.get.call(receiver);
      }
  
      return descriptor.value;
    }
  
    function _classPrivateFieldSet(receiver, privateMap, value) {
      if (!privateMap.has(receiver)) {
        throw new TypeError('attempted to set private field on non-instance');
      }
  
      var descriptor = privateMap.get(receiver);
  
      if (descriptor.set) {
        descriptor.set.call(receiver, value);
      } else {
        if (!descriptor.writable) {
          throw new TypeError('attempted to set read only private field');
        }
  
        descriptor.value = value;
      }
  
      return value;
    }
  
    function _classStaticPrivateFieldSpecGet(
      receiver,
      classConstructor,
      descriptor
    ) {
      if (receiver !== classConstructor) {
        throw new TypeError('Private static access of wrong provenance');
      }
  
      return descriptor.value;
    }
  
    function _classStaticPrivateFieldSpecSet(
      receiver,
      classConstructor,
      descriptor,
      value
    ) {
      if (receiver !== classConstructor) {
        throw new TypeError('Private static access of wrong provenance');
      }
  
      if (!descriptor.writable) {
        throw new TypeError('attempted to set read only private field');
      }
  
      descriptor.value = value;
      return value;
    }
  
    function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
      if (receiver !== classConstructor) {
        throw new TypeError('Private static access of wrong provenance');
      }
  
      return method;
    }
  
    function _classStaticPrivateMethodSet() {
      throw new TypeError('attempted to set read only static private field');
    }
  
    function _decorate(decorators, factory, superClass, mixins) {
      var api = _getDecoratorsApi();
  
      if (mixins) {
        for (var i = 0; i < mixins.length; i++) {
          api = mixins[i](api);
        }
      }
  
      var r = factory(function initialize(O) {
        api.initializeInstanceElements(O, decorated.elements);
      }, superClass);
      var decorated = api.decorateClass(
        _coalesceClassElements(r.d.map(_createElementDescriptor)),
        decorators
      );
      api.initializeClassElements(r.F, decorated.elements);
      return api.runClassFinishers(r.F, decorated.finishers);
    }
  
    function _getDecoratorsApi() {
      _getDecoratorsApi = function() {
        return api;
      };
  
      var api = {
        elementsDefinitionOrder: [['method'], ['field']],
        initializeInstanceElements: function(O, elements) {
          ['method', 'field'].forEach(function(kind) {
            elements.forEach(function(element) {
              if (element.kind === kind && element.placement === 'own') {
                this.defineClassElement(O, element);
              }
            }, this);
          }, this);
        },
        initializeClassElements: function(F, elements) {
          var proto = F.prototype;
          ['method', 'field'].forEach(function(kind) {
            elements.forEach(function(element) {
              var placement = element.placement;
  
              if (
                element.kind === kind &&
                (placement === 'static' || placement === 'prototype')
              ) {
                var receiver = placement === 'static' ? F : proto;
                this.defineClassElement(receiver, element);
              }
            }, this);
          }, this);
        },
        defineClassElement: function(receiver, element) {
          var descriptor = element.descriptor;
  
          if (element.kind === 'field') {
            var initializer = element.initializer;
            descriptor = {
              enumerable: descriptor.enumerable,
              writable: descriptor.writable,
              configurable: descriptor.configurable,
              value: initializer === void 0 ? void 0 : initializer.call(receiver)
            };
          }
  
          Object.defineProperty(receiver, element.key, descriptor);
        },
        decorateClass: function(elements, decorators) {
          var newElements = [];
          var finishers = [];
          var placements = {
            static: [],
            prototype: [],
            own: []
          };
          elements.forEach(function(element) {
            this.addElementPlacement(element, placements);
          }, this);
          elements.forEach(function(element) {
            if (!_hasDecorators(element)) return newElements.push(element);
            var elementFinishersExtras = this.decorateElement(
              element,
              placements
            );
            newElements.push(elementFinishersExtras.element);
            newElements.push.apply(newElements, elementFinishersExtras.extras);
            finishers.push.apply(finishers, elementFinishersExtras.finishers);
          }, this);
  
          if (!decorators) {
            return {
              elements: newElements,
              finishers: finishers
            };
          }
  
          var result = this.decorateConstructor(newElements, decorators);
          finishers.push.apply(finishers, result.finishers);
          result.finishers = finishers;
          return result;
        },
        addElementPlacement: function(element, placements, silent) {
          var keys = placements[element.placement];
  
          if (!silent && keys.indexOf(element.key) !== -1) {
            throw new TypeError('Duplicated element (' + element.key + ')');
          }
  
          keys.push(element.key);
        },
        decorateElement: function(element, placements) {
          var extras = [];
          var finishers = [];
  
          for (
            var decorators = element.decorators, i = decorators.length - 1;
            i >= 0;
            i--
          ) {
            var keys = placements[element.placement];
            keys.splice(keys.indexOf(element.key), 1);
            var elementObject = this.fromElementDescriptor(element);
            var elementFinisherExtras = this.toElementFinisherExtras(
              (0, decorators[i])(elementObject) || elementObject
            );
            element = elementFinisherExtras.element;
            this.addElementPlacement(element, placements);
  
            if (elementFinisherExtras.finisher) {
              finishers.push(elementFinisherExtras.finisher);
            }
  
            var newExtras = elementFinisherExtras.extras;
  
            if (newExtras) {
              for (var j = 0; j < newExtras.length; j++) {
                this.addElementPlacement(newExtras[j], placements);
              }
  
              extras.push.apply(extras, newExtras);
            }
          }
  
          return {
            element: element,
            finishers: finishers,
            extras: extras
          };
        },
        decorateConstructor: function(elements, decorators) {
          var finishers = [];
  
          for (var i = decorators.length - 1; i >= 0; i--) {
            var obj = this.fromClassDescriptor(elements);
            var elementsAndFinisher = this.toClassDescriptor(
              (0, decorators[i])(obj) || obj
            );
  
            if (elementsAndFinisher.finisher !== undefined) {
              finishers.push(elementsAndFinisher.finisher);
            }
  
            if (elementsAndFinisher.elements !== undefined) {
              elements = elementsAndFinisher.elements;
  
              for (var j = 0; j < elements.length - 1; j++) {
                for (var k = j + 1; k < elements.length; k++) {
                  if (
                    elements[j].key === elements[k].key &&
                    elements[j].placement === elements[k].placement
                  ) {
                    throw new TypeError(
                      'Duplicated element (' + elements[j].key + ')'
                    );
                  }
                }
              }
            }
          }
  
          return {
            elements: elements,
            finishers: finishers
          };
        },
        fromElementDescriptor: function(element) {
          var obj = {
            kind: element.kind,
            key: element.key,
            placement: element.placement,
            descriptor: element.descriptor
          };
          var desc = {
            value: 'Descriptor',
            configurable: true
          };
          Object.defineProperty(obj, Symbol.toStringTag, desc);
          if (element.kind === 'field') obj.initializer = element.initializer;
          return obj;
        },
        toElementDescriptors: function(elementObjects) {
          if (elementObjects === undefined) return;
          return _toArray(elementObjects).map(function(elementObject) {
            var element = this.toElementDescriptor(elementObject);
            this.disallowProperty(
              elementObject,
              'finisher',
              'An element descriptor'
            );
            this.disallowProperty(
              elementObject,
              'extras',
              'An element descriptor'
            );
            return element;
          }, this);
        },
        toElementDescriptor: function(elementObject) {
          var kind = String(elementObject.kind);
  
          if (kind !== 'method' && kind !== 'field') {
            throw new TypeError(
              'An element descriptor\'s .kind property must be either "method" or' +
                ' "field", but a decorator created an element descriptor with' +
                ' .kind "' +
                kind +
                '"'
            );
          }
  
          var key = _toPropertyKey(elementObject.key);
  
          var placement = String(elementObject.placement);
  
          if (
            placement !== 'static' &&
            placement !== 'prototype' &&
            placement !== 'own'
          ) {
            throw new TypeError(
              'An element descriptor\'s .placement property must be one of "static",' +
                ' "prototype" or "own", but a decorator created an element descriptor' +
                ' with .placement "' +
                placement +
                '"'
            );
          }
  
          var descriptor = elementObject.descriptor;
          this.disallowProperty(
            elementObject,
            'elements',
            'An element descriptor'
          );
          var element = {
            kind: kind,
            key: key,
            placement: placement,
            descriptor: Object.assign({}, descriptor)
          };
  
          if (kind !== 'field') {
            this.disallowProperty(
              elementObject,
              'initializer',
              'A method descriptor'
            );
          } else {
            this.disallowProperty(
              descriptor,
              'get',
              'The property descriptor of a field descriptor'
            );
            this.disallowProperty(
              descriptor,
              'set',
              'The property descriptor of a field descriptor'
            );
            this.disallowProperty(
              descriptor,
              'value',
              'The property descriptor of a field descriptor'
            );
            element.initializer = elementObject.initializer;
          }
  
          return element;
        },
        toElementFinisherExtras: function(elementObject) {
          var element = this.toElementDescriptor(elementObject);
  
          var finisher = _optionalCallableProperty(elementObject, 'finisher');
  
          var extras = this.toElementDescriptors(elementObject.extras);
          return {
            element: element,
            finisher: finisher,
            extras: extras
          };
        },
        fromClassDescriptor: function(elements) {
          var obj = {
            kind: 'class',
            elements: elements.map(this.fromElementDescriptor, this)
          };
          var desc = {
            value: 'Descriptor',
            configurable: true
          };
          Object.defineProperty(obj, Symbol.toStringTag, desc);
          return obj;
        },
        toClassDescriptor: function(obj) {
          var kind = String(obj.kind);
  
          if (kind !== 'class') {
            throw new TypeError(
              'A class descriptor\'s .kind property must be "class", but a decorator' +
                ' created a class descriptor with .kind "' +
                kind +
                '"'
            );
          }
  
          this.disallowProperty(obj, 'key', 'A class descriptor');
          this.disallowProperty(obj, 'placement', 'A class descriptor');
          this.disallowProperty(obj, 'descriptor', 'A class descriptor');
          this.disallowProperty(obj, 'initializer', 'A class descriptor');
          this.disallowProperty(obj, 'extras', 'A class descriptor');
  
          var finisher = _optionalCallableProperty(obj, 'finisher');
  
          var elements = this.toElementDescriptors(obj.elements);
          return {
            elements: elements,
            finisher: finisher
          };
        },
        runClassFinishers: function(constructor, finishers) {
          for (var i = 0; i < finishers.length; i++) {
            var newConstructor = (0, finishers[i])(constructor);
  
            if (newConstructor !== undefined) {
              if (typeof newConstructor !== 'function') {
                throw new TypeError('Finishers must return a constructor.');
              }
  
              constructor = newConstructor;
            }
          }
  
          return constructor;
        },
        disallowProperty: function(obj, name, objectType) {
          if (obj[name] !== undefined) {
            throw new TypeError(
              objectType + " can't have a ." + name + ' property.'
            );
          }
        }
      };
      return api;
    }
  
    function _createElementDescriptor(def) {
      var key = _toPropertyKey(def.key);
  
      var descriptor;
  
      if (def.kind === 'method') {
        descriptor = {
          value: def.value,
          writable: true,
          configurable: true,
          enumerable: false
        };
      } else if (def.kind === 'get') {
        descriptor = {
          get: def.value,
          configurable: true,
          enumerable: false
        };
      } else if (def.kind === 'set') {
        descriptor = {
          set: def.value,
          configurable: true,
          enumerable: false
        };
      } else if (def.kind === 'field') {
        descriptor = {
          configurable: true,
          writable: true,
          enumerable: true
        };
      }
  
      var element = {
        kind: def.kind === 'field' ? 'field' : 'method',
        key: key,
        placement: def.static
          ? 'static'
          : def.kind === 'field'
          ? 'own'
          : 'prototype',
        descriptor: descriptor
      };
      if (def.decorators) element.decorators = def.decorators;
      if (def.kind === 'field') element.initializer = def.value;
      return element;
    }
  
    function _coalesceGetterSetter(element, other) {
      if (element.descriptor.get !== undefined) {
        other.descriptor.get = element.descriptor.get;
      } else {
        other.descriptor.set = element.descriptor.set;
      }
    }
  
    function _coalesceClassElements(elements) {
      var newElements = [];
  
      var isSameElement = function(other) {
        return (
          other.kind === 'method' &&
          other.key === element.key &&
          other.placement === element.placement
        );
      };
  
      for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        var other;
  
        if (
          element.kind === 'method' &&
          (other = newElements.find(isSameElement))
        ) {
          if (
            _isDataDescriptor(element.descriptor) ||
            _isDataDescriptor(other.descriptor)
          ) {
            if (_hasDecorators(element) || _hasDecorators(other)) {
              throw new ReferenceError(
                'Duplicated methods (' + element.key + ") can't be decorated."
              );
            }
  
            other.descriptor = element.descriptor;
          } else {
            if (_hasDecorators(element)) {
              if (_hasDecorators(other)) {
                throw new ReferenceError(
                  "Decorators can't be placed on different accessors with for " +
                    'the same property (' +
                    element.key +
                    ').'
                );
              }
  
              other.decorators = element.decorators;
            }
  
            _coalesceGetterSetter(element, other);
          }
        } else {
          newElements.push(element);
        }
      }
  
      return newElements;
    }
  
    function _hasDecorators(element) {
      return element.decorators && element.decorators.length;
    }
  
    function _isDataDescriptor(desc) {
      return (
        desc !== undefined &&
        !(desc.value === undefined && desc.writable === undefined)
      );
    }
  
    function _optionalCallableProperty(obj, name) {
      var value = obj[name];
  
      if (value !== undefined && typeof value !== 'function') {
        throw new TypeError("Expected '" + name + "' to be a function");
      }
  
      return value;
    }
  
    function _classPrivateMethodGet(receiver, privateSet, fn) {
      if (!privateSet.has(receiver)) {
        throw new TypeError('attempted to get private field on non-instance');
      }
  
      return fn;
    }
  
    function _classPrivateMethodSet() {
      throw new TypeError('attempted to reassign private method');
    }
  
    function _wrapRegExp(re, groups) {
      _wrapRegExp = function(re, groups) {
        return new BabelRegExp(re, groups);
      };
  
      var _RegExp = _wrapNativeSuper(RegExp);
  
      var _super = RegExp.prototype;
  
      var _groups = new WeakMap();
  
      function BabelRegExp(re, groups) {
        var _this = _RegExp.call(this, re);
  
        _groups.set(_this, groups);
  
        return _this;
      }
  
      _inherits(BabelRegExp, _RegExp);
  
      BabelRegExp.prototype.exec = function(str) {
        var result = _super.exec.call(this, str);
  
        if (result) result.groups = buildGroups(result, this);
        return result;
      };
  
      BabelRegExp.prototype[Symbol.replace] = function(str, substitution) {
        if (typeof substitution === 'string') {
          var groups = _groups.get(this);
  
          return _super[Symbol.replace].call(
            this,
            str,
            substitution.replace(/\$<([^>]+)>/g, function(_, name) {
              return '$' + groups[name];
            })
          );
        } else if (typeof substitution === 'function') {
          var _this = this;
  
          return _super[Symbol.replace].call(this, str, function() {
            var args = [];
            args.push.apply(args, arguments);
  
            if (typeof args[args.length - 1] !== 'object') {
              args.push(buildGroups(args, _this));
            }
  
            return substitution.apply(this, args);
          });
        } else {
          return _super[Symbol.replace].call(this, str, substitution);
        }
      };
  
      function buildGroups(result, re) {
        var g = _groups.get(re);
  
        return Object.keys(g).reduce(function(groups, name) {
          groups[name] = result[g[name]];
          return groups;
        }, Object.create(null));
      }
  
      return _wrapRegExp.apply(this, arguments);
    }
  
    var vectorMultiply = function vectorMultiply(v, amount) {
      return createVector(v.x * amount, v.y * amount);
    };
  
    var vectorAdd = function vectorAdd(a, b) {
      return createVector(a.x + b.x, a.y + b.y);
    };
  
    var vectorNormalize = function vectorNormalize(v) {
      var l = Math.sqrt(v.x * v.x + v.y * v.y);
      if (l === 0) {
        return {
          x: 0,
          y: 0
        };
      }
      return createVector(v.x / l, v.y / l);
    };
  
    var vectorRotate = function vectorRotate(v, radians, origin) {
      var cos = Math.cos(radians);
      var sin = Math.sin(radians);
      var t = createVector(v.x - origin.x, v.y - origin.y);
      return createVector(
        origin.x + cos * t.x - sin * t.y,
        origin.y + sin * t.x + cos * t.y
      );
    };
  
    var createVector = function createVector() {
      var x =
        arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
      var y =
        arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      return { x: x, y: y };
    };
  
    var getMarkupValue = function getMarkupValue(value, size) {
      var scalar =
        arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
      var axis = arguments.length > 3 ? arguments[3] : undefined;
      if (typeof value === 'string') {
        return parseFloat(value) * scalar;
      }
      if (typeof value === 'number') {
        return value * (axis ? size[axis] : Math.min(size.width, size.height));
      }
      return;
    };
  
    var getMarkupStyles = function getMarkupStyles(markup, size, scale) {
      var lineStyle = markup.borderStyle || markup.lineStyle || 'solid';
      var fill = markup.backgroundColor || markup.fontColor || 'transparent';
      var stroke = markup.borderColor || markup.lineColor || 'transparent';
      var strokeWidth = getMarkupValue(
        markup.borderWidth || markup.lineWidth,
        size,
        scale
      );
      var lineCap = markup.lineCap || 'round';
      var lineJoin = markup.lineJoin || 'round';
      var dashes =
        typeof lineStyle === 'string'
          ? ''
          : lineStyle
              .map(function(v) {
                return getMarkupValue(v, size, scale);
              })
              .join(',');
      var opacity = markup.opacity || 1;
      return {
        'stroke-linecap': lineCap,
        'stroke-linejoin': lineJoin,
        'stroke-width': strokeWidth || 0,
        'stroke-dasharray': dashes,
        stroke: stroke,
        fill: fill,
        opacity: opacity
      };
    };
  
    var isDefined = function isDefined(value) {
      return value != null;
    };
  
    var getMarkupRect = function getMarkupRect(rect, size) {
      var scalar =
        arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  
      var left =
        getMarkupValue(rect.x, size, scalar, 'width') ||
        getMarkupValue(rect.left, size, scalar, 'width');
      var top =
        getMarkupValue(rect.y, size, scalar, 'height') ||
        getMarkupValue(rect.top, size, scalar, 'height');
      var width = getMarkupValue(rect.width, size, scalar, 'width');
      var height = getMarkupValue(rect.height, size, scalar, 'height');
      var right = getMarkupValue(rect.right, size, scalar, 'width');
      var bottom = getMarkupValue(rect.bottom, size, scalar, 'height');
  
      if (!isDefined(top)) {
        if (isDefined(height) && isDefined(bottom)) {
          top = size.height - height - bottom;
        } else {
          top = bottom;
        }
      }
  
      if (!isDefined(left)) {
        if (isDefined(width) && isDefined(right)) {
          left = size.width - width - right;
        } else {
          left = right;
        }
      }
  
      if (!isDefined(width)) {
        if (isDefined(left) && isDefined(right)) {
          width = size.width - left - right;
        } else {
          width = 0;
        }
      }
  
      if (!isDefined(height)) {
        if (isDefined(top) && isDefined(bottom)) {
          height = size.height - top - bottom;
        } else {
          height = 0;
        }
      }
  
      return {
        x: left || 0,
        y: top || 0,
        width: width || 0,
        height: height || 0
      };
    };
  
    var pointsToPathShape = function pointsToPathShape(points) {
      return points
        .map(function(point, index) {
          return ''
            .concat(index === 0 ? 'M' : 'L', ' ')
            .concat(point.x, ' ')
            .concat(point.y);
        })
        .join(' ');
    };
  
    var setAttributes = function setAttributes(element, attr) {
      return Object.keys(attr).forEach(function(key) {
        return element.setAttribute(key, attr[key]);
      });
    };
  
    var ns = 'http://www.w3.org/2000/svg';
    var svg = function svg(tag, attr) {
      var element = document.createElementNS(ns, tag);
      if (attr) {
        setAttributes(element, attr);
      }
      return element;
    };
  
    var updateRect = function updateRect(element) {
      return setAttributes(
        element,
        Object.assign({}, element.rect, element.styles)
      );
    };
  
    var updateEllipse = function updateEllipse(element) {
      var cx = element.rect.x + element.rect.width * 0.5;
      var cy = element.rect.y + element.rect.height * 0.5;
      var rx = element.rect.width * 0.5;
      var ry = element.rect.height * 0.5;
      return setAttributes(
        element,
        Object.assign(
          {
            cx: cx,
            cy: cy,
            rx: rx,
            ry: ry
          },
          element.styles
        )
      );
    };
  
    var IMAGE_FIT_STYLE = {
      contain: 'xMidYMid meet',
      cover: 'xMidYMid slice'
    };
  
    var updateImage = function updateImage(element, markup) {
      setAttributes(
        element,
        Object.assign({}, element.rect, element.styles, {
          preserveAspectRatio: IMAGE_FIT_STYLE[markup.fit] || 'none'
        })
      );
    };
  
    var TEXT_ANCHOR = {
      left: 'start',
      center: 'middle',
      right: 'end'
    };
  
    var updateText = function updateText(element, markup, size, scale) {
      var fontSize = getMarkupValue(markup.fontSize, size, scale);
      var fontFamily = markup.fontFamily || 'sans-serif';
      var fontWeight = markup.fontWeight || 'normal';
      var textAlign = TEXT_ANCHOR[markup.textAlign] || 'start';
  
      setAttributes(
        element,
        Object.assign({}, element.rect, element.styles, {
          'stroke-width': 0,
          'font-weight': fontWeight,
          'font-size': fontSize,
          'font-family': fontFamily,
          'text-anchor': textAlign
        })
      );
  
      // update text
      if (element.text !== markup.text) {
        element.text = markup.text;
        element.textContent = markup.text.length ? markup.text : ' ';
      }
    };
  
    var updateLine = function updateLine(element, markup, size, scale) {
      setAttributes(
        element,
        Object.assign({}, element.rect, element.styles, {
          fill: 'none'
        })
      );
  
      var line = element.childNodes[0];
      var begin = element.childNodes[1];
      var end = element.childNodes[2];
  
      var origin = element.rect;
  
      var target = {
        x: element.rect.x + element.rect.width,
        y: element.rect.y + element.rect.height
      };
  
      setAttributes(line, {
        x1: origin.x,
        y1: origin.y,
        x2: target.x,
        y2: target.y
      });
  
      if (!markup.lineDecoration) return;
  
      begin.style.display = 'none';
      end.style.display = 'none';
  
      var v = vectorNormalize({
        x: target.x - origin.x,
        y: target.y - origin.y
      });
  
      var l = getMarkupValue(0.05, size, scale);
  
      if (markup.lineDecoration.indexOf('arrow-begin') !== -1) {
        var arrowBeginRotationPoint = vectorMultiply(v, l);
        var arrowBeginCenter = vectorAdd(origin, arrowBeginRotationPoint);
        var arrowBeginA = vectorRotate(origin, 2, arrowBeginCenter);
        var arrowBeginB = vectorRotate(origin, -2, arrowBeginCenter);
  
        setAttributes(begin, {
          style: 'display:block;',
          d: 'M'
            .concat(arrowBeginA.x, ',')
            .concat(arrowBeginA.y, ' L')
            .concat(origin.x, ',')
            .concat(origin.y, ' L')
            .concat(arrowBeginB.x, ',')
            .concat(arrowBeginB.y)
        });
      }
  
      if (markup.lineDecoration.indexOf('arrow-end') !== -1) {
        var arrowEndRotationPoint = vectorMultiply(v, -l);
        var arrowEndCenter = vectorAdd(target, arrowEndRotationPoint);
        var arrowEndA = vectorRotate(target, 2, arrowEndCenter);
        var arrowEndB = vectorRotate(target, -2, arrowEndCenter);
  
        setAttributes(end, {
          style: 'display:block;',
          d: 'M'
            .concat(arrowEndA.x, ',')
            .concat(arrowEndA.y, ' L')
            .concat(target.x, ',')
            .concat(target.y, ' L')
            .concat(arrowEndB.x, ',')
            .concat(arrowEndB.y)
        });
      }
    };
  
    var updatePath = function updatePath(element, markup, size, scale) {
      setAttributes(
        element,
        Object.assign({}, element.styles, {
          fill: 'none',
          d: pointsToPathShape(
            markup.points.map(function(point) {
              return {
                x: getMarkupValue(point.x, size, scale, 'width'),
                y: getMarkupValue(point.y, size, scale, 'height')
              };
            })
          )
        })
      );
    };
  
    var createShape = function createShape(node) {
      return function(markup) {
        return svg(node, { id: markup.id });
      };
    };
  
    var createImage = function createImage(markup) {
      var shape = svg('image', {
        id: markup.id,
        'stroke-linecap': 'round',
        'stroke-linejoin': 'round',
        opacity: '0'
      });
  
      shape.onload = function() {
        shape.setAttribute('opacity', markup.opacity || 1);
      };
      shape.setAttributeNS(
        'http://www.w3.org/1999/xlink',
        'xlink:href',
        markup.src
      );
      return shape;
    };
  
    var createLine = function createLine(markup) {
      var shape = svg('g', {
        id: markup.id,
        'stroke-linecap': 'round',
        'stroke-linejoin': 'round'
      });
  
      var line = svg('line');
      shape.appendChild(line);
  
      var begin = svg('path');
      shape.appendChild(begin);
  
      var end = svg('path');
      shape.appendChild(end);
  
      return shape;
    };
  
    var CREATE_TYPE_ROUTES = {
      image: createImage,
      rect: createShape('rect'),
      ellipse: createShape('ellipse'),
      text: createShape('text'),
      path: createShape('path'),
      line: createLine
    };
  
    var UPDATE_TYPE_ROUTES = {
      rect: updateRect,
      ellipse: updateEllipse,
      image: updateImage,
      text: updateText,
      path: updatePath,
      line: updateLine
    };
  
    var createMarkupByType = function createMarkupByType(type, markup) {
      return CREATE_TYPE_ROUTES[type](markup);
    };
  
    var updateMarkupByType = function updateMarkupByType(
      element,
      type,
      markup,
      size,
      scale
    ) {
      if (type !== 'path') {
        element.rect = getMarkupRect(markup, size, scale);
      }
      element.styles = getMarkupStyles(markup, size, scale);
      UPDATE_TYPE_ROUTES[type](element, markup, size, scale);
    };
  
    var MARKUP_RECT = [
      'x',
      'y',
      'left',
      'top',
      'right',
      'bottom',
      'width',
      'height'
    ];
  
    var toOptionalFraction = function toOptionalFraction(value) {
      return typeof value === 'string' && /%/.test(value)
        ? parseFloat(value) / 100
        : value;
    };
  
    // adds default markup properties, clones markup
    var prepareMarkup = function prepareMarkup(markup) {
      var _markup = _slicedToArray(markup, 2),
        type = _markup[0],
        props = _markup[1];
  
      var rect = props.points
        ? {}
        : MARKUP_RECT.reduce(function(prev, curr) {
            prev[curr] = toOptionalFraction(props[curr]);
            return prev;
          }, {});
  
      return [
        type,
        Object.assign(
          {
            zIndex: 0
          },
          props,
          rect
        )
      ];
    };
  
    var sortMarkupByZIndex = function sortMarkupByZIndex(a, b) {
      if (a[1].zIndex > b[1].zIndex) {
        return 1;
      }
      if (a[1].zIndex < b[1].zIndex) {
        return -1;
      }
      return 0;
    };
  
    var createMarkupView = function createMarkupView(_) {
      return _.utils.createView({
        name: 'image-preview-markup',
        tag: 'svg',
        ignoreRect: true,
        mixins: {
          apis: ['width', 'height', 'crop', 'markup', 'resize', 'dirty']
        },
  
        write: function write(_ref) {
          var root = _ref.root,
            props = _ref.props;
  
          if (!props.dirty) return;
          var crop = props.crop,
            resize = props.resize,
            markup = props.markup;
  
          var viewWidth = props.width;
          var viewHeight = props.height;
  
          var cropWidth = crop.width;
          var cropHeight = crop.height;
  
          if (resize) {
            var _size = resize.size;
  
            var outputWidth = _size && _size.width;
            var outputHeight = _size && _size.height;
            var outputFit = resize.mode;
            var outputUpscale = resize.upscale;
  
            if (outputWidth && !outputHeight) outputHeight = outputWidth;
            if (outputHeight && !outputWidth) outputWidth = outputHeight;
  
            var shouldUpscale =
              cropWidth < outputWidth && cropHeight < outputHeight;
  
            if (!shouldUpscale || (shouldUpscale && outputUpscale)) {
              var scalarWidth = outputWidth / cropWidth;
              var scalarHeight = outputHeight / cropHeight;
  
              if (outputFit === 'force') {
                cropWidth = outputWidth;
                cropHeight = outputHeight;
              } else {
                var scalar;
                if (outputFit === 'cover') {
                  scalar = Math.max(scalarWidth, scalarHeight);
                } else if (outputFit === 'contain') {
                  scalar = Math.min(scalarWidth, scalarHeight);
                }
                cropWidth = cropWidth * scalar;
                cropHeight = cropHeight * scalar;
              }
            }
          }
  
          var size = {
            width: viewWidth,
            height: viewHeight
          };
  
          root.element.setAttribute('width', size.width);
          root.element.setAttribute('height', size.height);
  
          var scale = Math.min(viewWidth / cropWidth, viewHeight / cropHeight);
  
          // clear
          root.element.innerHTML = '';
  
          // get filter
          var markupFilter = root.query('GET_IMAGE_PREVIEW_MARKUP_FILTER');
  
          // draw new
          markup
            .filter(markupFilter)
            .map(prepareMarkup)
            .sort(sortMarkupByZIndex)
            .forEach(function(markup) {
              var _markup = _slicedToArray(markup, 2),
                type = _markup[0],
                settings = _markup[1];
  
              // create
              var element = createMarkupByType(type, settings);
  
              // update
              updateMarkupByType(element, type, settings, size, scale);
  
              // add
              root.element.appendChild(element);
            });
        }
      });
    };
  
    var createVector$1 = function createVector(x, y) {
      return { x: x, y: y };
    };
  
    var vectorDot = function vectorDot(a, b) {
      return a.x * b.x + a.y * b.y;
    };
  
    var vectorSubtract = function vectorSubtract(a, b) {
      return createVector$1(a.x - b.x, a.y - b.y);
    };
  
    var vectorDistanceSquared = function vectorDistanceSquared(a, b) {
      return vectorDot(vectorSubtract(a, b), vectorSubtract(a, b));
    };
  
    var vectorDistance = function vectorDistance(a, b) {
      return Math.sqrt(vectorDistanceSquared(a, b));
    };
  
    var getOffsetPointOnEdge = function getOffsetPointOnEdge(length, rotation) {
      var a = length;
  
      var A = 1.5707963267948966;
      var B = rotation;
      var C = 1.5707963267948966 - rotation;
  
      var sinA = Math.sin(A);
      var sinB = Math.sin(B);
      var sinC = Math.sin(C);
      var cosC = Math.cos(C);
      var ratio = a / sinA;
      var b = ratio * sinB;
      var c = ratio * sinC;
  
      return createVector$1(cosC * b, cosC * c);
    };
  
    var getRotatedRectSize = function getRotatedRectSize(rect, rotation) {
      var w = rect.width;
      var h = rect.height;
  
      var hor = getOffsetPointOnEdge(w, rotation);
      var ver = getOffsetPointOnEdge(h, rotation);
  
      var tl = createVector$1(rect.x + Math.abs(hor.x), rect.y - Math.abs(hor.y));
  
      var tr = createVector$1(
        rect.x + rect.width + Math.abs(ver.y),
        rect.y + Math.abs(ver.x)
      );
  
      var bl = createVector$1(
        rect.x - Math.abs(ver.y),
        rect.y + rect.height - Math.abs(ver.x)
      );
  
      return {
        width: vectorDistance(tl, tr),
        height: vectorDistance(tl, bl)
      };
    };
  
    var calculateCanvasSize = function calculateCanvasSize(
      image,
      canvasAspectRatio
    ) {
      var zoom =
        arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  
      var imageAspectRatio = image.height / image.width;
  
      // determine actual pixels on x and y axis
      var canvasWidth = 1;
      var canvasHeight = canvasAspectRatio;
      var imgWidth = 1;
      var imgHeight = imageAspectRatio;
      if (imgHeight > canvasHeight) {
        imgHeight = canvasHeight;
        imgWidth = imgHeight / imageAspectRatio;
      }
  
      var scalar = Math.max(canvasWidth / imgWidth, canvasHeight / imgHeight);
      var width = image.width / (zoom * scalar * imgWidth);
      var height = width * canvasAspectRatio;
  
      return {
        width: width,
        height: height
      };
    };
  
    var getImageRectZoomFactor = function getImageRectZoomFactor(
      imageRect,
      cropRect,
      rotation,
      center
    ) {
      // calculate available space round image center position
      var cx = center.x > 0.5 ? 1 - center.x : center.x;
      var cy = center.y > 0.5 ? 1 - center.y : center.y;
      var imageWidth = cx * 2 * imageRect.width;
      var imageHeight = cy * 2 * imageRect.height;
  
      // calculate rotated crop rectangle size
      var rotatedCropSize = getRotatedRectSize(cropRect, rotation);
  
      // calculate scalar required to fit image
      return Math.max(
        rotatedCropSize.width / imageWidth,
        rotatedCropSize.height / imageHeight
      );
    };
  
    var getCenteredCropRect = function getCenteredCropRect(
      container,
      aspectRatio
    ) {
      var width = container.width;
      var height = width * aspectRatio;
      if (height > container.height) {
        height = container.height;
        width = height / aspectRatio;
      }
      var x = (container.width - width) * 0.5;
      var y = (container.height - height) * 0.5;
  
      return {
        x: x,
        y: y,
        width: width,
        height: height
      };
    };
  
    var getCurrentCropSize = function getCurrentCropSize(imageSize) {
      var crop =
        arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var zoom = crop.zoom,
        rotation = crop.rotation,
        center = crop.center,
        aspectRatio = crop.aspectRatio;
  
      if (!aspectRatio) aspectRatio = imageSize.height / imageSize.width;
  
      var canvasSize = calculateCanvasSize(imageSize, aspectRatio, zoom);
  
      var canvasCenter = {
        x: canvasSize.width * 0.5,
        y: canvasSize.height * 0.5
      };
  
      var stage = {
        x: 0,
        y: 0,
        width: canvasSize.width,
        height: canvasSize.height,
        center: canvasCenter
      };
  
      var shouldLimit = typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;
  
      var stageZoomFactor = getImageRectZoomFactor(
        imageSize,
        getCenteredCropRect(stage, aspectRatio),
        rotation,
        shouldLimit ? center : { x: 0.5, y: 0.5 }
      );
  
      var scale = zoom * stageZoomFactor;
  
      // start drawing
      return {
        widthFloat: canvasSize.width / scale,
        heightFloat: canvasSize.height / scale,
        width: Math.round(canvasSize.width / scale),
        height: Math.round(canvasSize.height / scale)
      };
    };
  
    var IMAGE_SCALE_SPRING_PROPS = {
      type: 'spring',
      stiffness: 0.5,
      damping: 0.45,
      mass: 10
    };
  
    // does horizontal and vertical flipping
    var createBitmapView = function createBitmapView(_) {
      return _.utils.createView({
        name: 'image-bitmap',
        ignoreRect: true,
        mixins: { styles: ['scaleX', 'scaleY'] },
        create: function create(_ref) {
          var root = _ref.root,
            props = _ref.props;
          root.appendChild(props.image);
        }
      });
    };
  
    // shifts and rotates image
    var createImageCanvasWrapper = function createImageCanvasWrapper(_) {
      return _.utils.createView({
        name: 'image-canvas-wrapper',
        tag: 'div',
        ignoreRect: true,
        mixins: {
          apis: ['crop', 'width', 'height'],
  
          styles: [
            'originX',
            'originY',
            'translateX',
            'translateY',
            'scaleX',
            'scaleY',
            'rotateZ'
          ],
  
          animations: {
            originX: IMAGE_SCALE_SPRING_PROPS,
            originY: IMAGE_SCALE_SPRING_PROPS,
            scaleX: IMAGE_SCALE_SPRING_PROPS,
            scaleY: IMAGE_SCALE_SPRING_PROPS,
            translateX: IMAGE_SCALE_SPRING_PROPS,
            translateY: IMAGE_SCALE_SPRING_PROPS,
            rotateZ: IMAGE_SCALE_SPRING_PROPS
          }
        },
  
        create: function create(_ref2) {
          var root = _ref2.root,
            props = _ref2.props;
          props.width = props.image.width;
          props.height = props.image.height;
          root.ref.bitmap = root.appendChildView(
            root.createChildView(createBitmapView(_), { image: props.image })
          );
        },
        write: function write(_ref3) {
          var root = _ref3.root,
            props = _ref3.props;
          var flip = props.crop.flip;
          var bitmap = root.ref.bitmap;
          bitmap.scaleX = flip.horizontal ? -1 : 1;
          bitmap.scaleY = flip.vertical ? -1 : 1;
        }
      });
    };
  
    // clips canvas to correct aspect ratio
    var createClipView = function createClipView(_) {
      return _.utils.createView({
        name: 'image-clip',
        tag: 'div',
        ignoreRect: true,
        mixins: {
          apis: [
            'crop',
            'markup',
            'resize',
            'width',
            'height',
            'dirty',
            'background'
          ],
  
          styles: ['width', 'height', 'opacity'],
          animations: {
            opacity: { type: 'tween', duration: 250 }
          }
        },
  
        didWriteView: function didWriteView(_ref4) {
          var root = _ref4.root,
            props = _ref4.props;
          if (!props.background) return;
          root.element.style.backgroundColor = props.background;
        },
        create: function create(_ref5) {
          var root = _ref5.root,
            props = _ref5.props;
  
          root.ref.image = root.appendChildView(
            root.createChildView(
              createImageCanvasWrapper(_),
              Object.assign({}, props)
            )
          );
  
          root.ref.createMarkup = function() {
            if (root.ref.markup) return;
            root.ref.markup = root.appendChildView(
              root.createChildView(createMarkupView(_), Object.assign({}, props))
            );
          };
  
          root.ref.destroyMarkup = function() {
            if (!root.ref.markup) return;
            root.removeChildView(root.ref.markup);
            root.ref.markup = null;
          };
  
          // set up transparency grid
          var transparencyIndicator = root.query(
            'GET_IMAGE_PREVIEW_TRANSPARENCY_INDICATOR'
          );
          if (transparencyIndicator === null) return;
  
          // grid pattern
          if (transparencyIndicator === 'grid') {
            root.element.dataset.transparencyIndicator = transparencyIndicator;
          }
          // basic color
          else {
            root.element.dataset.transparencyIndicator = 'color';
          }
        },
        write: function write(_ref6) {
          var root = _ref6.root,
            props = _ref6.props,
            shouldOptimize = _ref6.shouldOptimize;
          var crop = props.crop,
            markup = props.markup,
            resize = props.resize,
            dirty = props.dirty,
            width = props.width,
            height = props.height;
  
          root.ref.image.crop = crop;
  
          var stage = {
            x: 0,
            y: 0,
            width: width,
            height: height,
            center: {
              x: width * 0.5,
              y: height * 0.5
            }
          };
  
          var image = {
            width: root.ref.image.width,
            height: root.ref.image.height
          };
  
          var origin = {
            x: crop.center.x * image.width,
            y: crop.center.y * image.height
          };
  
          var translation = {
            x: stage.center.x - image.width * crop.center.x,
            y: stage.center.y - image.height * crop.center.y
          };
  
          var rotation = Math.PI * 2 + (crop.rotation % (Math.PI * 2));
  
          var cropAspectRatio = crop.aspectRatio || image.height / image.width;
  
          var shouldLimit =
            typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;
  
          var stageZoomFactor = getImageRectZoomFactor(
            image,
            getCenteredCropRect(stage, cropAspectRatio),
  
            rotation,
            shouldLimit ? crop.center : { x: 0.5, y: 0.5 }
          );
  
          var scale = crop.zoom * stageZoomFactor;
  
          // update markup view
          if (markup && markup.length) {
            root.ref.createMarkup();
            root.ref.markup.width = width;
            root.ref.markup.height = height;
            root.ref.markup.resize = resize;
            root.ref.markup.dirty = dirty;
            root.ref.markup.markup = markup;
            root.ref.markup.crop = getCurrentCropSize(image, crop);
          } else if (root.ref.markup) {
            root.ref.destroyMarkup();
          }
  
          // update image view
          var imageView = root.ref.image;
  
          // don't update clip layout
          if (shouldOptimize) {
            imageView.originX = null;
            imageView.originY = null;
            imageView.translateX = null;
            imageView.translateY = null;
            imageView.rotateZ = null;
            imageView.scaleX = null;
            imageView.scaleY = null;
            return;
          }
  
          imageView.originX = origin.x;
          imageView.originY = origin.y;
          imageView.translateX = translation.x;
          imageView.translateY = translation.y;
          imageView.rotateZ = rotation;
          imageView.scaleX = scale;
          imageView.scaleY = scale;
        }
      });
    };
  
    var createImageView = function createImageView(_) {
      return _.utils.createView({
        name: 'image-preview',
        tag: 'div',
        ignoreRect: true,
        mixins: {
          apis: ['image', 'crop', 'markup', 'resize', 'dirty', 'background'],
  
          styles: ['translateY', 'scaleX', 'scaleY', 'opacity'],
  
          animations: {
            scaleX: IMAGE_SCALE_SPRING_PROPS,
            scaleY: IMAGE_SCALE_SPRING_PROPS,
            translateY: IMAGE_SCALE_SPRING_PROPS,
            opacity: { type: 'tween', duration: 400 }
          }
        },
  
        create: function create(_ref7) {
          var root = _ref7.root,
            props = _ref7.props;
          root.ref.clip = root.appendChildView(
            root.createChildView(createClipView(_), {
              id: props.id,
              image: props.image,
              crop: props.crop,
              markup: props.markup,
              resize: props.resize,
              dirty: props.dirty,
              background: props.background
            })
          );
        },
        write: function write(_ref8) {
          var root = _ref8.root,
            props = _ref8.props,
            shouldOptimize = _ref8.shouldOptimize;
          var clip = root.ref.clip;
          var image = props.image,
            crop = props.crop,
            markup = props.markup,
            resize = props.resize,
            dirty = props.dirty;
  
          clip.crop = crop;
          clip.markup = markup;
          clip.resize = resize;
          clip.dirty = dirty;
  
          // don't update clip layout
          clip.opacity = shouldOptimize ? 0 : 1;
  
          // don't re-render if optimizing or hidden (width will be zero resulting in weird animations)
          if (shouldOptimize || root.rect.element.hidden) return;
  
          // calculate scaled preview image size
          var imageAspectRatio = image.height / image.width;
          var aspectRatio = crop.aspectRatio || imageAspectRatio;
  
          // calculate container size
          var containerWidth = root.rect.inner.width;
          var containerHeight = root.rect.inner.height;
  
          var fixedPreviewHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');
          var minPreviewHeight = root.query('GET_IMAGE_PREVIEW_MIN_HEIGHT');
          var maxPreviewHeight = root.query('GET_IMAGE_PREVIEW_MAX_HEIGHT');
  
          var panelAspectRatio = root.query('GET_PANEL_ASPECT_RATIO');
          var allowMultiple = root.query('GET_ALLOW_MULTIPLE');
  
          if (panelAspectRatio && !allowMultiple) {
            fixedPreviewHeight = containerWidth * panelAspectRatio;
            aspectRatio = panelAspectRatio;
          }
  
          // determine clip width and height
          var clipHeight =
            fixedPreviewHeight !== null
              ? fixedPreviewHeight
              : Math.max(
                  minPreviewHeight,
                  Math.min(containerWidth * aspectRatio, maxPreviewHeight)
                );
  
          var clipWidth = clipHeight / aspectRatio;
          if (clipWidth > containerWidth) {
            clipWidth = containerWidth;
            clipHeight = clipWidth * aspectRatio;
          }
  
          if (clipHeight > containerHeight) {
            clipHeight = containerHeight;
            clipWidth = containerHeight / aspectRatio;
          }
  
          clip.width = clipWidth;
          clip.height = clipHeight;
        }
      });
    };
  
    var SVG_MASK =
      '<svg width="500" height="200" viewBox="0 0 500 200" preserveAspectRatio="none">\n    <defs>\n        <radialGradient id="gradient-__UID__" cx=".5" cy="1.25" r="1.15">\n            <stop offset=\'50%\' stop-color=\'#000000\'/>\n            <stop offset=\'56%\' stop-color=\'#0a0a0a\'/>\n            <stop offset=\'63%\' stop-color=\'#262626\'/>\n            <stop offset=\'69%\' stop-color=\'#4f4f4f\'/>\n            <stop offset=\'75%\' stop-color=\'#808080\'/>\n            <stop offset=\'81%\' stop-color=\'#b1b1b1\'/>\n            <stop offset=\'88%\' stop-color=\'#dadada\'/>\n            <stop offset=\'94%\' stop-color=\'#f6f6f6\'/>\n            <stop offset=\'100%\' stop-color=\'#ffffff\'/>\n        </radialGradient>\n        <mask id="mask-__UID__">\n            <rect x="0" y="0" width="500" height="200" fill="url(#gradient-__UID__)"></rect>\n        </mask>\n    </defs>\n    <rect x="0" width="500" height="200" fill="currentColor" mask="url(#mask-__UID__)"></rect>\n</svg>';
  
    var SVGMaskUniqueId = 0;
  
    var createImageOverlayView = function createImageOverlayView(fpAPI) {
      return fpAPI.utils.createView({
        name: 'image-preview-overlay',
        tag: 'div',
        ignoreRect: true,
        create: function create(_ref) {
          var root = _ref.root,
            props = _ref.props;
          var mask = SVG_MASK;
          if (document.querySelector('base')) {
            var url = new URL(
              window.location.href.replace(window.location.hash, '')
            ).href;
            mask = mask.replace(/url\(\#/g, 'url(' + url + '#');
          }
  
          SVGMaskUniqueId++;
          root.element.classList.add(
            'filepond--image-preview-overlay-'.concat(props.status)
          );
  
          root.element.innerHTML = mask.replace(/__UID__/g, SVGMaskUniqueId);
        },
        mixins: {
          styles: ['opacity'],
          animations: {
            opacity: { type: 'spring', mass: 25 }
          }
        }
      });
    };
  
    /**
     * Bitmap Worker
     */
    var BitmapWorker = function BitmapWorker() {
      self.onmessage = function(e) {
        createImageBitmap(e.data.message.file).then(function(bitmap) {
          self.postMessage({ id: e.data.id, message: bitmap }, [bitmap]);
        });
      };
    };
  
    /**
     * ColorMatrix Worker
     */
    var ColorMatrixWorker = function ColorMatrixWorker() {
      self.onmessage = function(e) {
        var imageData = e.data.message.imageData;
        var matrix = e.data.message.colorMatrix;
  
        var data = imageData.data;
        var l = data.length;
  
        var m11 = matrix[0];
        var m12 = matrix[1];
        var m13 = matrix[2];
        var m14 = matrix[3];
        var m15 = matrix[4];
  
        var m21 = matrix[5];
        var m22 = matrix[6];
        var m23 = matrix[7];
        var m24 = matrix[8];
        var m25 = matrix[9];
  
        var m31 = matrix[10];
        var m32 = matrix[11];
        var m33 = matrix[12];
        var m34 = matrix[13];
        var m35 = matrix[14];
  
        var m41 = matrix[15];
        var m42 = matrix[16];
        var m43 = matrix[17];
        var m44 = matrix[18];
        var m45 = matrix[19];
  
        var index = 0,
          r = 0.0,
          g = 0.0,
          b = 0.0,
          a = 0.0;
  
        for (; index < l; index += 4) {
          r = data[index] / 255;
          g = data[index + 1] / 255;
          b = data[index + 2] / 255;
          a = data[index + 3] / 255;
          data[index] = Math.max(
            0,
            Math.min((r * m11 + g * m12 + b * m13 + a * m14 + m15) * 255, 255)
          );
          data[index + 1] = Math.max(
            0,
            Math.min((r * m21 + g * m22 + b * m23 + a * m24 + m25) * 255, 255)
          );
          data[index + 2] = Math.max(
            0,
            Math.min((r * m31 + g * m32 + b * m33 + a * m34 + m35) * 255, 255)
          );
          data[index + 3] = Math.max(
            0,
            Math.min((r * m41 + g * m42 + b * m43 + a * m44 + m45) * 255, 255)
          );
        }
  
        self.postMessage({ id: e.data.id, message: imageData }, [
          imageData.data.buffer
        ]);
      };
    };
  
    var getImageSize = function getImageSize(url, cb) {
      var image = new Image();
      image.onload = function() {
        var width = image.naturalWidth;
        var height = image.naturalHeight;
        image = null;
        cb(width, height);
      };
      image.src = url;
    };
  
    var transforms = {
      1: function _() {
        return [1, 0, 0, 1, 0, 0];
      },
      2: function _(width) {
        return [-1, 0, 0, 1, width, 0];
      },
      3: function _(width, height) {
        return [-1, 0, 0, -1, width, height];
      },
      4: function _(width, height) {
        return [1, 0, 0, -1, 0, height];
      },
      5: function _() {
        return [0, 1, 1, 0, 0, 0];
      },
      6: function _(width, height) {
        return [0, 1, -1, 0, height, 0];
      },
      7: function _(width, height) {
        return [0, -1, -1, 0, height, width];
      },
      8: function _(width) {
        return [0, -1, 1, 0, 0, width];
      }
    };
  
    var fixImageOrientation = function fixImageOrientation(
      ctx,
      width,
      height,
      orientation
    ) {
      // no orientation supplied
      if (orientation === -1) {
        return;
      }
  
      ctx.transform.apply(ctx, transforms[orientation](width, height));
    };
  
    // draws the preview image to canvas
    var createPreviewImage = function createPreviewImage(
      data,
      width,
      height,
      orientation
    ) {
      // can't draw on half pixels
      width = Math.round(width);
      height = Math.round(height);
  
      // draw image
      var canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext('2d');
  
      // if is rotated incorrectly swap width and height
      if (orientation >= 5 && orientation <= 8) {
        var _ref = [height, width];
        width = _ref[0];
        height = _ref[1];
      }
  
      // correct image orientation
      fixImageOrientation(ctx, width, height, orientation);
  
      // draw the image
      ctx.drawImage(data, 0, 0, width, height);
  
      return canvas;
    };
  
    var isBitmap = function isBitmap(file) {
      return /^image/.test(file.type) && !/svg/.test(file.type);
    };
  
    var MAX_WIDTH = 10;
    var MAX_HEIGHT = 10;
  
    var calculateAverageColor = function calculateAverageColor(image) {
      var scalar = Math.min(MAX_WIDTH / image.width, MAX_HEIGHT / image.height);
  
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var width = (canvas.width = Math.ceil(image.width * scalar));
      var height = (canvas.height = Math.ceil(image.height * scalar));
      ctx.drawImage(image, 0, 0, width, height);
      var data = null;
      try {
        data = ctx.getImageData(0, 0, width, height).data;
      } catch (e) {
        return null;
      }
      var l = data.length;
  
      var r = 0;
      var g = 0;
      var b = 0;
      var i = 0;
  
      for (; i < l; i += 4) {
        r += data[i] * data[i];
        g += data[i + 1] * data[i + 1];
        b += data[i + 2] * data[i + 2];
      }
  
      r = averageColor(r, l);
      g = averageColor(g, l);
      b = averageColor(b, l);
  
      return { r: r, g: g, b: b };
    };
  
    var averageColor = function averageColor(c, l) {
      return Math.floor(Math.sqrt(c / (l / 4)));
    };
  
    var cloneCanvas = function cloneCanvas(origin, target) {
      target = target || document.createElement('canvas');
      target.width = origin.width;
      target.height = origin.height;
      var ctx = target.getContext('2d');
      ctx.drawImage(origin, 0, 0);
      return target;
    };
  
    var cloneImageData = function cloneImageData(imageData) {
      var id;
      try {
        id = new ImageData(imageData.width, imageData.height);
      } catch (e) {
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        id = ctx.createImageData(imageData.width, imageData.height);
      }
      id.data.set(new Uint8ClampedArray(imageData.data));
      return id;
    };
  
    var loadImage = function loadImage(url) {
      return new Promise(function(resolve, reject) {
        var img = new Image();
        img.crossOrigin = 'Anonymous';
        img.onload = function() {
          resolve(img);
        };
        img.onerror = function(e) {
          reject(e);
        };
        img.src = url;
      });
    };
  
    var createImageWrapperView = function createImageWrapperView(_) {
      // create overlay view
      var OverlayView = createImageOverlayView(_);
  
      var ImageView = createImageView(_);
      var createWorker = _.utils.createWorker;
  
      var applyFilter = function applyFilter(root, filter, target) {
        return new Promise(function(resolve) {
          // will store image data for future filter updates
          if (!root.ref.imageData) {
            root.ref.imageData = target
              .getContext('2d')
              .getImageData(0, 0, target.width, target.height);
          }
  
          // get image data reference
          var imageData = cloneImageData(root.ref.imageData);
  
          if (!filter || filter.length !== 20) {
            target.getContext('2d').putImageData(imageData, 0, 0);
            return resolve();
          }
  
          var worker = createWorker(ColorMatrixWorker);
          worker.post(
            {
              imageData: imageData,
              colorMatrix: filter
            },
  
            function(response) {
              // apply filtered colors
              target.getContext('2d').putImageData(response, 0, 0);
  
              // stop worker
              worker.terminate();
  
              // done!
              resolve();
            },
            [imageData.data.buffer]
          );
        });
      };
  
      var removeImageView = function removeImageView(root, imageView) {
        root.removeChildView(imageView);
        imageView.image.width = 1;
        imageView.image.height = 1;
        imageView._destroy();
      };
  
      // remove an image
      var shiftImage = function shiftImage(_ref) {
        var root = _ref.root;
        var imageView = root.ref.images.shift();
        imageView.opacity = 0;
        imageView.translateY = -15;
        root.ref.imageViewBin.push(imageView);
        return imageView;
      };
  
      // add new image
      var pushImage = function pushImage(_ref2) {
        var root = _ref2.root,
          props = _ref2.props,
          image = _ref2.image;
        var id = props.id;
        var item = root.query('GET_ITEM', { id: id });
        if (!item) return;
  
        var crop = item.getMetadata('crop') || {
          center: {
            x: 0.5,
            y: 0.5
          },
  
          flip: {
            horizontal: false,
            vertical: false
          },
  
          zoom: 1,
          rotation: 0,
          aspectRatio: null
        };
  
        var background = root.query(
          'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'
        );
  
        var markup;
        var resize;
        var dirty = false;
        if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {
          markup = item.getMetadata('markup') || [];
          resize = item.getMetadata('resize');
          dirty = true;
        }
  
        // append image presenter
        var imageView = root.appendChildView(
          root.createChildView(ImageView, {
            id: id,
            image: image,
            crop: crop,
            resize: resize,
            markup: markup,
            dirty: dirty,
            background: background,
            opacity: 0,
            scaleX: 1.15,
            scaleY: 1.15,
            translateY: 15
          }),
  
          root.childViews.length
        );
  
        root.ref.images.push(imageView);
  
        // reveal the preview image
        imageView.opacity = 1;
        imageView.scaleX = 1;
        imageView.scaleY = 1;
        imageView.translateY = 0;
  
        // the preview is now ready to be drawn
        setTimeout(function() {
          root.dispatch('DID_IMAGE_PREVIEW_SHOW', { id: id });
        }, 250);
      };
  
      var updateImage = function updateImage(_ref3) {
        var root = _ref3.root,
          props = _ref3.props;
        var item = root.query('GET_ITEM', { id: props.id });
        if (!item) return;
        var imageView = root.ref.images[root.ref.images.length - 1];
        imageView.crop = item.getMetadata('crop');
        imageView.background = root.query(
          'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'
        );
  
        if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {
          imageView.dirty = true;
          imageView.resize = item.getMetadata('resize');
          imageView.markup = item.getMetadata('markup');
        }
      };
  
      // replace image preview
      var didUpdateItemMetadata = function didUpdateItemMetadata(_ref4) {
        var root = _ref4.root,
          props = _ref4.props,
          action = _ref4.action;
        // only filter and crop trigger redraw
        if (!/crop|filter|markup|resize/.test(action.change.key)) return;
  
        // no images to update, exit
        if (!root.ref.images.length) return;
  
        // no item found, exit
        var item = root.query('GET_ITEM', { id: props.id });
        if (!item) return;
  
        // for now, update existing image when filtering
        if (/filter/.test(action.change.key)) {
          var imageView = root.ref.images[root.ref.images.length - 1];
          applyFilter(root, action.change.value, imageView.image);
          return;
        }
  
        if (/crop|markup|resize/.test(action.change.key)) {
          var crop = item.getMetadata('crop');
          var image = root.ref.images[root.ref.images.length - 1];
  
          // if aspect ratio has changed, we need to create a new image
          if (
            crop &&
            crop.aspectRatio &&
            image.crop &&
            image.crop.aspectRatio &&
            Math.abs(crop.aspectRatio - image.crop.aspectRatio) > 0.00001
          ) {
            var _imageView = shiftImage({ root: root });
            pushImage({
              root: root,
              props: props,
              image: cloneCanvas(_imageView.image)
            });
          }
          // if not, we can update the current image
          else {
            updateImage({ root: root, props: props });
          }
        }
      };
  
      var canCreateImageBitmap = function canCreateImageBitmap(file) {
        // Firefox versions before 58 will freeze when running createImageBitmap
        // in a Web Worker so we detect those versions and return false for support
        var userAgent = window.navigator.userAgent;
        var isFirefox = userAgent.match(/Firefox\/([0-9]+)\./);
        var firefoxVersion = isFirefox ? parseInt(isFirefox[1]) : null;
        if (firefoxVersion <= 58) return false;
  
        return 'createImageBitmap' in window && isBitmap(file);
      };
  
      /**
       * Write handler for when preview container has been created
       */
      var didCreatePreviewContainer = function didCreatePreviewContainer(_ref5) {
        var root = _ref5.root,
          props = _ref5.props;
        var id = props.id;
  
        // we need to get the file data to determine the eventual image size
        var item = root.query('GET_ITEM', id);
        if (!item) return;
  
        // get url to file (we'll revoke it later on when done)
        var fileURL = URL.createObjectURL(item.file);
  
        // determine image size of this item
        getImageSize(fileURL, function(width, height) {
          // we can now scale the panel to the final size
          root.dispatch('DID_IMAGE_PREVIEW_CALCULATE_SIZE', {
            id: id,
            width: width,
            height: height
          });
        });
      };
  
      var drawPreview = function drawPreview(_ref6) {
        var root = _ref6.root,
          props = _ref6.props;
        var id = props.id;
  
        // we need to get the file data to determine the eventual image size
        var item = root.query('GET_ITEM', id);
        if (!item) return;
  
        // get url to file (we'll revoke it later on when done)
        var fileURL = URL.createObjectURL(item.file);
  
        // fallback
        var loadPreviewFallback = function loadPreviewFallback() {
          // let's scale the image in the main thread :(
          loadImage(fileURL).then(previewImageLoaded);
        };
  
        // image is now ready
        var previewImageLoaded = function previewImageLoaded(imageData) {
          // the file url is no longer needed
          URL.revokeObjectURL(fileURL);
  
          // draw the scaled down version here and use that as source so bitmapdata can be closed
          // orientation info
          var exif = item.getMetadata('exif') || {};
          var orientation = exif.orientation || -1;
  
          // get width and height from action, and swap if orientation is incorrect
          var width = imageData.width,
            height = imageData.height;
  
          // if no width or height, just return early.
          if (!width || !height) return;
  
          if (orientation >= 5 && orientation <= 8) {
            var _ref7 = [height, width];
            width = _ref7[0];
            height = _ref7[1];
          }
  
          // scale canvas based on pixel density
          // we multiply by .75 as that creates smaller but still clear images on screens with high res displays
          var pixelDensityFactor = Math.max(1, window.devicePixelRatio * 0.75);
  
          // we want as much pixels to work with as possible,
          // this multiplies the minimum image resolution,
          // so when zooming in it doesn't get too blurry
          var zoomFactor = root.query('GET_IMAGE_PREVIEW_ZOOM_FACTOR');
  
          // imaeg scale factor
          var scaleFactor = zoomFactor * pixelDensityFactor;
  
          // calculate scaled preview image size
          var previewImageRatio = height / width;
  
          // calculate image preview height and width
          var previewContainerWidth = root.rect.element.width;
          var previewContainerHeight = root.rect.element.height;
  
          var imageWidth = previewContainerWidth;
          var imageHeight = imageWidth * previewImageRatio;
  
          if (previewImageRatio > 1) {
            imageWidth = Math.min(width, previewContainerWidth * scaleFactor);
            imageHeight = imageWidth * previewImageRatio;
          } else {
            imageHeight = Math.min(height, previewContainerHeight * scaleFactor);
            imageWidth = imageHeight / previewImageRatio;
          }
  
          // transfer to image tag so no canvas memory wasted on iOS
          var previewImage = createPreviewImage(
            imageData,
            imageWidth,
            imageHeight,
            orientation
          );
  
          // done
          var done = function done() {
            // calculate average image color, disabled for now
            var averageColor = root.query(
              'GET_IMAGE_PREVIEW_CALCULATE_AVERAGE_IMAGE_COLOR'
            )
              ? calculateAverageColor(data)
              : null;
            item.setMetadata('color', averageColor, true);
  
            // data has been transferred to canvas ( if was ImageBitmap )
            if ('close' in imageData) {
              imageData.close();
            }
  
            // show the overlay
            root.ref.overlayShadow.opacity = 1;
  
            // create the first image
            pushImage({ root: root, props: props, image: previewImage });
          };
  
          // apply filter
          var filter = item.getMetadata('filter');
          if (filter) {
            applyFilter(root, filter, previewImage).then(done);
          } else {
            done();
          }
        };
  
        // if we support scaling using createImageBitmap we use a worker
        if (canCreateImageBitmap(item.file)) {
          // let's scale the image in a worker
          var worker = createWorker(BitmapWorker);
  
          worker.post(
            {
              file: item.file
            },
  
            function(imageBitmap) {
              // destroy worker
              worker.terminate();
  
              // no bitmap returned, must be something wrong,
              // try the oldschool way
              if (!imageBitmap) {
                loadPreviewFallback();
                return;
              }
  
              // yay we got our bitmap, let's continue showing the preview
              previewImageLoaded(imageBitmap);
            }
          );
        } else {
          // create fallback preview
          loadPreviewFallback();
        }
      };
  
      /**
       * Write handler for when the preview image is ready to be animated
       */
      var didDrawPreview = function didDrawPreview(_ref8) {
        var root = _ref8.root;
        // get last added image
        var image = root.ref.images[root.ref.images.length - 1];
        image.translateY = 0;
        image.scaleX = 1.0;
        image.scaleY = 1.0;
        image.opacity = 1;
      };
  
      /**
       * Write handler for when the preview has been loaded
       */
      var restoreOverlay = function restoreOverlay(_ref9) {
        var root = _ref9.root;
        root.ref.overlayShadow.opacity = 1;
        root.ref.overlayError.opacity = 0;
        root.ref.overlaySuccess.opacity = 0;
      };
  
      var didThrowError = function didThrowError(_ref10) {
        var root = _ref10.root;
        root.ref.overlayShadow.opacity = 0.25;
        root.ref.overlayError.opacity = 1;
      };
  
      var didCompleteProcessing = function didCompleteProcessing(_ref11) {
        var root = _ref11.root;
        root.ref.overlayShadow.opacity = 0.25;
        root.ref.overlaySuccess.opacity = 1;
      };
  
      /**
       * Constructor
       */
      var create = function create(_ref12) {
        var root = _ref12.root;
        // image view
        root.ref.images = [];
  
        // the preview image data (we need this to filter the image)
        root.ref.imageData = null;
  
        // image bin
        root.ref.imageViewBin = [];
  
        // image overlays
        root.ref.overlayShadow = root.appendChildView(
          root.createChildView(OverlayView, {
            opacity: 0,
            status: 'idle'
          })
        );
  
        root.ref.overlaySuccess = root.appendChildView(
          root.createChildView(OverlayView, {
            opacity: 0,
            status: 'success'
          })
        );
  
        root.ref.overlayError = root.appendChildView(
          root.createChildView(OverlayView, {
            opacity: 0,
            status: 'failure'
          })
        );
      };
  
      return _.utils.createView({
        name: 'image-preview-wrapper',
        create: create,
        styles: ['height'],
        apis: ['height'],
        destroy: function destroy(_ref13) {
          var root = _ref13.root;
          // we resize the image so memory on iOS 12 is released more quickly (it seems)
          root.ref.images.forEach(function(imageView) {
            imageView.image.width = 1;
            imageView.image.height = 1;
          });
        },
        didWriteView: function didWriteView(_ref14) {
          var root = _ref14.root;
          root.ref.images.forEach(function(imageView) {
            imageView.dirty = false;
          });
        },
        write: _.utils.createRoute(
          {
            // image preview stated
            DID_IMAGE_PREVIEW_DRAW: didDrawPreview,
            DID_IMAGE_PREVIEW_CONTAINER_CREATE: didCreatePreviewContainer,
            DID_FINISH_CALCULATE_PREVIEWSIZE: drawPreview,
            DID_UPDATE_ITEM_METADATA: didUpdateItemMetadata,
  
            // file states
            DID_THROW_ITEM_LOAD_ERROR: didThrowError,
            DID_THROW_ITEM_PROCESSING_ERROR: didThrowError,
            DID_THROW_ITEM_INVALID: didThrowError,
            DID_COMPLETE_ITEM_PROCESSING: didCompleteProcessing,
            DID_START_ITEM_PROCESSING: restoreOverlay,
            DID_REVERT_ITEM_PROCESSING: restoreOverlay
          },
  
          function(_ref15) {
            var root = _ref15.root;
            // views on death row
            var viewsToRemove = root.ref.imageViewBin.filter(function(imageView) {
              return imageView.opacity === 0;
            });
  
            // views to retain
            root.ref.imageViewBin = root.ref.imageViewBin.filter(function(
              imageView
            ) {
              return imageView.opacity > 0;
            });
  
            // remove these views
            viewsToRemove.forEach(function(imageView) {
              return removeImageView(root, imageView);
            });
            viewsToRemove.length = 0;
          }
        )
      });
    };
  
    /**
     * Image Preview Plugin
     */
    var plugin = function plugin(fpAPI) {
      var addFilter = fpAPI.addFilter,
        utils = fpAPI.utils;
      var Type = utils.Type,
        createRoute = utils.createRoute,
        isFile = utils.isFile;
  
      // imagePreviewView
      var imagePreviewView = createImageWrapperView(fpAPI);
  
      // called for each view that is created right after the 'create' method
      addFilter('CREATE_VIEW', function(viewAPI) {
        // get reference to created view
        var is = viewAPI.is,
          view = viewAPI.view,
          query = viewAPI.query;
  
        // only hook up to item view and only if is enabled for this cropper
        if (!is('file') || !query('GET_ALLOW_IMAGE_PREVIEW')) return;
  
        // create the image preview plugin, but only do so if the item is an image
        var didLoadItem = function didLoadItem(_ref) {
          var root = _ref.root,
            props = _ref.props;
          var id = props.id;
          var item = query('GET_ITEM', id);
  
          // item could theoretically have been removed in the mean time
          if (!item || !isFile(item.file) || item.archived) return;
  
          // get the file object
          var file = item.file;
  
          // exit if this is not an image
          if (!isPreviewableImage(file)) return;
  
          // test if is filtered
          if (!query('GET_IMAGE_PREVIEW_FILTER_ITEM')(item)) return;
  
          // exit if image size is too high and no createImageBitmap support
          // this would simply bring the browser to its knees and that is not what we want
          var supportsCreateImageBitmap = 'createImageBitmap' in (window || {});
          var maxPreviewFileSize = query('GET_IMAGE_PREVIEW_MAX_FILE_SIZE');
          if (
            !supportsCreateImageBitmap &&
            maxPreviewFileSize &&
            file.size > maxPreviewFileSize
          )
            return;
  
          // set preview view
          root.ref.imagePreview = view.appendChildView(
            view.createChildView(imagePreviewView, { id: id })
          );
  
          // update height if is fixed
          var fixedPreviewHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');
          if (fixedPreviewHeight) {
            root.dispatch('DID_UPDATE_PANEL_HEIGHT', {
              id: item.id,
              height: fixedPreviewHeight
            });
          }
  
          // now ready
          var queue =
            !supportsCreateImageBitmap &&
            file.size > query('GET_IMAGE_PREVIEW_MAX_INSTANT_PREVIEW_FILE_SIZE');
          root.dispatch('DID_IMAGE_PREVIEW_CONTAINER_CREATE', { id: id }, queue);
        };
  
        var rescaleItem = function rescaleItem(root, props) {
          if (!root.ref.imagePreview) return;
          var id = props.id;
  
          // get item
          var item = root.query('GET_ITEM', { id: id });
          if (!item) return;
  
          // if is fixed height or panel has aspect ratio, exit here, height has already been defined
          var panelAspectRatio = root.query('GET_PANEL_ASPECT_RATIO');
          var itemPanelAspectRatio = root.query('GET_ITEM_PANEL_ASPECT_RATIO');
          var fixedHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');
          if (panelAspectRatio || itemPanelAspectRatio || fixedHeight) return;
  
          // no data!
          var _root$ref = root.ref,
            imageWidth = _root$ref.imageWidth,
            imageHeight = _root$ref.imageHeight;
          if (!imageWidth || !imageHeight) return;
  
          // get height min and max
          var minPreviewHeight = root.query('GET_IMAGE_PREVIEW_MIN_HEIGHT');
          var maxPreviewHeight = root.query('GET_IMAGE_PREVIEW_MAX_HEIGHT');
  
          // orientation info
          var exif = item.getMetadata('exif') || {};
          var orientation = exif.orientation || -1;
  
          // get width and height from action, and swap of orientation is incorrect
          if (orientation >= 5 && orientation <= 8) {
            var _ref2 = [imageHeight, imageWidth];
            imageWidth = _ref2[0];
            imageHeight = _ref2[1];
          }
  
          // scale up width and height when we're dealing with an SVG
          if (!isBitmap(item.file) || root.query('GET_IMAGE_PREVIEW_UPSCALE')) {
            var scalar = 2048 / imageWidth;
            imageWidth *= scalar;
            imageHeight *= scalar;
          }
  
          // image aspect ratio
          var imageAspectRatio = imageHeight / imageWidth;
  
          // we need the item to get to the crop size
          var previewAspectRatio =
            (item.getMetadata('crop') || {}).aspectRatio || imageAspectRatio;
  
          // preview height range
          var previewHeightMax = Math.max(
            minPreviewHeight,
            Math.min(imageHeight, maxPreviewHeight)
          );
  
          var itemWidth = root.rect.element.width;
          var previewHeight = Math.min(
            itemWidth * previewAspectRatio,
            previewHeightMax
          );
  
          // request update to panel height
          root.dispatch('DID_UPDATE_PANEL_HEIGHT', {
            id: item.id,
            height: previewHeight
          });
        };
  
        var didResizeView = function didResizeView(_ref3) {
          var root = _ref3.root;
          // actions in next write operation
          root.ref.shouldRescale = true;
        };
  
        var didUpdateItemMetadata = function didUpdateItemMetadata(_ref4) {
          var root = _ref4.root,
            action = _ref4.action;
          if (action.change.key !== 'crop') return;
  
          // actions in next write operation
          root.ref.shouldRescale = true;
        };
  
        var didCalculatePreviewSize = function didCalculatePreviewSize(_ref5) {
          var root = _ref5.root,
            action = _ref5.action;
          // remember dimensions
          root.ref.imageWidth = action.width;
          root.ref.imageHeight = action.height;
  
          // actions in next write operation
          root.ref.shouldRescale = true;
          root.ref.shouldDrawPreview = true;
  
          // as image load could take a while and fire when draw loop is resting we need to give it a kick
          root.dispatch('KICK');
        };
  
        // start writing
        view.registerWriter(
          createRoute(
            {
              DID_RESIZE_ROOT: didResizeView,
              DID_STOP_RESIZE: didResizeView,
              DID_LOAD_ITEM: didLoadItem,
              DID_IMAGE_PREVIEW_CALCULATE_SIZE: didCalculatePreviewSize,
              DID_UPDATE_ITEM_METADATA: didUpdateItemMetadata
            },
  
            function(_ref6) {
              var root = _ref6.root,
                props = _ref6.props;
              // no preview view attached
              if (!root.ref.imagePreview) return;
  
              // don't do anything while hidden
              if (root.rect.element.hidden) return;
  
              // resize the item panel
              if (root.ref.shouldRescale) {
                rescaleItem(root, props);
                root.ref.shouldRescale = false;
              }
  
              if (root.ref.shouldDrawPreview) {
                // queue till next frame so we're sure the height has been applied this forces the draw image call inside the wrapper view to use the correct height
                requestAnimationFrame(function() {
                  // this requestAnimationFrame nesting is horrible but it fixes an issue with 100hz displays on Chrome
                  // https://github.com/pqina/filepond-plugin-image-preview/issues/57
                  requestAnimationFrame(function() {
                    root.dispatch('DID_FINISH_CALCULATE_PREVIEWSIZE', {
                      id: props.id
                    });
                  });
                });
  
                root.ref.shouldDrawPreview = false;
              }
            }
          )
        );
      });
  
      // expose plugin
      return {
        options: {
          // Enable or disable image preview
          allowImagePreview: [true, Type.BOOLEAN],
  
          // filters file items to determine which are shown as preview
          imagePreviewFilterItem: [
            function() {
              return true;
            },
            Type.FUNCTION
          ],
  
          // Fixed preview height
          imagePreviewHeight: [null, Type.INT],
  
          // Min image height
          imagePreviewMinHeight: [44, Type.INT],
  
          // Max image height
          imagePreviewMaxHeight: [256, Type.INT],
  
          // Max size of preview file for when createImageBitmap is not supported
          imagePreviewMaxFileSize: [null, Type.INT],
  
          // The amount of extra pixels added to the image preview to allow comfortable zooming
          imagePreviewZoomFactor: [2, Type.INT],
  
          // Should we upscale small images to fit the max bounding box of the preview area
          imagePreviewUpscale: [false, Type.BOOLEAN],
  
          // Max size of preview file that we allow to try to instant preview if createImageBitmap is not supported, else image is queued for loading
          imagePreviewMaxInstantPreviewFileSize: [1000000, Type.INT],
  
          // Style of the transparancy indicator used behind images
          imagePreviewTransparencyIndicator: [null, Type.STRING],
  
          // Enables or disables reading average image color
          imagePreviewCalculateAverageImageColor: [false, Type.BOOLEAN],
  
          // Enables or disables the previewing of markup
          imagePreviewMarkupShow: [true, Type.BOOLEAN],
  
          // Allows filtering of markup to only show certain shapes
          imagePreviewMarkupFilter: [
            function() {
              return true;
            },
            Type.FUNCTION
          ]
        }
      };
    };
  
    // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags
    var isBrowser =
      typeof window !== 'undefined' && typeof window.document !== 'undefined';
    if (isBrowser) {
      document.dispatchEvent(
        new CustomEvent('FilePond:pluginloaded', { detail: plugin })
      );
    }
  
    return plugin;
  });
  