/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Tileset = require('../../Tileset');
var ImageCollection = require('../../ImageCollection');
var ParseObject = require('./ParseObject');

/**
 * Tilesets & Image Collections
 *
 * @function Phaser.Tilemaps.Parsers.Tiled.ParseTilesets
 * @since 3.0.0
 *
 * @param {object} json - [description]
 *
 * @return {object} [description]
 */
var ParseTilesets = function (json)
{
    var tilesets = [];
    var imageCollections = [];
    var lastSet = null;
    var stringID;

    for (var i = 0; i < json.tilesets.length; i++)
    {
        //  name, firstgid, width, height, margin, spacing, properties
        var set = json.tilesets[i];

        if (set.source)
        {
            console.warn('Phaser can\'t load external tilesets. Use the Embed Tileset button and then export the map again.');
        }
        else if (set.image)
        {
            var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing);

            if (json.version > 1)
            {
                // Tiled 1.2+

                if (Array.isArray(set.tiles))
                {
                    var tiles = {};
                    var props = {};

                    for (var t = 0; t < set.tiles.length; t++)
                    {
                        var tile = set.tiles[t];

                        //  Convert tileproperties
                        if (tile.properties)
                        {
                            var newPropData = {};

                            tile.properties.forEach(function (propData)
                            {
                                newPropData[propData['name']] = propData['value'];
                            });

                            props[tile.id] = newPropData;
                        }

                        //  Convert objectgroup
                        if (tile.objectgroup)
                        {
                            tiles[tile.id] = { objectgroup: tile.objectgroup };

                            if (tile.objectgroup.objects)
                            {
                                var parsedObjects2 = tile.objectgroup.objects.map(
                                    function (obj) { return ParseObject(obj); }
                                );

                                tiles[tile.id].objectgroup.objects = parsedObjects2;
                            }
                        }

                        // Copy animation data
                        if (tile.animation)
                        {
                            if (tiles.hasOwnProperty(tile.id))
                            {
                                tiles[tile.id].animation = tile.animation;
                            }
                            else
                            {
                                tiles[tile.id] = { animation: tile.animation };
                            }
                        }
                    }

                    newSet.tileData = tiles;
                    newSet.tileProperties = props;
                }
            }
            else
            {
                // Tiled 1

                // Properties stored per-tile in object with string indexes starting at "0"
                if (set.tileproperties)
                {
                    newSet.tileProperties = set.tileproperties;
                }

                // Object & terrain shapes stored per-tile in object with string indexes starting at "0"
                if (set.tiles)
                {
                    newSet.tileData = set.tiles;

                    // Parse the objects into Phaser format to match handling of other Tiled objects
                    for (stringID in newSet.tileData)
                    {
                        var objectGroup = newSet.tileData[stringID].objectgroup;
                        if (objectGroup && objectGroup.objects)
                        {
                            var parsedObjects1 = objectGroup.objects.map(
                                function (obj) { return ParseObject(obj); }
                            );
                            newSet.tileData[stringID].objectgroup.objects = parsedObjects1;
                        }
                    }
                }
            }

            // For a normal sliced tileset the row/count/size information is computed when updated.
            // This is done (again) after the image is set.
            newSet.updateTileData(set.imagewidth, set.imageheight);

            tilesets.push(newSet);
        }
        else
        {
            var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth,
                set.tileheight, set.margin, set.spacing, set.properties);

            for (stringID in set.tiles)
            {
                var image = set.tiles[stringID].image;
                var gid = set.firstgid + parseInt(stringID, 10);
                newCollection.addImage(gid, image);
            }

            imageCollections.push(newCollection);
        }

        //  We've got a new Tileset, so set the lastgid into the previous one
        if (lastSet)
        {
            lastSet.lastgid = set.firstgid - 1;
        }

        lastSet = set;
    }

    return { tilesets: tilesets, imageCollections: imageCollections };
};

module.exports = ParseTilesets;


//  Export it
module.exports = Phaser;
global.Phaser = Phaser;
/*

if (typeof FEATURE_SOUND)
{
Phaser.Sound = require('./sound');
}

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var AddToDOM = require('../dom/AddToDOM');
var AnimationManager = require('../animations/AnimationManager');
var CacheManager = require('../cache/CacheManager');
var CanvasPool = require('../display/canvas/CanvasPool');
var Class = require('../utils/Class');
var Config = require('./Config');
var CreateDOMContainer = require('../dom/CreateDOMContainer');
var CreateRenderer = require('./CreateRenderer');
var DataManager = require('../data/DataManager');
var DebugHeader = require('./DebugHeader');
var Device = require('../device');
var DOMContentLoaded = require('../dom/DOMContentLoaded');
var EventEmitter = require('eventemitter3');
var Events = require('./events');
var InputManager = require('../input/InputManager');
var PluginCache = require('../plugins/PluginCache');
var PluginManager = require('../plugins/PluginManager');
var ScaleManager = require('../scale/ScaleManager');
var SceneManager = require('../scene/SceneManager');
var SoundManagerCreator = require('../sound/SoundManagerCreator');
var TextureEvents = require('../textures/events');
var TextureManager = require('../textures/TextureManager');
var TimeStep = require('./TimeStep');
var VisibilityHandler = require('./VisibilityHandler');

if (typeof PLUGIN_FBINSTANT)
{
    var FacebookInstantGamesPlugin = require('../../plugins/fbinstant/src/FacebookInstantGamesPlugin');
}

/**
 * @classdesc
 * The Phaser.Game instance is the main controller for the entire Phaser game. It is responsible
 * for handling the boot process, parsing the configuration values, creating the renderer,
 * and setting-up all of the global Phaser systems, such as sound and input.
 * Once that is complete it will start the Scene Manager and then begin the main game loop.
 *
 * You should generally avoid accessing any of the systems created by Game, and instead use those
 * made available to you via the Phaser.Scene Systems class instead.
 *
 * @class Game
 * @memberof Phaser
 * @constructor
 * @fires Phaser.Core.Events#BLUR
 * @fires Phaser.Core.Events#FOCUS
 * @fires Phaser.Core.Events#HIDDEN
 * @fires Phaser.Core.Events#VISIBLE
 * @since 3.0.0
 *
 * @param {Phaser.Core.Types.GameConfig} [GameConfig] - The configuration object for your Phaser Game instance.
 */
