text: (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexloadingprogressplugin = factory());
  })(this, (function () { 'use strict';
  
    function _regeneratorRuntime() {
      /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
  
      _regeneratorRuntime = function () {
        return exports;
      };
  
      var exports = {},
          Op = Object.prototype,
          hasOwn = Op.hasOwnProperty,
          $Symbol = "function" == typeof Symbol ? Symbol : {},
          iteratorSymbol = $Symbol.iterator || "@@iterator",
          asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
          toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  
      function define(obj, key, value) {
        return Object.defineProperty(obj, key, {
          value: value,
          enumerable: !0,
          configurable: !0,
          writable: !0
        }), obj[key];
      }
  
      try {
        define({}, "");
      } catch (err) {
        define = function (obj, key, value) {
          return obj[key] = value;
        };
      }
  
      function wrap(innerFn, outerFn, self, tryLocsList) {
        var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
            generator = Object.create(protoGenerator.prototype),
            context = new Context(tryLocsList || []);
        return generator._invoke = function (innerFn, self, context) {
          var state = "suspendedStart";
          return function (method, arg) {
            if ("executing" === state) throw new Error("Generator is already running");
  
            if ("completed" === state) {
              if ("throw" === method) throw arg;
              return doneResult();
            }
  
            for (context.method = method, context.arg = arg;;) {
              var delegate = context.delegate;
  
              if (delegate) {
                var delegateResult = maybeInvokeDelegate(delegate, context);
  
                if (delegateResult) {
                  if (delegateResult === ContinueSentinel) continue;
                  return delegateResult;
                }
              }
  
              if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
                if ("suspendedStart" === state) throw state = "completed", context.arg;
                context.dispatchException(context.arg);
              } else "return" === context.method && context.abrupt("return", context.arg);
              state = "executing";
              var record = tryCatch(innerFn, self, context);
  
              if ("normal" === record.type) {
                if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
                return {
                  value: record.arg,
                  done: context.done
                };
              }
  
              "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
            }
          };
        }(innerFn, self, context), generator;
      }
  
      function tryCatch(fn, obj, arg) {
        try {
          return {
            type: "normal",
            arg: fn.call(obj, arg)
          };
        } catch (err) {
          return {
            type: "throw",
            arg: err
          };
        }
      }
  
      exports.wrap = wrap;
      var ContinueSentinel = {};
  
      function Generator() {}
  
      function GeneratorFunction() {}
  
      function GeneratorFunctionPrototype() {}
  
      var IteratorPrototype = {};
      define(IteratorPrototype, iteratorSymbol, function () {
        return this;
      });
      var getProto = Object.getPrototypeOf,
          NativeIteratorPrototype = getProto && getProto(getProto(values([])));
      NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
      var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
  
      function defineIteratorMethods(prototype) {
        ["next", "throw", "return"].forEach(function (method) {
          define(prototype, method, function (arg) {
            return this._invoke(method, arg);
          });
        });
      }
  
      function AsyncIterator(generator, PromiseImpl) {
        function invoke(method, arg, resolve, reject) {
          var record = tryCatch(generator[method], generator, arg);
  
          if ("throw" !== record.type) {
            var result = record.arg,
                value = result.value;
            return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
              invoke("next", value, resolve, reject);
            }, function (err) {
              invoke("throw", err, resolve, reject);
            }) : PromiseImpl.resolve(value).then(function (unwrapped) {
              result.value = unwrapped, resolve(result);
            }, function (error) {
              return invoke("throw", error, resolve, reject);
            });
          }
  
          reject(record.arg);
        }
  
        var previousPromise;
  
        this._invoke = function (method, arg) {
          function callInvokeWithMethodAndArg() {
            return new PromiseImpl(function (resolve, reject) {
              invoke(method, arg, resolve, reject);
            });
          }
  
          return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
        };
      }
  
      function maybeInvokeDelegate(delegate, context) {
        var method = delegate.iterator[context.method];
  
        if (undefined === method) {
          if (context.delegate = null, "throw" === context.method) {
            if (delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
            context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
          }
  
          return ContinueSentinel;
        }
  
        var record = tryCatch(method, delegate.iterator, context.arg);
        if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
        var info = record.arg;
        return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
      }
  
      function pushTryEntry(locs) {
        var entry = {
          tryLoc: locs[0]
        };
        1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
      }
  
      function resetTryEntry(entry) {
        var record = entry.completion || {};
        record.type = "normal", delete record.arg, entry.completion = record;
      }
  
      function Context(tryLocsList) {
        this.tryEntries = [{
          tryLoc: "root"
        }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
      }
  
      function values(iterable) {
        if (iterable) {
          var iteratorMethod = iterable[iteratorSymbol];
          if (iteratorMethod) return iteratorMethod.call(iterable);
          if ("function" == typeof iterable.next) return iterable;
  
          if (!isNaN(iterable.length)) {
            var i = -1,
                next = function next() {
              for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
  
              return next.value = undefined, next.done = !0, next;
            };
  
            return next.next = next;
          }
        }
  
        return {
          next: doneResult
        };
      }
  
      function doneResult() {
        return {
          value: undefined,
          done: !0
        };
      }
  
      return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
        var ctor = "function" == typeof genFun && genFun.constructor;
        return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
      }, exports.mark = function (genFun) {
        return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
      }, exports.awrap = function (arg) {
        return {
          __await: arg
        };
      }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
        return this;
      }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
        void 0 === PromiseImpl && (PromiseImpl = Promise);
        var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
        return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
          return result.done ? result.value : iter.next();
        });
      }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
        return this;
      }), define(Gp, "toString", function () {
        return "[object Generator]";
      }), exports.keys = function (object) {
        var keys = [];
  
        for (var key in object) keys.push(key);
  
        return keys.reverse(), function next() {
          for (; keys.length;) {
            var key = keys.pop();
            if (key in object) return next.value = key, next.done = !1, next;
          }
  
          return next.done = !0, next;
        };
      }, exports.values = values, Context.prototype = {
        constructor: Context,
        reset: function (skipTempReset) {
          if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
        },
        stop: function () {
          this.done = !0;
          var rootRecord = this.tryEntries[0].completion;
          if ("throw" === rootRecord.type) throw rootRecord.arg;
          return this.rval;
        },
        dispatchException: function (exception) {
          if (this.done) throw exception;
          var context = this;
  
          function handle(loc, caught) {
            return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
          }
  
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i],
                record = entry.completion;
            if ("root" === entry.tryLoc) return handle("end");
  
            if (entry.tryLoc <= this.prev) {
              var hasCatch = hasOwn.call(entry, "catchLoc"),
                  hasFinally = hasOwn.call(entry, "finallyLoc");
  
              if (hasCatch && hasFinally) {
                if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
                if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
              } else if (hasCatch) {
                if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
              } else {
                if (!hasFinally) throw new Error("try statement without catch or finally");
                if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
              }
            }
          }
        },
        abrupt: function (type, arg) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
  
            if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
              var finallyEntry = entry;
              break;
            }
          }
  
          finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
          var record = finallyEntry ? finallyEntry.completion : {};
          return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
        },
        complete: function (record, afterLoc) {
          if ("throw" === record.type) throw record.arg;
          return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
        },
        finish: function (finallyLoc) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
            if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
          }
        },
        catch: function (tryLoc) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
  
            if (entry.tryLoc === tryLoc) {
              var record = entry.completion;
  
              if ("throw" === record.type) {
                var thrown = record.arg;
                resetTryEntry(entry);
              }
  
              return thrown;
            }
          }
  
          throw new Error("illegal catch attempt");
        },
        delegateYield: function (iterable, resultName, nextLoc) {
          return this.delegate = {
            iterator: values(iterable),
            resultName: resultName,
            nextLoc: nextLoc
          }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
        }
      }, exports;
    }
  
    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);
      Object.defineProperty(Constructor, "prototype", {
        writable: false
      });
      return Constructor;
    }
  
    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
        }
      });
      Object.defineProperty(subClass, "prototype", {
        writable: false
      });
      if (superClass) _setPrototypeOf(subClass, superClass);
    }
  
    function _getPrototypeOf(o) {
      _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
      };
      return _getPrototypeOf(o);
    }
  
    function _setPrototypeOf(o, p) {
      _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : 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 {
        Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
        return true;
      } catch (e) {
        return false;
      }
    }
  
    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;
      } else if (call !== void 0) {
        throw new TypeError("Derived constructors may only return object or undefined");
      }
  
      return _assertThisInitialized(self);
    }
  
    function _createSuper(Derived) {
      var hasNativeReflectConstruct = _isNativeReflectConstruct();
  
      return function _createSuperInternal() {
        var Super = _getPrototypeOf(Derived),
            result;
  
        if (hasNativeReflectConstruct) {
          var NewTarget = _getPrototypeOf(this).constructor;
  
          result = Reflect.construct(Super, arguments, NewTarget);
        } else {
          result = Super.apply(this, arguments);
        }
  
        return _possibleConstructorReturn(this, result);
      };
    }
  
    var FILE_POPULATED = Phaser.Loader.FILE_POPULATED;
    var UUID = Phaser.Utils.String.UUID;
  
    var AwaitFile = /*#__PURE__*/function (_Phaser$Loader$File) {
      _inherits(AwaitFile, _Phaser$Loader$File);
  
      var _super = _createSuper(AwaitFile);
  
      function AwaitFile(loader, fileConfig) {
        _classCallCheck(this, AwaitFile);
  
        if (!fileConfig.hasOwnProperty('type')) {
          fileConfig.type = 'await';
        }
  
        if (!fileConfig.hasOwnProperty('url')) {
          fileConfig.url = '';
        }
  
        if (!fileConfig.hasOwnProperty('key')) {
          fileConfig.key = UUID();
        }
  
        return _super.call(this, loader, fileConfig);
      }
  
      _createClass(AwaitFile, [{
        key: "load",
        value: function load() {
          if (this.state === FILE_POPULATED) {
            //  Can happen for example in a JSONFile if they've provided a JSON object instead of a URL
            this.loader.nextFile(this, true);
          } else {
            // start loading task
            var config = this.config;
            var callback = config.callback;
            var scope = config.scope;
            var successCallback = this.onLoad.bind(this);
            var failureCallback = this.onError.bind(this);
  
            if (callback) {
              if (scope) {
                callback.call(scope, successCallback, failureCallback);
              } else {
                callback(successCallback, failureCallback);
              }
            } else {
              this.onLoad();
            }
          }
        }
      }, {
        key: "onLoad",
        value: function onLoad() {
          this.loader.nextFile(this, true);
        }
      }, {
        key: "onError",
        value: function onError() {
          this.loader.nextFile(this, false);
        }
      }]);
  
      return AwaitFile;
    }(Phaser.Loader.File);
  
    var IsFunction = function IsFunction(obj) {
      return obj && typeof obj === 'function';
    };
  
    var IsPlainObject = Phaser.Utils.Objects.IsPlainObject;
  
    var loaderCallback = function loaderCallback(key, config) {
      if (IsFunction(key)) {
        var callback = key;
        var scope = config;
        config = {
          config: {
            callback: callback,
            scope: scope
          }
        };
      } else if (IsPlainObject(key)) {
        config = key;
  
        if (!config.hasOwnProperty('config')) {
          config = {
            config: config
          };
        }
      } else {
        config = {
          key: key,
          config: config
        };
      }
  
      this.addFile(new AwaitFile(this, config));
      return this;
    };
  
    var WaitEvent = function WaitEvent(eventEmitter, eventName) {
      return new Promise(function (resolve, reject) {
        eventEmitter.once(eventName, function () {
          resolve();
        });
      });
    };
  
    var NOOP = function NOOP() {//  NOOP
    };
  
    var GetValue = Phaser.Utils.Objects.GetValue;
  
    var LoadingProgress = function LoadingProgress(gameObject, config) {
      var TransitionInCallback = GetValue(config, 'transitIn', NOOP);
      var ProgressCallback = GetValue(config, 'progress', NOOP);
      var TransitionOutCallback = GetValue(config, 'transitionOut', NOOP);
      var scene = gameObject.scene; // Register AwaitLoader
  
      if (!scene.sys.load.rexAwait) {
        Phaser.Loader.FileTypesManager.register('rexAwait', loaderCallback);
        scene.sys.load.rexAwait = loaderCallback;
      } // Add await-task
  
  
      scene.load.rexAwait( /*#__PURE__*/function () {
        var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(successCallback, failureCallback) {
          var progress;
          return _regeneratorRuntime().wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  _context.next = 2;
                  return TransitionInCallback(gameObject);
  
                case 2:
                  progress = GetProgress(scene);
  
                  if (!(progress < 1)) {
                    _context.next = 13;
                    break;
                  }
  
                case 4:
                  if (!(progress < 1)) {
                    _context.next = 11;
                    break;
                  }
  
                  _context.next = 7;
                  return WaitEvent(scene.load, 'progress');
  
                case 7:
                  progress = GetProgress(scene);
                  ProgressCallback(gameObject, progress);
                  _context.next = 4;
                  break;
  
                case 11:
                  _context.next = 14;
                  break;
  
                case 13:
                  // Progress is 1 already
                  ProgressCallback(gameObject, progress);
  
                case 14:
                  _context.next = 16;
                  return TransitionOutCallback(gameObject);
  
                case 16:
                  gameObject.destroy(); // Finish this loading task, goto create stage
  
                  successCallback();
  
                case 18:
                case "end":
                  return _context.stop();
              }
            }
          }, _callee);
        }));
  
        return function (_x, _x2) {
          return _ref.apply(this, arguments);
        };
      }());
    };
  
    var GetProgress = function GetProgress(scene) {
      var loader = scene.load;
      var total = loader.totalToLoad - 1;
      var remainder = loader.list.size + loader.inflight.size - 1;
      var progress = 1 - remainder / total;
      return progress;
    };
  
    var Delay = function Delay(time, result) {
      if (time === undefined) {
        time = 0;
      }
  
      return new Promise(function (resolve, reject) {
        setTimeout(function () {
          resolve(result);
        }, time);
      });
    };
  
    var LoadingProgressPlugin = /*#__PURE__*/function (_Phaser$Plugins$BaseP) {
      _inherits(LoadingProgressPlugin, _Phaser$Plugins$BaseP);
  
      var _super = _createSuper(LoadingProgressPlugin);
  
      function LoadingProgressPlugin(pluginManager) {
        _classCallCheck(this, LoadingProgressPlugin);
  
        return _super.call(this, pluginManager);
      }
  
      _createClass(LoadingProgressPlugin, [{
        key: "add",
        value: function add(gameObject, config) {
          LoadingProgress(gameObject, config);
        }
      }, {
        key: "addDelayPromise",
        value: function addDelayPromise(time) {
          return Delay(time);
        }
      }]);
  
      return LoadingProgressPlugin;
    }(Phaser.Plugins.BasePlugin);
  
    return LoadingProgressPlugin;
  
  }));
  