text: /*!
   * @pixi/prepare - v5.2.1
   * Compiled Tue, 28 Jan 2020 23:33:11 UTC
   *
   * @pixi/prepare is licensed under the MIT License.
   * http://www.opensource.org/licenses/mit-license
   */
  this.PIXI = this.PIXI || {};
  var _pixi_prepare = (function (exports, settings, core, graphics, ticker, display, text) {
      'use strict';
  
      /**
       * Default number of uploads per frame using prepare plugin.
       *
       * @static
       * @memberof PIXI.settings
       * @name UPLOADS_PER_FRAME
       * @type {number}
       * @default 4
       */
      settings.settings.UPLOADS_PER_FRAME = 4;
  
      /**
       * CountLimiter limits the number of items handled by a {@link PIXI.BasePrepare} to a specified
       * number of items per frame.
       *
       * @class
       * @memberof PIXI
       */
      var CountLimiter = function CountLimiter(maxItemsPerFrame)
      {
          /**
           * The maximum number of items that can be prepared each frame.
           * @type {number}
           * @private
           */
          this.maxItemsPerFrame = maxItemsPerFrame;
          /**
           * The number of items that can be prepared in the current frame.
           * @type {number}
           * @private
           */
          this.itemsLeft = 0;
      };
  
      /**
       * Resets any counting properties to start fresh on a new frame.
       */
      CountLimiter.prototype.beginFrame = function beginFrame ()
      {
          this.itemsLeft = this.maxItemsPerFrame;
      };
  
      /**
       * Checks to see if another item can be uploaded. This should only be called once per item.
       * @return {boolean} If the item is allowed to be uploaded.
       */
      CountLimiter.prototype.allowedToUpload = function allowedToUpload ()
      {
          return this.itemsLeft-- > 0;
      };
  
      /**
       * The prepare manager provides functionality to upload content to the GPU.
       *
       * BasePrepare handles basic queuing functionality and is extended by
       * {@link PIXI.Prepare} and {@link PIXI.CanvasPrepare}
       * to provide preparation capabilities specific to their respective renderers.
       *
       * @example
       * // Create a sprite
       * const sprite = PIXI.Sprite.from('something.png');
       *
       * // Load object into GPU
       * app.renderer.plugins.prepare.upload(sprite, () => {
       *
       *     //Texture(s) has been uploaded to GPU
       *     app.stage.addChild(sprite);
       *
       * })
       *
       * @abstract
       * @class
       * @memberof PIXI
       */
      var BasePrepare = function BasePrepare(renderer)
      {
          var this$1 = this;
  
          /**
           * The limiter to be used to control how quickly items are prepared.
           * @type {PIXI.CountLimiter|PIXI.TimeLimiter}
           */
          this.limiter = new CountLimiter(settings.settings.UPLOADS_PER_FRAME);
  
          /**
           * Reference to the renderer.
           * @type {PIXI.AbstractRenderer}
           * @protected
           */
          this.renderer = renderer;
  
          /**
           * The only real difference between CanvasPrepare and Prepare is what they pass
           * to upload hooks. That different parameter is stored here.
           * @type {object}
           * @protected
           */
          this.uploadHookHelper = null;
  
          /**
           * Collection of items to uploads at once.
           * @type {Array<*>}
           * @private
           */
          this.queue = [];
  
          /**
           * Collection of additional hooks for finding assets.
           * @type {Array<Function>}
           * @private
           */
          this.addHooks = [];
  
          /**
           * Collection of additional hooks for processing assets.
           * @type {Array<Function>}
           * @private
           */
          this.uploadHooks = [];
  
          /**
           * Callback to call after completed.
           * @type {Array<Function>}
           * @private
           */
          this.completes = [];
  
          /**
           * If prepare is ticking (running).
           * @type {boolean}
           * @private
           */
          this.ticking = false;
  
          /**
           * 'bound' call for prepareItems().
           * @type {Function}
           * @private
           */
          this.delayedTick = function () {
              // unlikely, but in case we were destroyed between tick() and delayedTick()
              if (!this$1.queue)
              {
                  return;
              }
              this$1.prepareItems();
          };
  
          // hooks to find the correct texture
          this.registerFindHook(findText);
          this.registerFindHook(findTextStyle);
          this.registerFindHook(findMultipleBaseTextures);
          this.registerFindHook(findBaseTexture);
          this.registerFindHook(findTexture);
  
          // upload hooks
          this.registerUploadHook(drawText);
          this.registerUploadHook(calculateTextStyle);
      };
  
      /**
       * Upload all the textures and graphics to the GPU.
       *
       * @param {Function|PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} item -
       *    Either the container or display object to search for items to upload, the items to upload themselves,
       *    or the callback function, if items have been added using `prepare.add`.
       * @param {Function} [done] - Optional callback when all queued uploads have completed
       */
      BasePrepare.prototype.upload = function upload (item, done)
      {
          if (typeof item === 'function')
          {
              done = item;
              item = null;
          }
  
          // If a display object, search for items
          // that we could upload
          if (item)
          {
              this.add(item);
          }
  
          // Get the items for upload from the display
          if (this.queue.length)
          {
              if (done)
              {
                  this.completes.push(done);
              }
  
              if (!this.ticking)
              {
                  this.ticking = true;
                  ticker.Ticker.system.addOnce(this.tick, this, ticker.UPDATE_PRIORITY.UTILITY);
              }
          }
          else if (done)
          {
              done();
          }
      };
  
      /**
       * Handle tick update
       *
       * @private
       */
      BasePrepare.prototype.tick = function tick ()
      {
          setTimeout(this.delayedTick, 0);
      };
  
      /**
       * Actually prepare items. This is handled outside of the tick because it will take a while
       * and we do NOT want to block the current animation frame from rendering.
       *
       * @private
       */
      BasePrepare.prototype.prepareItems = function prepareItems ()
      {
          this.limiter.beginFrame();
          // Upload the graphics
          while (this.queue.length && this.limiter.allowedToUpload())
          {
              var item = this.queue[0];
              var uploaded = false;
  
              if (item && !item._destroyed)
              {
                  for (var i = 0, len = this.uploadHooks.length; i < len; i++)
                  {
                      if (this.uploadHooks[i](this.uploadHookHelper, item))
                      {
                          this.queue.shift();
                          uploaded = true;
                          break;
                      }
                  }
              }
  
              if (!uploaded)
              {
                  this.queue.shift();
              }
          }
  
          // We're finished
          if (!this.queue.length)
          {
              this.ticking = false;
  
              var completes = this.completes.slice(0);
  
              this.completes.length = 0;
  
              for (var i$1 = 0, len$1 = completes.length; i$1 < len$1; i$1++)
              {
                  completes[i$1]();
              }
          }
          else
          {
              // if we are not finished, on the next rAF do this again
              ticker.Ticker.system.addOnce(this.tick, this, ticker.UPDATE_PRIORITY.UTILITY);
          }
      };
  
      /**
       * Adds hooks for finding items.
       *
       * @param {Function} addHook - Function call that takes two parameters: `item:*, queue:Array`
       *      function must return `true` if it was able to add item to the queue.
       * @return {this} Instance of plugin for chaining.
       */
      BasePrepare.prototype.registerFindHook = function registerFindHook (addHook)
      {
          if (addHook)
          {
              this.addHooks.push(addHook);
          }
  
          return this;
      };
  
      /**
       * Adds hooks for uploading items.
       *
       * @param {Function} uploadHook - Function call that takes two parameters: `prepare:CanvasPrepare, item:*` and
       *      function must return `true` if it was able to handle upload of item.
       * @return {this} Instance of plugin for chaining.
       */
      BasePrepare.prototype.registerUploadHook = function registerUploadHook (uploadHook)
      {
          if (uploadHook)
          {
              this.uploadHooks.push(uploadHook);
          }
  
          return this;
      };
  
      /**
       * Manually add an item to the uploading queue.
       *
       * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to
       *    add to the queue
       * @return {this} Instance of plugin for chaining.
       */
      BasePrepare.prototype.add = function add (item)
      {
          // Add additional hooks for finding elements on special
          // types of objects that
          for (var i = 0, len = this.addHooks.length; i < len; i++)
          {
              if (this.addHooks[i](item, this.queue))
              {
                  break;
              }
          }
  
          // Get children recursively
          if (item instanceof display.Container)
          {
              for (var i$1 = item.children.length - 1; i$1 >= 0; i$1--)
              {
                  this.add(item.children[i$1]);
              }
          }
  
          return this;
      };
  
      /**
       * Destroys the plugin, don't use after this.
       *
       */
      BasePrepare.prototype.destroy = function destroy ()
      {
          if (this.ticking)
          {
              ticker.Ticker.system.remove(this.tick, this);
          }
          this.ticking = false;
          this.addHooks = null;
          this.uploadHooks = null;
          this.renderer = null;
          this.completes = null;
          this.queue = null;
          this.limiter = null;
          this.uploadHookHelper = null;
      };
  
      /**
       * Built-in hook to find multiple textures from objects like AnimatedSprites.
       *
       * @private
       * @param {PIXI.DisplayObject} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.Texture object was found.
       */
      function findMultipleBaseTextures(item, queue)
      {
          var result = false;
  
          // Objects with multiple textures
          if (item && item._textures && item._textures.length)
          {
              for (var i = 0; i < item._textures.length; i++)
              {
                  if (item._textures[i] instanceof core.Texture)
                  {
                      var baseTexture = item._textures[i].baseTexture;
  
                      if (queue.indexOf(baseTexture) === -1)
                      {
                          queue.push(baseTexture);
                          result = true;
                      }
                  }
              }
          }
  
          return result;
      }
  
      /**
       * Built-in hook to find BaseTextures from Texture.
       *
       * @private
       * @param {PIXI.Texture} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.Texture object was found.
       */
      function findBaseTexture(item, queue)
      {
          if (item.baseTexture instanceof core.BaseTexture)
          {
              var texture = item.baseTexture;
  
              if (queue.indexOf(texture) === -1)
              {
                  queue.push(texture);
              }
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to find textures from objects.
       *
       * @private
       * @param {PIXI.DisplayObject} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.Texture object was found.
       */
      function findTexture(item, queue)
      {
          if (item._texture && item._texture instanceof core.Texture)
          {
              var texture = item._texture.baseTexture;
  
              if (queue.indexOf(texture) === -1)
              {
                  queue.push(texture);
              }
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to draw PIXI.Text to its texture.
       *
       * @private
       * @param {PIXI.Renderer|PIXI.CanvasPrepare} helper - Not used by this upload handler
       * @param {PIXI.DisplayObject} item - Item to check
       * @return {boolean} If item was uploaded.
       */
      function drawText(helper, item)
      {
          if (item instanceof text.Text)
          {
              // updating text will return early if it is not dirty
              item.updateText(true);
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to calculate a text style for a PIXI.Text object.
       *
       * @private
       * @param {PIXI.Renderer|PIXI.CanvasPrepare} helper - Not used by this upload handler
       * @param {PIXI.DisplayObject} item - Item to check
       * @return {boolean} If item was uploaded.
       */
      function calculateTextStyle(helper, item)
      {
          if (item instanceof text.TextStyle)
          {
              var font = item.toFontString();
  
              text.TextMetrics.measureFont(font);
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to find Text objects.
       *
       * @private
       * @param {PIXI.DisplayObject} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.Text object was found.
       */
      function findText(item, queue)
      {
          if (item instanceof text.Text)
          {
              // push the text style to prepare it - this can be really expensive
              if (queue.indexOf(item.style) === -1)
              {
                  queue.push(item.style);
              }
              // also push the text object so that we can render it (to canvas/texture) if needed
              if (queue.indexOf(item) === -1)
              {
                  queue.push(item);
              }
              // also push the Text's texture for upload to GPU
              var texture = item._texture.baseTexture;
  
              if (queue.indexOf(texture) === -1)
              {
                  queue.push(texture);
              }
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to find TextStyle objects.
       *
       * @private
       * @param {PIXI.TextStyle} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.TextStyle object was found.
       */
      function findTextStyle(item, queue)
      {
          if (item instanceof text.TextStyle)
          {
              if (queue.indexOf(item) === -1)
              {
                  queue.push(item);
              }
  
              return true;
          }
  
          return false;
      }
  
      /**
       * The prepare plugin provides renderer-specific plugins for pre-rendering DisplayObjects. These plugins are useful for
       * asynchronously preparing and uploading to the GPU assets, textures, graphics waiting to be displayed.
       *
       * Do not instantiate this plugin directly. It is available from the `renderer.plugins` property.
       * See {@link PIXI.CanvasRenderer#plugins} or {@link PIXI.Renderer#plugins}.
       * @example
       * // Create a new application
       * const app = new PIXI.Application();
       * document.body.appendChild(app.view);
       *
       * // Don't start rendering right away
       * app.stop();
       *
       * // create a display object
       * const rect = new PIXI.Graphics()
       *     .beginFill(0x00ff00)
       *     .drawRect(40, 40, 200, 200);
       *
       * // Add to the stage
       * app.stage.addChild(rect);
       *
       * // Don't start rendering until the graphic is uploaded to the GPU
       * app.renderer.plugins.prepare.upload(app.stage, () => {
       *     app.start();
       * });
       *
       * @class
       * @extends PIXI.BasePrepare
       * @memberof PIXI
       */
      var Prepare = /*@__PURE__*/(function (BasePrepare) {
          function Prepare(renderer)
          {
              BasePrepare.call(this, renderer);
  
              this.uploadHookHelper = this.renderer;
  
              // Add textures and graphics to upload
              this.registerFindHook(findGraphics);
              this.registerUploadHook(uploadBaseTextures);
              this.registerUploadHook(uploadGraphics);
          }
  
          if ( BasePrepare ) Prepare.__proto__ = BasePrepare;
          Prepare.prototype = Object.create( BasePrepare && BasePrepare.prototype );
          Prepare.prototype.constructor = Prepare;
  
          return Prepare;
      }(BasePrepare));
      /**
       * Built-in hook to upload PIXI.Texture objects to the GPU.
       *
       * @private
       * @param {PIXI.Renderer} renderer - instance of the webgl renderer
       * @param {PIXI.BaseTexture} item - Item to check
       * @return {boolean} If item was uploaded.
       */
      function uploadBaseTextures(renderer, item)
      {
          if (item instanceof core.BaseTexture)
          {
              // if the texture already has a GL texture, then the texture has been prepared or rendered
              // before now. If the texture changed, then the changer should be calling texture.update() which
              // reuploads the texture without need for preparing it again
              if (!item._glTextures[renderer.CONTEXT_UID])
              {
                  renderer.texture.bind(item);
              }
  
              return true;
          }
  
          return false;
      }
  
      /**
       * Built-in hook to upload PIXI.Graphics to the GPU.
       *
       * @private
       * @param {PIXI.Renderer} renderer - instance of the webgl renderer
       * @param {PIXI.DisplayObject} item - Item to check
       * @return {boolean} If item was uploaded.
       */
      function uploadGraphics(renderer, item)
      {
          if (!(item instanceof graphics.Graphics))
          {
              return false;
          }
  
          var geometry = item.geometry;
  
          // update dirty graphics to get batches
          item.finishPoly();
          geometry.updateBatches();
  
          var batches = geometry.batches;
  
          // upload all textures found in styles
          for (var i = 0; i < batches.length; i++)
          {
              var ref = batches[i].style;
              var texture = ref.texture;
  
              if (texture)
              {
                  uploadBaseTextures(renderer, texture.baseTexture);
              }
          }
  
          // if its not batchable - update vao for particular shader
          if (!geometry.batchable)
          {
              renderer.geometry.bind(geometry, item._resolveDirectShader());
          }
  
          return true;
      }
  
      /**
       * Built-in hook to find graphics.
       *
       * @private
       * @param {PIXI.DisplayObject} item - Display object to check
       * @param {Array<*>} queue - Collection of items to upload
       * @return {boolean} if a PIXI.Graphics object was found.
       */
      function findGraphics(item, queue)
      {
          if (item instanceof graphics.Graphics)
          {
              queue.push(item);
  
              return true;
          }
  
          return false;
      }
  
      /**
       * TimeLimiter limits the number of items handled by a {@link PIXI.BasePrepare} to a specified
       * number of milliseconds per frame.
       *
       * @class
       * @memberof PIXI
       */
      var TimeLimiter = function TimeLimiter(maxMilliseconds)
      {
          /**
           * The maximum milliseconds that can be spent preparing items each frame.
           * @type {number}
           * @private
           */
          this.maxMilliseconds = maxMilliseconds;
          /**
           * The start time of the current frame.
           * @type {number}
           * @private
           */
          this.frameStart = 0;
      };
  
      /**
       * Resets any counting properties to start fresh on a new frame.
       */
      TimeLimiter.prototype.beginFrame = function beginFrame ()
      {
          this.frameStart = Date.now();
      };
  
      /**
       * Checks to see if another item can be uploaded. This should only be called once per item.
       * @return {boolean} If the item is allowed to be uploaded.
       */
      TimeLimiter.prototype.allowedToUpload = function allowedToUpload ()
      {
          return Date.now() - this.frameStart < this.maxMilliseconds;
      };
  
      exports.BasePrepare = BasePrepare;
      exports.CountLimiter = CountLimiter;
      exports.Prepare = Prepare;
      exports.TimeLimiter = TimeLimiter;
  
      return exports;
  
  }({}, PIXI, PIXI, PIXI, PIXI, PIXI, PIXI));
  Object.assign(this.PIXI, _pixi_prepare);
  //# sourceMappingURL=prepare.js.map
  