var Game = new Class({

    initialize:

    function Game (config)
    {
        /**
         * The parsed Game Configuration object.
         *
         * The values stored within this object are read-only and should not be changed at run-time.
         *
         * @name Phaser.Game#config
         * @type {Phaser.Core.Config}
         * @readonly
         * @since 3.0.0
         */
        this.config = new Config(config);

        /**
         * A reference to either the Canvas or WebGL Renderer that this Game is using.
         *
         * @name Phaser.Game#renderer
         * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)}
         * @since 3.0.0
         */
        this.renderer = null;

        /**
         * A reference to an HTML Div Element used as the DOM Element Container.
         *
         * Only set if `createDOMContainer` is `true` in the game config (by default it is `false`) and
         * if you provide a parent element to insert the Phaser Game inside.
         *
         * See the DOM Element Game Object for more details.
         *
         * @name Phaser.Game#domContainer
         * @type {HTMLDivElement}
         * @since 3.17.0
         */
        this.domContainer = null;

        /**
         * A reference to the HTML Canvas Element that Phaser uses to render the game.
         * This is created automatically by Phaser unless you provide a `canvas` property
         * in your Game Config.
         *
         * @name Phaser.Game#canvas
         * @type {HTMLCanvasElement}
         * @since 3.0.0
         */
        this.canvas = null;

        /**
         * A reference to the Rendering Context belonging to the Canvas Element this game is rendering to.
         * If the game is running under Canvas it will be a 2d Canvas Rendering Context.
         * If the game is running under WebGL it will be a WebGL Rendering Context.
         * This context is created automatically by Phaser unless you provide a `context` property
         * in your Game Config.
         *
         * @name Phaser.Game#context
         * @type {(CanvasRenderingContext2D|WebGLRenderingContext)}
         * @since 3.0.0
         */
        this.context = null;

        /**
         * A flag indicating when this Game instance has finished its boot process.
         *
         * @name Phaser.Game#isBooted
         * @type {boolean}
         * @readonly
         * @since 3.0.0
         */
        this.isBooted = false;

        /**
         * A flag indicating if this Game is currently running its game step or not.
         *
         * @name Phaser.Game#isRunning
         * @type {boolean}
         * @readonly
         * @since 3.0.0
         */
        this.isRunning = false;

        /**
         * An Event Emitter which is used to broadcast game-level events from the global systems.
         *
         * @name Phaser.Game#events
         * @type {Phaser.Events.EventEmitter}
         * @since 3.0.0
         */
        this.events = new EventEmitter();

        /**
         * An instance of the Animation Manager.
         *
         * The Animation Manager is a global system responsible for managing all animations used within your game.
         *
         * @name Phaser.Game#anims
         * @type {Phaser.Animations.AnimationManager}
         * @since 3.0.0
         */
        this.anims = new AnimationManager(this);

        /**
         * An instance of the Texture Manager.
         *
         * The Texture Manager is a global system responsible for managing all textures being used by your game.
         *
         * @name Phaser.Game#textures
         * @type {Phaser.Textures.TextureManager}
         * @since 3.0.0
         */
        this.textures = new TextureManager(this);

        /**
         * An instance of the Cache Manager.
         *
         * The Cache Manager is a global system responsible for caching, accessing and releasing external game assets.
         *
         * @name Phaser.Game#cache
         * @type {Phaser.Cache.CacheManager}
         * @since 3.0.0
         */
        this.cache = new CacheManager(this);

        /**
         * An instance of the Data Manager
         *
         * @name Phaser.Game#registry
         * @type {Phaser.Data.DataManager}
         * @since 3.0.0
         */
        this.registry = new DataManager(this);

        /**
         * An instance of the Input Manager.
         *
         * The Input Manager is a global system responsible for the capture of browser-level input events.
         *
         * @name Phaser.Game#input
         * @type {Phaser.Input.InputManager}
         * @since 3.0.0
         */
        this.input = new InputManager(this, this.config);

        /**
         * An instance of the Scene Manager.
         *
         * The Scene Manager is a global system responsible for creating, modifying and updating the Scenes in your game.
         *
         * @name Phaser.Game#scene
         * @type {Phaser.Scenes.SceneManager}
         * @since 3.0.0
         */
        this.scene = new SceneManager(this, this.config.sceneConfig);

        /**
         * A reference to the Device inspector.
         *
         * Contains information about the device running this game, such as OS, browser vendor and feature support.
         * Used by various systems to determine capabilities and code paths.
         *
         * @name Phaser.Game#device
         * @type {Phaser.DeviceConf}
         * @since 3.0.0
         */
        this.device = Device;

        /**
         * An instance of the Scale Manager.
         *
         * The Scale Manager is a global system responsible for handling scaling of the game canvas.
         *
         * @name Phaser.Game#scale
         * @type {Phaser.Scale.ScaleManager}
         * @since 3.16.0
         */
        this.scale = new ScaleManager(this, this.config);

        /**
         * An instance of the base Sound Manager.
         *
         * The Sound Manager is a global system responsible for the playback and updating of all audio in your game.
         *
         * @name Phaser.Game#sound
         * @type {Phaser.Sound.BaseSoundManager}
         * @since 3.0.0
         */
        this.sound = SoundManagerCreator.create(this);

        /**
         * An instance of the Time Step.
         *
         * The Time Step is a global system responsible for setting-up and responding to the browser frame events, processing
         * them and calculating delta values. It then automatically calls the game step.
         *
         * @name Phaser.Game#loop
         * @type {Phaser.Core.TimeStep}
         * @since 3.0.0
         */
        this.loop = new TimeStep(this, this.config.fps);

        /**
         * An instance of the Plugin Manager.
         *
         * The Plugin Manager is a global system that allows plugins to register themselves with it, and can then install
         * those plugins into Scenes as required.
         *
         * @name Phaser.Game#plugins
         * @type {Phaser.Plugins.PluginManager}
         * @since 3.0.0
         */
        this.plugins = new PluginManager(this, this.config);

        if (typeof PLUGIN_FBINSTANT)
        {
            /**
             * An instance of the Facebook Instant Games Plugin.
             *
             * This will only be available if the plugin has been built into Phaser,
             * or you're using the special Facebook Instant Games custom build.
             *
             * @name Phaser.Game#facebook
             * @type {Phaser.FacebookInstantGamesPlugin}
             * @since 3.13.0
             */
            this.facebook = new FacebookInstantGamesPlugin(this);
        }

        /**
         * Is this Game pending destruction at the start of the next frame?
         *
         * @name Phaser.Game#pendingDestroy
         * @type {boolean}
         * @private
         * @since 3.5.0
         */
        this.pendingDestroy = false;

        /**
         * Remove the Canvas once the destroy is over?
         *
         * @name Phaser.Game#removeCanvas
         * @type {boolean}
         * @private
         * @since 3.5.0
         */
        this.removeCanvas = false;

        /**
         * Remove everything when the game is destroyed.
         * You cannot create a new Phaser instance on the same web page after doing this.
         *
         * @name Phaser.Game#noReturn
         * @type {boolean}
         * @private
         * @since 3.12.0
         */
        this.noReturn = false;

        /**
         * Does the window the game is running in currently have focus or not?
         * This is modified by the VisibilityHandler.
         *
         * @name Phaser.Game#hasFocus
         * @type {boolean}
         * @readonly
         * @since 3.9.0
         */
        this.hasFocus = false;

        //  Wait for the DOM Ready event, then call boot.
        DOMContentLoaded(this.boot.bind(this));
    },

    /**
     * This method is called automatically when the DOM is ready. It is responsible for creating the renderer,
     * displaying the Debug Header, adding the game canvas to the DOM and emitting the 'boot' event.
     * It listens for a 'ready' event from the base systems and once received it will call `Game.start`.
     *
     * @method Phaser.Game#boot
     * @protected
     * @fires Phaser.Core.Events#BOOT
     * @listens Phaser.Textures.Events#READY
     * @since 3.0.0
     */
    boot: function ()
    {
        if (!PluginCache.hasCore('EventEmitter'))
        {
            console.warn('Aborting. Core Plugins missing.');
            return;
        }

        this.isBooted = true;

        this.config.preBoot(this);

        this.scale.preBoot();

        CreateRenderer(this);

        CreateDOMContainer(this);

        DebugHeader(this);

        AddToDOM(this.canvas, this.config.parent);

        //  The Texture Manager has to wait on a couple of non-blocking events before it's fully ready.
        //  So it will emit this internal event when done:
        this.textures.once(TextureEvents.READY, this.texturesReady, this);

        this.events.emit(Events.BOOT);
    },

    /**
     * Called automatically when the Texture Manager has finished setting up and preparing the
     * default textures.
     *
     * @method Phaser.Game#texturesReady
     * @private
     * @fires Phaser.Game#ready
     * @since 3.12.0
     */
    texturesReady: function ()
    {
        //  Start all the other systems
        this.events.emit(Events.READY);

        this.start();
    },

    /**
     * Called automatically by Game.boot once all of the global systems have finished setting themselves up.
     * By this point the Game is now ready to start the main loop running.
     * It will also enable the Visibility Handler.
     *
     * @method Phaser.Game#start
     * @protected
     * @since 3.0.0
     */
    start: function ()
    {
        this.isRunning = true;

        this.config.postBoot(this);

        if (this.renderer)
        {
            this.loop.start(this.step.bind(this));
        }
        else
        {
            this.loop.start(this.headlessStep.bind(this));
        }

        VisibilityHandler(this);

        var eventEmitter = this.events;

        eventEmitter.on(Events.HIDDEN, this.onHidden, this);
        eventEmitter.on(Events.VISIBLE, this.onVisible, this);
        eventEmitter.on(Events.BLUR, this.onBlur, this);
        eventEmitter.on(Events.FOCUS, this.onFocus, this);
    },

    /**
     * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of
     * Request Animation Frame, or Set Timeout on very old browsers.)
     *
     * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager.
     *
     * It will then render each Scene in turn, via the Renderer. This process emits `prerender` and `postrender` events.
     *
     * @method Phaser.Game#step
     * @fires Phaser.Core.Events#PRE_STEP_EVENT
     * @fires Phaser.Core.Events#STEP_EVENT
     * @fires Phaser.Core.Events#POST_STEP_EVENT
     * @fires Phaser.Core.Events#PRE_RENDER_EVENT
     * @fires Phaser.Core.Events#POST_RENDER_EVENT
     * @since 3.0.0
     *
     * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
     * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
     */
    step: function (time, delta)
    {
        if (this.pendingDestroy)
        {
            return this.runDestroy();
        }

        var eventEmitter = this.events;

        //  Global Managers like Input and Sound update in the prestep

        eventEmitter.emit(Events.PRE_STEP, time, delta);

        //  This is mostly meant for user-land code and plugins

        eventEmitter.emit(Events.STEP, time, delta);

        //  Update the Scene Manager and all active Scenes

        this.scene.update(time, delta);

        //  Our final event before rendering starts

        eventEmitter.emit(Events.POST_STEP, time, delta);

        var renderer = this.renderer;

        //  Run the Pre-render (clearing the canvas, setting background colors, etc)

        renderer.preRender();

        eventEmitter.emit(Events.PRE_RENDER, renderer, time, delta);

        //  The main render loop. Iterates all Scenes and all Cameras in those scenes, rendering to the renderer instance.

        this.scene.render(renderer);

        //  The Post-Render call. Tidies up loose end, takes snapshots, etc.

        renderer.postRender();

        //  The final event before the step repeats. Your last chance to do anything to the canvas before it all starts again.

        eventEmitter.emit(Events.POST_RENDER, renderer, time, delta);
    },

    /**
     * A special version of the Game Step for the HEADLESS renderer only.
     *
     * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of
     * Request Animation Frame, or Set Timeout on very old browsers.)
     *
     * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager.
     *
     * This process emits `prerender` and `postrender` events, even though nothing actually displays.
     *
     * @method Phaser.Game#headlessStep
     * @fires Phaser.Game#prerenderEvent
     * @fires Phaser.Game#postrenderEvent
     * @since 3.2.0
     *
     * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
     * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
     */
    headlessStep: function (time, delta)
    {
        var eventEmitter = this.events;

        //  Global Managers

        eventEmitter.emit(Events.PRE_STEP, time, delta);

        eventEmitter.emit(Events.STEP, time, delta);

        //  Scenes

        this.scene.update(time, delta);

        eventEmitter.emit(Events.POST_STEP, time, delta);

        //  Render

        eventEmitter.emit(Events.PRE_RENDER);

        eventEmitter.emit(Events.POST_RENDER);
    },

    /**
     * Called automatically by the Visibility Handler.
     * This will pause the main loop and then emit a pause event.
     *
     * @method Phaser.Game#onHidden
     * @protected
     * @fires Phaser.Core.Events#PAUSE
     * @since 3.0.0
     */
    onHidden: function ()
    {
        this.loop.pause();

        this.events.emit(Events.PAUSE);
    },

    /**
     * Called automatically by the Visibility Handler.
     * This will resume the main loop and then emit a resume event.
     *
     * @method Phaser.Game#onVisible
     * @protected
     * @fires Phaser.Core.Events#RESUME
     * @since 3.0.0
     */
    onVisible: function ()
    {
        this.loop.resume();

        this.events.emit(Events.RESUME);
    },

    /**
     * Called automatically by the Visibility Handler.
     * This will set the main loop into a 'blurred' state, which pauses it.
     *
     * @method Phaser.Game#onBlur
     * @protected
     * @since 3.0.0
     */
    onBlur: function ()
    {
        this.hasFocus = false;

        this.loop.blur();
    },

    /**
     * Called automatically by the Visibility Handler.
     * This will set the main loop into a 'focused' state, which resumes it.
     *
     * @method Phaser.Game#onFocus
     * @protected
     * @since 3.0.0
     */
    onFocus: function ()
    {
        this.hasFocus = true;

        this.loop.focus();
    },

    /**
     * Returns the current game frame.
     * When the game starts running, the frame is incremented every time Request Animation Frame, or Set Timeout, fires.
     *
     * @method Phaser.Game#getFrame
     * @since 3.16.0
     *
     * @return {number} The current game frame.
     */
    getFrame: function ()
    {
        return this.loop.frame;
    },

    /**
     * Returns the current game timestamp.
     * When the game starts running, the frame is incremented every time Request Animation Frame, or Set Timeout, fires.
     *
     * @method Phaser.Game#getTime
     * @since 3.16.0
     *
     * @return {number} The current game timestamp.
     */
    getTime: function ()
    {
        return this.loop.frame.time;
    },

    /**
     * Flags this Game instance as needing to be destroyed on the next frame.
     * It will wait until the current frame has completed and then call `runDestroy` internally.
     *
     * If you **do not** need to run Phaser again on the same web page you can set the `noReturn` argument to `true` and it will free-up
     * memory being held by the core Phaser plugins. If you do need to create another game instance on the same page, leave this as `false`.
     *
     * @method Phaser.Game#destroy
     * @fires Phaser.Core.Events#DESTROY
     * @since 3.0.0
     *
     * @param {boolean} removeCanvas - Set to `true` if you would like the parent canvas element removed from the DOM, or `false` to leave it in place.
     * @param {boolean} [noReturn=false] - If `true` all the core Phaser plugins are destroyed. You cannot create another instance of Phaser on the same web page if you do this.
     */
    destroy: function (removeCanvas, noReturn)
    {
        if (noReturn === undefined) { noReturn = false; }

        this.pendingDestroy = true;

        this.removeCanvas = removeCanvas;
        this.noReturn = noReturn;
    },

    /**
     * Destroys this Phaser.Game instance, all global systems, all sub-systems and all Scenes.
     *
     * @method Phaser.Game#runDestroy
     * @private
     * @since 3.5.0
     */
    runDestroy: function ()
    {
        this.events.emit(Events.DESTROY);

        this.events.removeAllListeners();

        this.scene.destroy();

        if (this.renderer)
        {
            this.renderer.destroy();
        }

        if (this.removeCanvas && this.canvas)
        {
            CanvasPool.remove(this.canvas);

            if (this.canvas.parentNode)
            {
                this.canvas.parentNode.removeChild(this.canvas);
            }
        }

        if (this.domContainer)
        {
            this.domContainer.parentNode.removeChild(this.domContainer);
        }

        this.loop.destroy();

        this.pendingDestroy = false;
    }

});

module.exports = Game;

/**
 * "Computers are good at following instructions, but not at reading your mind." - Donald Knuth
 */


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var GetBottom = require('../../bounds/GetBottom');
var GetRight = require('../../bounds/GetRight');
var SetBottom = require('../../bounds/SetBottom');
var SetRight = require('../../bounds/SetRight');

/**
 * Takes given Game Object and aligns it so that it is positioned in the bottom right of the other.
 *
 * @function Phaser.Display.Align.In.BottomRight
 * @since 3.0.0
 *
 * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return]
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned.
 * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on.
 * @param {number} [offsetX=0] - Optional horizontal offset from the position.
 * @param {number} [offsetY=0] - Optional vertical offset from the position.
 *
 * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned.
 */
var BottomRight = function (gameObject, alignIn, offsetX, offsetY)
{
    if (offsetX === undefined) { offsetX = 0; }
    if (offsetY === undefined) { offsetY = 0; }

    SetRight(gameObject, GetRight(alignIn) + offsetX);
    SetBottom(gameObject, GetBottom(alignIn) + offsetY);

    return gameObject;
};

module.exports = BottomRight;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * @namespace Phaser.Physics.Arcade.Events
 */

module.exports = {

    COLLIDE: require('./COLLIDE_EVENT'),
    OVERLAP: require('./OVERLAP_EVENT'),
    PAUSE: require('./PAUSE_EVENT'),
    RESUME: require('./RESUME_EVENT'),
    TILE_COLLIDE: require('./TILE_COLLIDE_EVENT'),
    TILE_OVERLAP: require('./TILE_OVERLAP_EVENT'),
    TOUCH: require('./TOUCH_EVENT'),
    WORLD_BOUNDS: require('./WORLD_BOUNDS_EVENT')

};


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * The Game Pre-Step Event.
 *
 * This event is dispatched before the main Game Step starts. By this point in the game cycle none of the Scene updates have yet happened.
 * Hook into it from plugins or systems that need to update before the Scene Manager does.
 *
 * @event Phaser.Core.Events#PRE_STEP
 * @since 3.0.0
 *
 * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
 * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
 */
module.exports = 'prestep';


Plugins: require('./plugins'),
Renderer: require('./renderer'),
Scale: require('./scale'),
Scene: require('./scene/Scene'),
Scenes: require('./scene'),
Sound: require('./sound'),
Structs: require('./structs'),
Textures: require('./textures'),
Tilemaps: require('./tilemaps'),
Time: require('./time'),

keep keep keep keep keep replace keep keep keep keep

'use strict';

const webpack = require('webpack');
const exec = require('child_process').exec;

module.exports = {
    mode: 'development',

    context: `${__dirname}/src/`,

    entry: {
        phaser: './phaser.js'
    },

    output: {
        path: `${__dirname}/build/`,
        filename: 'phaser-facebook-instant-games.js',
        library: 'Phaser',
        libraryTarget: 'umd',
        sourceMapFilename: '[file].map',
        devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
        devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
        umdNamedDefine: true
    },

    performance: { hints: false },

    plugins: [
        new webpack.DefinePlugin({
            "typeof CANVAS_RENDERER": JSON.stringify(true),
            "typeof WEBGL_RENDERER": JSON.stringify(true),
            "typeof EXPERIMENTAL": JSON.stringify(false),
            "typeof PLUGIN_CAMERA3D": JSON.stringify(false),
            "typeof PLUGIN_FBINSTANT": JSON.stringify(true)
        }),
        {
            apply: (compiler) => {
                compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
                    exec('node scripts/copy-to-examples-fb.js', (err, stdout, stderr) => {
                        if (stdout) process.stdout.write(stdout);
                        if (stderr) process.stderr.write(stderr);
                    });
                });
            }
        }
    ],

    devtool: 'source-map'
};


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var PropertyValueSet = require('./PropertyValueSet');

/**
 * Takes an array of Game Objects, or any objects that have the public property `y`
 * and then sets it to the given value.
 *
 * The optional `step` property is applied incrementally, multiplied by each item in the array.
 *
 * To use this with a Group: `SetY(group.getChildren(), value, step)`
 *
 * @function Phaser.Actions.SetY
 * @since 3.0.0
 *
 * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
 *
 * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action.
 * @param {number} value - The amount to set the property to.
 * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
 * @param {integer} [index=0] - An optional offset to start searching from within the items array.
 * @param {integer} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
 *
 * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action.
 */
var SetY = function (items, value, step, index, direction)
{
    return PropertyValueSet(items, 'y', value, step, index, direction);
};

module.exports = SetY;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Keyboard Codes.
 *
 * @namespace Phaser.Input.Keyboard.KeyCodes
 * @memberof Phaser.Input.Keyboard
 * @since 3.0.0
 */

var KeyCodes = {

    /**
     * The BACKSPACE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.BACKSPACE
     * @type {integer}
     * @since 3.0.0
     */
    BACKSPACE: 8,

    /**
     * The TAB key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.TAB
     * @type {integer}
     * @since 3.0.0
     */
    TAB: 9,

    /**
     * The ENTER key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.ENTER
     * @type {integer}
     * @since 3.0.0
     */
    ENTER: 13,

    /**
     * The SHIFT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SHIFT
     * @type {integer}
     * @since 3.0.0
     */
    SHIFT: 16,

    /**
     * The CTRL key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.CTRL
     * @type {integer}
     * @since 3.0.0
     */
    CTRL: 17,

    /**
     * The ALT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.ALT
     * @type {integer}
     * @since 3.0.0
     */
    ALT: 18,

    /**
     * The PAUSE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PAUSE
     * @type {integer}
     * @since 3.0.0
     */
    PAUSE: 19,

    /**
     * The CAPS_LOCK key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.CAPS_LOCK
     * @type {integer}
     * @since 3.0.0
     */
    CAPS_LOCK: 20,

    /**
     * The ESC key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.ESC
     * @type {integer}
     * @since 3.0.0
     */
    ESC: 27,

    /**
     * The SPACE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SPACE
     * @type {integer}
     * @since 3.0.0
     */
    SPACE: 32,

    /**
     * The PAGE_UP key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PAGE_UP
     * @type {integer}
     * @since 3.0.0
     */
    PAGE_UP: 33,

    /**
     * The PAGE_DOWN key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN
     * @type {integer}
     * @since 3.0.0
     */
    PAGE_DOWN: 34,

    /**
     * The END key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.END
     * @type {integer}
     * @since 3.0.0
     */
    END: 35,

    /**
     * The HOME key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.HOME
     * @type {integer}
     * @since 3.0.0
     */
    HOME: 36,

    /**
     * The LEFT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.LEFT
     * @type {integer}
     * @since 3.0.0
     */
    LEFT: 37,

    /**
     * The UP key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.UP
     * @type {integer}
     * @since 3.0.0
     */
    UP: 38,

    /**
     * The RIGHT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.RIGHT
     * @type {integer}
     * @since 3.0.0
     */
    RIGHT: 39,

    /**
     * The DOWN key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.DOWN
     * @type {integer}
     * @since 3.0.0
     */
    DOWN: 40,

    /**
     * The PRINT_SCREEN key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PRINT_SCREEN
     * @type {integer}
     * @since 3.0.0
     */
    PRINT_SCREEN: 42,

    /**
     * The INSERT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.INSERT
     * @type {integer}
     * @since 3.0.0
     */
    INSERT: 45,

    /**
     * The DELETE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.DELETE
     * @type {integer}
     * @since 3.0.0
     */
    DELETE: 46,

    /**
     * The ZERO key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.ZERO
     * @type {integer}
     * @since 3.0.0
     */
    ZERO: 48,

    /**
     * The ONE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.ONE
     * @type {integer}
     * @since 3.0.0
     */
    ONE: 49,

    /**
     * The TWO key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.TWO
     * @type {integer}
     * @since 3.0.0
     */
    TWO: 50,

    /**
     * The THREE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.THREE
     * @type {integer}
     * @since 3.0.0
     */
    THREE: 51,

    /**
     * The FOUR key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.FOUR
     * @type {integer}
     * @since 3.0.0
     */
    FOUR: 52,

    /**
     * The FIVE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.FIVE
     * @type {integer}
     * @since 3.0.0
     */
    FIVE: 53,

    /**
     * The SIX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SIX
     * @type {integer}
     * @since 3.0.0
     */
    SIX: 54,

    /**
     * The SEVEN key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SEVEN
     * @type {integer}
     * @since 3.0.0
     */
    SEVEN: 55,

    /**
     * The EIGHT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.EIGHT
     * @type {integer}
     * @since 3.0.0
     */
    EIGHT: 56,

    /**
     * The NINE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NINE
     * @type {integer}
     * @since 3.0.0
     */
    NINE: 57,

    /**
     * The NUMPAD_ZERO key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ZERO
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_ZERO: 96,

    /**
     * The NUMPAD_ONE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_ONE: 97,

    /**
     * The NUMPAD_TWO key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_TWO: 98,

    /**
     * The NUMPAD_THREE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_THREE: 99,

    /**
     * The NUMPAD_FOUR key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FOUR
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_FOUR: 100,

    /**
     * The NUMPAD_FIVE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FIVE
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_FIVE: 101,

    /**
     * The NUMPAD_SIX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SIX
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_SIX: 102,

    /**
     * The NUMPAD_SEVEN key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SEVEN
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_SEVEN: 103,

    /**
     * The NUMPAD_EIGHT key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_EIGHT
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_EIGHT: 104,

    /**
     * The NUMPAD_NINE key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_NINE
     * @type {integer}
     * @since 3.0.0
     */
    NUMPAD_NINE: 105,

    /**
     * The A key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.A
     * @type {integer}
     * @since 3.0.0
     */
    A: 65,

    /**
     * The B key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.B
     * @type {integer}
     * @since 3.0.0
     */
    B: 66,

    /**
     * The C key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.C
     * @type {integer}
     * @since 3.0.0
     */
    C: 67,

    /**
     * The D key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.D
     * @type {integer}
     * @since 3.0.0
     */
    D: 68,

    /**
     * The E key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.E
     * @type {integer}
     * @since 3.0.0
     */
    E: 69,

    /**
     * The F key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F
     * @type {integer}
     * @since 3.0.0
     */
    F: 70,

    /**
     * The G key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.G
     * @type {integer}
     * @since 3.0.0
     */
    G: 71,

    /**
     * The H key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.H
     * @type {integer}
     * @since 3.0.0
     */
    H: 72,

    /**
     * The I key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.I
     * @type {integer}
     * @since 3.0.0
     */
    I: 73,

    /**
     * The J key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.J
     * @type {integer}
     * @since 3.0.0
     */
    J: 74,

    /**
     * The K key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.K
     * @type {integer}
     * @since 3.0.0
     */
    K: 75,

    /**
     * The L key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.L
     * @type {integer}
     * @since 3.0.0
     */
    L: 76,

    /**
     * The M key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.M
     * @type {integer}
     * @since 3.0.0
     */
    M: 77,

    /**
     * The N key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.N
     * @type {integer}
     * @since 3.0.0
     */
    N: 78,

    /**
     * The O key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.O
     * @type {integer}
     * @since 3.0.0
     */
    O: 79,

    /**
     * The P key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.P
     * @type {integer}
     * @since 3.0.0
     */
    P: 80,

    /**
     * The Q key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.Q
     * @type {integer}
     * @since 3.0.0
     */
    Q: 81,

    /**
     * The R key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.R
     * @type {integer}
     * @since 3.0.0
     */
    R: 82,

    /**
     * The S key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.S
     * @type {integer}
     * @since 3.0.0
     */
    S: 83,

    /**
     * The T key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.T
     * @type {integer}
     * @since 3.0.0
     */
    T: 84,

    /**
     * The U key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.U
     * @type {integer}
     * @since 3.0.0
     */
    U: 85,

    /**
     * The V key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.V
     * @type {integer}
     * @since 3.0.0
     */
    V: 86,

    /**
     * The W key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.W
     * @type {integer}
     * @since 3.0.0
     */
    W: 87,

    /**
     * The X key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.X
     * @type {integer}
     * @since 3.0.0
     */
    X: 88,

    /**
     * The Y key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.Y
     * @type {integer}
     * @since 3.0.0
     */
    Y: 89,

    /**
     * The Z key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.Z
     * @type {integer}
     * @since 3.0.0
     */
    Z: 90,

    /**
     * The F1 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F1
     * @type {integer}
     * @since 3.0.0
     */
    F1: 112,

    /**
     * The F2 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F2
     * @type {integer}
     * @since 3.0.0
     */
    F2: 113,

    /**
     * The F3 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F3
     * @type {integer}
     * @since 3.0.0
     */
    F3: 114,

    /**
     * The F4 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F4
     * @type {integer}
     * @since 3.0.0
     */
    F4: 115,

    /**
     * The F5 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F5
     * @type {integer}
     * @since 3.0.0
     */
    F5: 116,

    /**
     * The F6 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F6
     * @type {integer}
     * @since 3.0.0
     */
    F6: 117,

    /**
     * The F7 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F7
     * @type {integer}
     * @since 3.0.0
     */
    F7: 118,

    /**
     * The F8 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F8
     * @type {integer}
     * @since 3.0.0
     */
    F8: 119,

    /**
     * The F9 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F9
     * @type {integer}
     * @since 3.0.0
     */
    F9: 120,

    /**
     * The F10 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F10
     * @type {integer}
     * @since 3.0.0
     */
    F10: 121,

    /**
     * The F11 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F11
     * @type {integer}
     * @since 3.0.0
     */
    F11: 122,

    /**
     * The F12 key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.F12
     * @type {integer}
     * @since 3.0.0
     */
    F12: 123,

    /**
     * The SEMICOLON key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON
     * @type {integer}
     * @since 3.0.0
     */
    SEMICOLON: 186,

    /**
     * The PLUS key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PLUS
     * @type {integer}
     * @since 3.0.0
     */
    PLUS: 187,

    /**
     * The COMMA key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.COMMA
     * @type {integer}
     * @since 3.0.0
     */
    COMMA: 188,

    /**
     * The MINUS key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.MINUS
     * @type {integer}
     * @since 3.0.0
     */
    MINUS: 189,

    /**
     * The PERIOD key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.PERIOD
     * @type {integer}
     * @since 3.0.0
     */
    PERIOD: 190,

    /**
     * The FORWARD_SLASH key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.FORWARD_SLASH
     * @type {integer}
     * @since 3.0.0
     */
    FORWARD_SLASH: 191,

    /**
     * The BACK_SLASH key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.BACK_SLASH
     * @type {integer}
     * @since 3.0.0
     */
    BACK_SLASH: 220,

    /**
     * The QUOTES key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.QUOTES
     * @type {integer}
     * @since 3.0.0
     */
    QUOTES: 222,

    /**
     * The BACKTICK key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.BACKTICK
     * @type {integer}
     * @since 3.0.0
     */
    BACKTICK: 192,

    /**
     * The OPEN_BRACKET key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.OPEN_BRACKET
     * @type {integer}
     * @since 3.0.0
     */
    OPEN_BRACKET: 219,

    /**
     * The CLOSED_BRACKET key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.CLOSED_BRACKET
     * @type {integer}
     * @since 3.0.0
     */
    CLOSED_BRACKET: 221,

    /**
     * The SEMICOLON_FIREFOX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON_FIREFOX
     * @type {integer}
     * @since 3.0.0
     */
    SEMICOLON_FIREFOX: 59,

    /**
     * The COLON key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.COLON
     * @type {integer}
     * @since 3.0.0
     */
    COLON: 58,

    /**
     * The COMMA_FIREFOX_WINDOWS key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX_WINDOWS
     * @type {integer}
     * @since 3.0.0
     */
    COMMA_FIREFOX_WINDOWS: 60,

    /**
     * The COMMA_FIREFOX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX
     * @type {integer}
     * @since 3.0.0
     */
    COMMA_FIREFOX: 62,

    /**
     * The BRACKET_RIGHT_FIREFOX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_RIGHT_FIREFOX
     * @type {integer}
     * @since 3.0.0
     */
    BRACKET_RIGHT_FIREFOX: 174,

    /**
     * The BRACKET_LEFT_FIREFOX key.
     *
     * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_LEFT_FIREFOX
     * @type {integer}
     * @since 3.0.0
     */
    BRACKET_LEFT_FIREFOX: 175
};

module.exports = KeyCodes;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Renders this Game Object with the Canvas Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.Blitter#renderCanvas
 * @since 3.0.0
 * @private
 *
 * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {Phaser.GameObjects.Blitter} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var BlitterCanvasRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
    var list = src.getRenderList();

    if (list.length === 0)
    {
        return;
    }

    var ctx = renderer.currentContext;

    var alpha = camera.alpha * src.alpha;

    if (alpha === 0)
    {
        //  Nothing to see, so abort early
        return;
    }

    //  Blend Mode
    ctx.globalCompositeOperation = renderer.blendModes[src.blendMode];

    var cameraScrollX = src.x - camera.scrollX * src.scrollFactorX;
    var cameraScrollY = src.y - camera.scrollY * src.scrollFactorY;

    ctx.save();

    if (parentMatrix)
    {
        parentMatrix.copyToContext(ctx);
    }

    var roundPixels = camera.roundPixels;

    //  Render bobs
    for (var i = 0; i < list.length; i++)
    {
        var bob = list[i];
        var flip = (bob.flipX || bob.flipY);
        var frame = bob.frame;
        var cd = frame.canvasData;
        var dx = frame.x;
        var dy = frame.y;
        var fx = 1;
        var fy = 1;

        var bobAlpha = bob.alpha * alpha;

        if (bobAlpha === 0)
        {
            continue;
        }

        ctx.globalAlpha = bobAlpha;

        if (!flip)
        {
            if (roundPixels)
            {
                dx = Math.round(dx);
                dy = Math.round(dy);
            }

            ctx.drawImage(
                frame.source.image,
                cd.x,
                cd.y,
                cd.width,
                cd.height,
                dx + bob.x + cameraScrollX,
                dy + bob.y + cameraScrollY,
                cd.width,
                cd.height
            );
        }
        else
        {
            if (bob.flipX)
            {
                fx = -1;
                dx -= cd.width;
            }

            if (bob.flipY)
            {
                fy = -1;
                dy -= cd.height;
            }

            ctx.save();
            ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY);
            ctx.scale(fx, fy);
            ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height);
            ctx.restore();
        }
    }

    ctx.restore();
};

module.exports = BlitterCanvasRenderer;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

require('./polyfills');

var CONST = require('./const');
var Extend = require('./utils/object/Extend');

/**
 * @namespace Phaser
 */

var Phaser = {

    Animations: require('./animations'),
    Cache: require('./cache'),
    Cameras: { Scene2D: require('./cameras/2d') },
    Core: require('./core'),
    Class: require('./utils/Class'),
    Data: require('./data'),
    Display: { Masks: require('./display/mask') },
    Events: require('./events'),
    Game: require('./core/Game'),
    GameObjects: {
        DisplayList: require('./gameobjects/DisplayList'),
        GameObjectCreator: require('./gameobjects/GameObjectCreator'),
        GameObjectFactory: require('./gameobjects/GameObjectFactory'),
        UpdateList: require('./gameobjects/UpdateList'),
        Components: require('./gameobjects/components'),
        BuildGameObject: require('./gameobjects/BuildGameObject'),
        BuildGameObjectAnimation: require('./gameobjects/BuildGameObjectAnimation'),
        GameObject: require('./gameobjects/GameObject'),
        Graphics: require('./gameobjects/graphics/Graphics.js'),
        Image: require('./gameobjects/image/Image'),
        Sprite: require('./gameobjects/sprite/Sprite'),
        Text: require('./gameobjects/text/static/Text'),
        Factories: {
            Graphics: require('./gameobjects/graphics/GraphicsFactory'),
            Image: require('./gameobjects/image/ImageFactory'),
            Sprite: require('./gameobjects/sprite/SpriteFactory'),
            Text: require('./gameobjects/text/static/TextFactory')
        },
        Creators: {
            Graphics: require('./gameobjects/graphics/GraphicsCreator'),
            Image: require('./gameobjects/image/ImageCreator'),
            Sprite: require('./gameobjects/sprite/SpriteCreator'),
            Text: require('./gameobjects/text/static/TextCreator')
        }
    },
    Input: require('./input'),
    Loader: {
        FileTypes: {
            AnimationJSONFile: require('./loader/filetypes/AnimationJSONFile'),
            AtlasJSONFile: require('./loader/filetypes/AtlasJSONFile'),
            AudioFile: require('./loader/filetypes/AudioFile'),
            AudioSpriteFile: require('./loader/filetypes/AudioSpriteFile'),
            HTML5AudioFile: require('./loader/filetypes/HTML5AudioFile'),
            ImageFile: require('./loader/filetypes/ImageFile'),
            JSONFile: require('./loader/filetypes/JSONFile'),
            MultiAtlasFile: require('./loader/filetypes/MultiAtlasFile'),
            PluginFile: require('./loader/filetypes/PluginFile'),
            ScriptFile: require('./loader/filetypes/ScriptFile'),
            SpriteSheetFile: require('./loader/filetypes/SpriteSheetFile'),
            TextFile: require('./loader/filetypes/TextFile'),
            XMLFile: require('./loader/filetypes/XMLFile')
        },
        File: require('./loader/File'),
        FileTypesManager: require('./loader/FileTypesManager'),
        GetURL: require('./loader/GetURL'),
        LoaderPlugin: require('./loader/LoaderPlugin'),
        MergeXHRSettings: require('./loader/MergeXHRSettings'),
        MultiFile: require('./loader/MultiFile'),
        XHRLoader: require('./loader/XHRLoader'),
        XHRSettings: require('./loader/XHRSettings')
    },
    Math: {
        Between: require('./math/Between'),
        DegToRad: require('./math/DegToRad'),
        FloatBetween: require('./math/FloatBetween'),
        RadToDeg: require('./math/RadToDeg'),
        Vector2: require('./math/Vector2')
    },
    Plugins: require('./plugins'),
    Renderer: require('./renderer'),
    Scale: require('./scale'),
    Scene: require('./scene/Scene'),
    Scenes: require('./scene'),
    Sound: require('./sound'),
    Structs: require('./structs'),
    Textures: require('./textures'),
    Time: require('./time'),
    Tweens: require('./tweens')
};

//   Merge in the consts

Phaser = Extend(false, Phaser, CONST);

//  Export it

module.exports = Phaser;

global.Phaser = Phaser;

/*
 * "Documentation is like pizza: when it is good, it is very, very good;
 * and when it is bad, it is better than nothing."
 *  -- Dick Brandon
 */


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Clamp = require('../../../math/Clamp');
var Class = require('../../../utils/Class');
var Events = require('../events');

/**
 * @classdesc
 * A Camera Flash effect.
 *
 * This effect will flash the camera viewport to the given color, over the duration specified.
 *
 * Only the camera viewport is flashed. None of the objects it is displaying are impacted, i.e. their colors do
 * not change.
 *
 * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback,
 * which is invoked each frame for the duration of the effect, if required.
 *
 * @class Flash
 * @memberof Phaser.Cameras.Scene2D.Effects
 * @constructor
 * @since 3.5.0
 *
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon.
 */
var Flash = new Class({

    initialize:

    function Flash (camera)
    {
        /**
         * The Camera this effect belongs to.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#camera
         * @type {Phaser.Cameras.Scene2D.Camera}
         * @readonly
         * @since 3.5.0
         */
        this.camera = camera;

        /**
         * Is this effect actively running?
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#isRunning
         * @type {boolean}
         * @readonly
         * @default false
         * @since 3.5.0
         */
        this.isRunning = false;

        /**
         * The duration of the effect, in milliseconds.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#duration
         * @type {integer}
         * @readonly
         * @default 0
         * @since 3.5.0
         */
        this.duration = 0;

        /**
         * The value of the red color channel the camera will use for the fade effect.
         * A value between 0 and 255.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#red
         * @type {integer}
         * @private
         * @since 3.5.0
         */
        this.red = 0;

        /**
         * The value of the green color channel the camera will use for the fade effect.
         * A value between 0 and 255.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#green
         * @type {integer}
         * @private
         * @since 3.5.0
         */
        this.green = 0;

        /**
         * The value of the blue color channel the camera will use for the fade effect.
         * A value between 0 and 255.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#blue
         * @type {integer}
         * @private
         * @since 3.5.0
         */
        this.blue = 0;

        /**
         * The value of the alpha channel used during the fade effect.
         * A value between 0 and 1.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#alpha
         * @type {number}
         * @private
         * @since 3.5.0
         */
        this.alpha = 0;

        /**
         * If this effect is running this holds the current percentage of the progress, a value between 0 and 1.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#progress
         * @type {number}
         * @since 3.5.0
         */
        this.progress = 0;

        /**
         * Effect elapsed timer.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#_elapsed
         * @type {number}
         * @private
         * @since 3.5.0
         */
        this._elapsed = 0;

        /**
         * This callback is invoked every frame for the duration of the effect.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdate
         * @type {?Phaser.Cameras.Scene2D.Types.CameraFlashCallback}
         * @private
         * @default null
         * @since 3.5.0
         */
        this._onUpdate;

        /**
         * On Complete callback scope.
         *
         * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdateScope
         * @type {any}
         * @private
         * @since 3.5.0
         */
        this._onUpdateScope;
    },

    /**
     * Flashes the Camera to or from the given color over the duration specified.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#start
     * @fires Phaser.Cameras.Scene2D.Events#FLASH_START
     * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE
     * @since 3.5.0
     *
     * @param {integer} [duration=250] - The duration of the effect in milliseconds.
     * @param {integer} [red=255] - The amount to fade the red channel towards. A value between 0 and 255.
     * @param {integer} [green=255] - The amount to fade the green channel towards. A value between 0 and 255.
     * @param {integer} [blue=255] - The amount to fade the blue channel towards. A value between 0 and 255.
     * @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
     * @param {Phaser.Cameras.Scene2D.Types.CameraFlashCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
     * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
     * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
     *
     * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
     */
    start: function (duration, red, green, blue, force, callback, context)
    {
        if (duration === undefined) { duration = 250; }
        if (red === undefined) { red = 255; }
        if (green === undefined) { green = 255; }
        if (blue === undefined) { blue = 255; }
        if (force === undefined) { force = false; }
        if (callback === undefined) { callback = null; }
        if (context === undefined) { context = this.camera.scene; }

        if (!force && this.isRunning)
        {
            return this.camera;
        }

        this.isRunning = true;
        this.duration = duration;
        this.progress = 0;

        this.red = red;
        this.green = green;
        this.blue = blue;
        this.alpha = 1;

        this._elapsed = 0;

        this._onUpdate = callback;
        this._onUpdateScope = context;

        this.camera.emit(Events.FLASH_START, this.camera, this, duration, red, green, blue);

        return this.camera;
    },

    /**
     * The main update loop for this effect. Called automatically by the Camera.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#update
     * @since 3.5.0
     *
     * @param {integer} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
     * @param {number} delta - The delta time, in ms, elapsed since the last frame.
     */
    update: function (time, delta)
    {
        if (!this.isRunning)
        {
            return;
        }

        this._elapsed += delta;

        this.progress = Clamp(this._elapsed / this.duration, 0, 1);

        if (this._onUpdate)
        {
            this._onUpdate.call(this._onUpdateScope, this.camera, this.progress);
        }

        if (this._elapsed < this.duration)
        {
            this.alpha = 1 - this.progress;
        }
        else
        {
            this.effectComplete();
        }
    },

    /**
     * Called internally by the Canvas Renderer.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderCanvas
     * @since 3.5.0
     *
     * @param {CanvasRenderingContext2D} ctx - The Canvas context to render to.
     *
     * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
     */
    postRenderCanvas: function (ctx)
    {
        if (!this.isRunning)
        {
            return false;
        }

        var camera = this.camera;

        ctx.fillStyle = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')';
        ctx.fillRect(camera._cx, camera._cy, camera._cw, camera._ch);

        return true;
    },

    /**
     * Called internally by the WebGL Renderer.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderWebGL
     * @since 3.5.0
     *
     * @param {Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline} pipeline - The WebGL Pipeline to render to.
     * @param {function} getTintFunction - A function that will return the gl safe tint colors.
     *
     * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
     */
    postRenderWebGL: function (pipeline, getTintFunction)
    {
        if (!this.isRunning)
        {
            return false;
        }

        var camera = this.camera;
        var red = this.red / 255;
        var blue = this.blue / 255;
        var green = this.green / 255;

        pipeline.drawFillRect(
            camera._cx, camera._cy, camera._cw, camera._ch,
            getTintFunction(red, green, blue, 1),
            this.alpha
        );

        return true;
    },

    /**
     * Called internally when the effect completes.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#effectComplete
     * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE
     * @since 3.5.0
     */
    effectComplete: function ()
    {
        this._onUpdate = null;
        this._onUpdateScope = null;

        this.isRunning = false;

        this.camera.emit(Events.FLASH_COMPLETE, this.camera, this);
    },

    /**
     * Resets this camera effect.
     * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#reset
     * @since 3.5.0
     */
    reset: function ()
    {
        this.isRunning = false;

        this._onUpdate = null;
        this._onUpdateScope = null;
    },

    /**
     * Destroys this effect, releasing it from the Camera.
     *
     * @method Phaser.Cameras.Scene2D.Effects.Flash#destroy
     * @since 3.5.0
     */
    destroy: function ()
    {
        this.reset();

        this.camera = null;
    }

});

module.exports = Flash;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var StrokePathWebGL = require('../StrokePathWebGL');
var Utils = require('../../../renderer/webgl/Utils');

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.Rectangle#renderWebGL
 * @since 3.13.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {Phaser.GameObjects.Rectangle} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var RectangleWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
    var pipeline = this.pipeline;

    var camMatrix = pipeline._tempMatrix1;
    var shapeMatrix = pipeline._tempMatrix2;
    var calcMatrix = pipeline._tempMatrix3;

    renderer.setPipeline(pipeline);

    shapeMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);

    camMatrix.copyFrom(camera.matrix);

    if (parentMatrix)
    {
        //  Multiply the camera by the parent matrix
        camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);

        //  Undo the camera scroll
        shapeMatrix.e = src.x;
        shapeMatrix.f = src.y;
    }
    else
    {
        shapeMatrix.e -= camera.scrollX * src.scrollFactorX;
        shapeMatrix.f -= camera.scrollY * src.scrollFactorY;
    }

    camMatrix.multiply(shapeMatrix, calcMatrix);

    var dx = src._displayOriginX;
    var dy = src._displayOriginY;
    var alpha = camera.alpha * src.alpha;

    if (src.isFilled)
    {
        var fillTint = pipeline.fillTint;
        var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * alpha);

        fillTint.TL = fillTintColor;
        fillTint.TR = fillTintColor;
        fillTint.BL = fillTintColor;
        fillTint.BR = fillTintColor;

        pipeline.setTexture2D();

        pipeline.batchFillRect(
            -dx,
            -dy,
            src.width,
            src.height
        );
    }

    if (src.isStroked)
    {
        StrokePathWebGL(pipeline, src, alpha, dx, dy);
    }
};

module.exports = RectangleWebGLRenderer;


compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {

keep keep keep keep replace keep keep keep keep


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Class = require('../utils/Class');
var PluginCache = require('../plugins/PluginCache');
var SceneEvents = require('../scene/events');

/**
 * @classdesc
 * The Game Object Creator is a Scene plugin that allows you to quickly create many common
 * types of Game Objects and return them. Unlike the Game Object Factory, they are not automatically
 * added to the Scene.
 *
 * Game Objects directly register themselves with the Creator and inject their own creation
 * methods into the class.
 *
 * @class GameObjectCreator
 * @memberof Phaser.GameObjects
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs.
 */
var GameObjectCreator = new Class({

    initialize:

    function GameObjectCreator (scene)
    {
        /**
         * The Scene to which this Game Object Creator belongs.
         *
         * @name Phaser.GameObjects.GameObjectCreator#scene
         * @type {Phaser.Scene}
         * @protected
         * @since 3.0.0
         */
        this.scene = scene;

        /**
         * A reference to the Scene.Systems.
         *
         * @name Phaser.GameObjects.GameObjectCreator#systems
         * @type {Phaser.Scenes.Systems}
         * @protected
         * @since 3.0.0
         */
        this.systems = scene.sys;

        /**
         * A reference to the Scene Display List.
         *
         * @name Phaser.GameObjects.GameObjectCreator#displayList
         * @type {Phaser.GameObjects.DisplayList}
         * @protected
         * @since 3.0.0
         */
        this.displayList;

        /**
         * A reference to the Scene Update List.
         *
         * @name Phaser.GameObjects.GameObjectCreator#updateList;
         * @type {Phaser.GameObjects.UpdateList}
         * @protected
         * @since 3.0.0
         */
        this.updateList;

        scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
        scene.sys.events.on(SceneEvents.START, this.start, this);
    },

    /**
     * This method is called automatically, only once, when the Scene is first created.
     * Do not invoke it directly.
     *
     * @method Phaser.GameObjects.GameObjectCreator#boot
     * @private
     * @since 3.5.1
     */
    boot: function ()
    {
        this.displayList = this.systems.displayList;
        this.updateList = this.systems.updateList;

        this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
    },

    /**
     * This method is called automatically by the Scene when it is starting up.
     * It is responsible for creating local systems, properties and listening for Scene events.
     * Do not invoke it directly.
     *
     * @method Phaser.GameObjects.GameObjectCreator#start
     * @private
     * @since 3.5.0
     */
    start: function ()
    {
        this.systems.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
    },

    /**
     * The Scene that owns this plugin is shutting down.
     * We need to kill and reset all internal properties as well as stop listening to Scene events.
     *
     * @method Phaser.GameObjects.GameObjectCreator#shutdown
     * @private
     * @since 3.0.0
     */
    shutdown: function ()
    {
        this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
    },

    /**
     * The Scene that owns this plugin is being destroyed.
     * We need to shutdown and then kill off all external references.
     *
     * @method Phaser.GameObjects.GameObjectCreator#destroy
     * @private
     * @since 3.0.0
     */
    destroy: function ()
    {
        this.shutdown();

        this.scene.sys.events.off(SceneEvents.START, this.start, this);

        this.scene = null;
        this.systems = null;
        this.displayList = null;
        this.updateList = null;
    }

});

//  Static method called directly by the Game Object creator functions

GameObjectCreator.register = function (factoryType, factoryFunction)
{
    if (!GameObjectCreator.prototype.hasOwnProperty(factoryType))
    {
        GameObjectCreator.prototype[factoryType] = factoryFunction;
    }
};

PluginCache.register('GameObjectCreator', GameObjectCreator, 'make');

module.exports = GameObjectCreator;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var SetTileCollision = require('./SetTileCollision');
var CalculateFacesWithin = require('./CalculateFacesWithin');
var SetLayerCollisionIndex = require('./SetLayerCollisionIndex');

/**
 * Sets collision on the given tile or tiles within a layer by index. You can pass in either a
 * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if
 * collision will be enabled (true) or disabled (false).
 *
 * @function Phaser.Tilemaps.Components.SetCollision
 * @private
 * @since 3.0.0
 *
 * @param {(integer|array)} indexes - Either a single tile index, or an array of tile indexes.
 * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
 * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 */
var SetCollision = function (indexes, collides, recalculateFaces, layer)
{
    if (collides === undefined) { collides = true; }
    if (recalculateFaces === undefined) { recalculateFaces = true; }
    if (!Array.isArray(indexes)) { indexes = [ indexes ]; }

    // Update the array of colliding indexes
    for (var i = 0; i < indexes.length; i++)
    {
        SetLayerCollisionIndex(indexes[i], collides, layer);
    }

    // Update the tiles
    for (var ty = 0; ty < layer.height; ty++)
    {
        for (var tx = 0; tx < layer.width; tx++)
        {
            var tile = layer.data[ty][tx];

            if (tile && indexes.indexOf(tile.index) !== -1)
            {
                SetTileCollision(tile, collides);
            }
        }
    }

    if (recalculateFaces)
    {
        CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
    }
};

module.exports = SetCollision;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var GameObjectCreator = require('../GameObjectCreator');
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
var Zone = require('./Zone');

/**
 * Creates a new Zone Game Object and returns it.
 *
 * Note: This method will only be available if the Zone Game Object has been built into Phaser.
 *
 * @method Phaser.GameObjects.GameObjectCreator#zone
 * @since 3.0.0
 *
 * @param {object} config - The configuration object this Game Object will use to create itself.
 *
 * @return {Phaser.GameObjects.Zone} The Game Object that was created.
 */
GameObjectCreator.register('zone', function (config)
{
    var x = GetAdvancedValue(config, 'x', 0);
    var y = GetAdvancedValue(config, 'y', 0);
    var width = GetAdvancedValue(config, 'width', 1);
    var height = GetAdvancedValue(config, 'height', width);

    return new Zone(this.scene, x, y, width, height);
});

//  When registering a factory function 'this' refers to the GameObjectCreator context.


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

require('./polyfills');

var CONST = require('./const');
var Extend = require('./utils/object/Extend');

/**
 * @namespace Phaser
 */

var Phaser = {

    Actions: require('./actions'),
    Animations: require('./animations'),
    Cache: require('./cache'),
    Cameras: require('./cameras'),
    Core: require('./core'),
    Class: require('./utils/Class'),
    Create: require('./create'),
    Curves: require('./curves'),
    Data: require('./data'),
    Display: require('./display'),
    DOM: require('./dom'),
    Events: require('./events'),
    Game: require('./core/Game'),
    GameObjects: require('./gameobjects'),
    Geom: require('./geom'),
    Input: require('./input'),
    Loader: require('./loader'),
    Math: require('./math'),
    Physics: require('./physics'),
    Plugins: require('./plugins'),
    Renderer: require('./renderer'),
    Scale: require('./scale'),
    Scene: require('./scene/Scene'),
    Scenes: require('./scene'),
    Sound: require('./sound'),
    Structs: require('./structs'),
    Textures: require('./textures'),
    Tilemaps: require('./tilemaps'),
    Time: require('./time'),
    Tweens: require('./tweens'),
    Utils: require('./utils')

};

//  Merge in the optional plugins

if (typeof PLUGIN_CAMERA3D)
{
    Phaser.Cameras.Sprite3D = require('../plugins/camera3d/src');
    Phaser.GameObjects.Sprite3D = require('../plugins/camera3d/src/sprite3d/Sprite3D');
    Phaser.GameObjects.Factories.Sprite3D = require('../plugins/camera3d/src/sprite3d/Sprite3DFactory');
    Phaser.GameObjects.Creators.Sprite3D = require('../plugins/camera3d/src/sprite3d/Sprite3DCreator');
}

if (typeof PLUGIN_FBINSTANT)
{
    Phaser.FacebookInstantGamesPlugin = require('../plugins/fbinstant/src/FacebookInstantGamesPlugin');
}

//   Merge in the consts

Phaser = Extend(false, Phaser, CONST);

//  Export it

module.exports = Phaser;

global.Phaser = Phaser;

/*
 * "Documentation is like pizza: when it is good, it is very, very good;
 * and when it is bad, it is better than nothing."
 *  -- Dick Brandon
 */


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Provides methods used for setting the WebGL rendering pipeline of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Pipeline
 * @webglOnly
 * @since 3.0.0
 */

var Pipeline = {

    /**
     * The initial WebGL pipeline of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Pipeline#defaultPipeline
     * @type {Phaser.Renderer.WebGL.WebGLPipeline}
     * @default null
     * @webglOnly
     * @since 3.0.0
     */
    defaultPipeline: null,

    /**
     * The current WebGL pipeline of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Pipeline#pipeline
     * @type {Phaser.Renderer.WebGL.WebGLPipeline}
     * @default null
     * @webglOnly
     * @since 3.0.0
     */
    pipeline: null,

    /**
     * Sets the initial WebGL Pipeline of this Game Object.
     * This should only be called during the instantiation of the Game Object.
     *
     * @method Phaser.GameObjects.Components.Pipeline#initPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @param {string} [pipelineName=TextureTintPipeline] - The name of the pipeline to set on this Game Object. Defaults to the Texture Tint Pipeline.
     *
     * @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
     */
    initPipeline: function (pipelineName)
    {
        if (pipelineName === undefined) { pipelineName = 'TextureTintPipeline'; }

        var renderer = this.scene.sys.game.renderer;

        if (renderer && renderer.gl && renderer.hasPipeline(pipelineName))
        {
            this.defaultPipeline = renderer.getPipeline(pipelineName);
            this.pipeline = this.defaultPipeline;

            return true;
        }

        return false;
    },

    /**
     * Sets the active WebGL Pipeline of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Pipeline#setPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @param {string} pipelineName - The name of the pipeline to set on this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setPipeline: function (pipelineName)
    {
        var renderer = this.scene.sys.game.renderer;

        if (renderer && renderer.gl && renderer.hasPipeline(pipelineName))
        {
            this.pipeline = renderer.getPipeline(pipelineName);
        }

        return this;
    },

    /**
     * Resets the WebGL Pipeline of this Game Object back to the default it was created with.
     *
     * @method Phaser.GameObjects.Components.Pipeline#resetPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
     */
    resetPipeline: function ()
    {
        this.pipeline = this.defaultPipeline;

        return (this.pipeline !== null);
    },

    /**
     * Gets the name of the WebGL Pipeline this Game Object is currently using.
     *
     * @method Phaser.GameObjects.Components.Pipeline#getPipelineName
     * @webglOnly
     * @since 3.0.0
     *
     * @return {string} The string-based name of the pipeline being used by this Game Object.
     */
    getPipelineName: function ()
    {
        return this.pipeline.name;
    }

};

module.exports = Pipeline;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y).
 *
 * Calculates the angle of the vector from the first point to the second point.
 *
 * @function Phaser.Math.Angle.BetweenPoints
 * @since 3.0.0
 *
 * @param {(Phaser.Geom.Point|object)} point1 - The first point.
 * @param {(Phaser.Geom.Point|object)} point2 - The second point.
 *
 * @return {number} The angle in radians.
 */
var BetweenPoints = function (point1, point2)
{
    return Math.atan2(point2.y - point1.y, point2.x - point1.x);
};

module.exports = BetweenPoints;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * @namespace Phaser.Actions.Types
 */


exec('node scripts/copy-to-examples-fb.js', (err, stdout, stderr) => {

keep keep keep replace keep keep keep keep keep

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

require('./polyfills');

var CONST = require('./const');
var Extend = require('./utils/object/Extend');

/**
 * @namespace Phaser
 */

var Phaser = {

    Actions: require('./actions'),
    Animations: require('./animations'),
    Cache: require('./cache'),
    Cameras: require('./cameras'),
    Core: require('./core'),
    Class: require('./utils/Class'),
    Create: require('./create'),
    Curves: require('./curves'),
    Data: require('./data'),
    Display: require('./display'),
    DOM: require('./dom'),
    Events: require('./events'),
    Game: require('./core/Game'),
    GameObjects: require('./gameobjects'),
    Geom: require('./geom'),
    Input: require('./input'),
    Loader: require('./loader'),
    Math: require('./math'),
    Physics: {
        Arcade: require('./physics/arcade')
    },
    Plugins: require('./plugins'),
    Scale: require('./scale'),
    Scene: require('./scene/Scene'),
    Scenes: require('./scene'),
    Sound: require('./sound'),
    Structs: require('./structs'),
    Textures: require('./textures'),
    Tilemaps: require('./tilemaps'),
    Time: require('./time'),
    Tweens: require('./tweens'),
    Utils: require('./utils')

};

//   Merge in the consts

Phaser = Extend(false, Phaser, CONST);

//  Export it

module.exports = Phaser;

global.Phaser = Phaser;

/*
 * "Documentation is like pizza: when it is good, it is very, very good;
 * and when it is bad, it is better than nothing."
 *  -- Dick Brandon
 */


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var GetTilesWithin = require('./GetTilesWithin');
var CalculateFacesWithin = require('./CalculateFacesWithin');

/**
 * Copies the tiles in the source rectangular area to a new destination (all specified in tile
 * coordinates) within the layer. This copies all tile properties & recalculates collision
 * information in the destination region.
 *
 * @function Phaser.Tilemaps.Components.Copy
 * @private
 * @since 3.0.0
 *
 * @param {integer} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels.
 * @param {integer} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels.
 * @param {integer} width - The width of the area to copy, in tiles, not pixels.
 * @param {integer} height - The height of the area to copy, in tiles, not pixels.
 * @param {integer} destTileX - The x coordinate of the area to copy to, in tiles, not pixels.
 * @param {integer} destTileY - The y coordinate of the area to copy to, in tiles, not pixels.
 * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
 * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon.
 */
var Copy = function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer)
{
    if (srcTileX < 0) { srcTileX = 0; }
    if (srcTileY < 0) { srcTileY = 0; }
    if (recalculateFaces === undefined) { recalculateFaces = true; }

    var srcTiles = GetTilesWithin(srcTileX, srcTileY, width, height, null, layer);

    var offsetX = destTileX - srcTileX;
    var offsetY = destTileY - srcTileY;

    for (var i = 0; i < srcTiles.length; i++)
    {
        var tileX = srcTiles[i].x + offsetX;
        var tileY = srcTiles[i].y + offsetY;
        if (tileX >= 0 && tileX < layer.width && tileY >= 0 && tileY < layer.height)
        {
            if (layer.data[tileY][tileX])
            {
                layer.data[tileY][tileX].copy(srcTiles[i]);
            }
        }
    }

    if (recalculateFaces)
    {
        // Recalculate the faces within the destination area and neighboring tiles
        CalculateFacesWithin(destTileX - 1, destTileY - 1, width + 2, height + 2, layer);
    }
};

module.exports = Copy;


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * The Scale Manager has successfully entered fullscreen mode.
 *
 * @event Phaser.Scale.Events#ENTER_FULLSCREEN
 * @since 3.16.1
 */
module.exports = 'enterfullscreen';


require('./Array.forEach');
require('./Array.isArray');
require('./AudioContextMonkeyPatch');
require('./console');
require('./Math.trunc');
require('./performance.now');
require('./requestAnimationFrame');
require('./Uint32Array');


keep keep keep keep keep replace keep keep keep

'use strict';

const webpack = require('webpack');
const exec = require('child_process').exec;

module.exports = {
    mode: 'development',

    context: `${__dirname}/src/`,

    entry: {
        phaser: './phaser.js'
    },

    output: {
        path: `${__dirname}/build/`,
        filename: 'phaser-facebook-instant-games.js',
        library: 'Phaser',
        libraryTarget: 'umd',
        sourceMapFilename: '[file].map',
        devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
        devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
        umdNamedDefine: true
    },

    performance: { hints: false },

    plugins: [
        new webpack.DefinePlugin({
            "typeof CANVAS_RENDERER": JSON.stringify(true),
            "typeof WEBGL_RENDERER": JSON.stringify(true),
            "typeof EXPERIMENTAL": JSON.stringify(false),
            "typeof PLUGIN_CAMERA3D": JSON.stringify(false),
            "typeof PLUGIN_FBINSTANT": JSON.stringify(true)
        }),
        {
            apply: (compiler) => {
                compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
                    exec('node scripts/copy-to-examples-fb.js', (err, stdout, stderr) => {
                        if (stdout) process.stdout.write(stdout);
                        if (stderr) process.stderr.write(stderr);
                    });
                });
            }
        }
    ],

    devtool: 'source-map'
};


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * Calculate the length of the given line.
 *
 * @function Phaser.Geom.Line.Length
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Line} line - The line to calculate the length of.
 *
 * @return {number} The length of the line.
 */
var Length = function (line)
{
    return Math.sqrt((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));
};

module.exports = Length;