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

/**
* The Phaser.Game object 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 Phaser systems, such as physics, sound and input.
* Once that is complete it will start the default State, and then begin the main game loop.
*
* You can access lots of the Phaser systems via the properties on the `game` object. For
* example `game.renderer` is the Renderer, `game.sound` is the Sound Manager, and so on.
*
* Anywhere you can access the `game` property, you can access all of these core systems.
* For example a Sprite has a `game` property, allowing you to talk to the various parts
* of Phaser directly, without having to look after your own references.
*
* In it's most simplest form, a Phaser game can be created by providing the arguments
* to the constructor:
*
* ```
* var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create });
* ```
*
* In the example above it is passing in a State object directly. You can also use the State
* Manager to do this:
*
* ```
* var game = new Phaser.Game(800, 600, Phaser.AUTO);
* game.state.add('Boot', BasicGame.Boot);
* game.state.add('Preloader', BasicGame.Preloader);
* game.state.add('MainMenu', BasicGame.MainMenu);
* game.state.add('Game', BasicGame.Game);
* game.state.start('Boot');
*
* ```
* In the example above, 4 States are added to the State Manager, and Phaser is told to
* start running the `Boot` state when it has finished initializing. There are example
* project templates you can use in the Phaser GitHub repo, inside the `resources` folder.
*
* Instead of specifying arguments you can also pass a single object instead:
*
* ```
* var config = {
*     width: 800,
*     height: 600,
*     renderer: Phaser.AUTO,
*     antialias: true,
*     multiTexture: true,
*     state: {
*         preload: preload,
*         create: create,
*         update: update
*     }
* }
*
* var game = new Phaser.Game(config);
* ```
*
* @class Phaser.Game
* @constructor
* @param {number|string} [width=800] - The width of your game in game pixels. If given as a string the value must be between 0 and 100 and will be used as the percentage width of the parent container, or the browser window if no parent is given.
* @param {number|string} [height=600] - The height of your game in game pixels. If given as a string the value must be between 0 and 100 and will be used as the percentage height of the parent container, or the browser window if no parent is given.
* @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.WEBGL_MULTI, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all).
* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself.
* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null.
* @param {boolean} [pixelArt=false] - Draw all image textures anti-aliased or not. The default is for smooth textures (false), but set to `true` if your game features all pixel art.
*/
Phaser.Game = function (width, height, renderer, parent, state, pixelArt)
{
    /**
    * TODO: Remove this
    * @property {number} id - Phaser Game ID
    * @readonly
    */
    this.id = Phaser.GAMES.push(this) - 1;

    /**
    * @property {object} config - The Phaser.Game configuration object.
    */
    this.config = null;

    /**
    * @property {object} physicsConfig - The Phaser.Physics.World configuration object.
    */
    this.physicsConfig = null;

    /**
    * @property {string|HTMLElement} parent - The Games DOM parent.
    * @default
    */
    this.parent = '';

    /**
    * The current Game Width in pixels.
    *
    * _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
    *
    * @property {integer} width
    * @readonly
    * @default
    */
    this.width = 800;

    /**
    * The current Game Height in pixels.
    *
    * _Do not modify this property directly:_ use {@link Phaser.ScaleManager#setGameSize} - eg. `game.scale.setGameSize(width, height)` - instead.
    *
    * @property {integer} height
    * @readonly
    * @default
    */
    this.height = 600;

    /**
    * The resolution of your game. This value is read only, but can be changed at start time it via a game configuration object.
    *
    * @property {integer} resolution
    * @readonly
    * @default
    */
    this.resolution = 1;

    /**
    * @property {integer} _width - Private internal var.
    * @private
    */
    this._width = 800;

    /**
    * @property {integer} _height - Private internal var.
    * @private
    */
    this._height = 600;

    /**
    * @property {boolean} antialias - Anti-alias graphics. By default scaled images are smoothed in Canvas and WebGL, set anti-alias to false to disable this globally.
    * @default
    */
    this.antialias = true;

    /**
    * Has support for Multiple bound Textures in WebGL been enabled? This is a read-only property.
    * To set it you need to either specify `Phaser.WEBGL_MULTI` as the renderer type, or use the Game
    * Configuration object with the property `multiTexture` set to true. It has to be enabled before
    * Pixi boots, and cannot be changed after the game is running. Once enabled, take advantage of it
    * via the `game.renderer.setTexturePriority` method.
    *
    * @property {boolean} multiTexture
    * @default
    * @readOnly
    */
    this.multiTexture = false;

    /**
    * @property {boolean} preserveDrawingBuffer - The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering.
    * @default
    */
    this.preserveDrawingBuffer = false;

    /**
    * Clear the Canvas each frame before rendering the display list.
    * You can set this to `false` to gain some performance if your game always contains a background that completely fills the display.
    * @property {boolean} clearBeforeRender
    * @default
    */
    this.clearBeforeRender = true;

    /**
    * @property {PIXI.CanvasRenderer|PIXI.WebGLRenderer} renderer - The Pixi Renderer.
    * @protected
    */
    this.renderer = null;

    /**
    * @property {number} renderType - The Renderer this game will use. Either Phaser.AUTO, Phaser.CANVAS, Phaser.WEBGL, Phaser.WEBGL_MULTI or Phaser.HEADLESS.
    * @readonly
    */
    this.renderType = Phaser.AUTO;

    /**
    * @property {Phaser.StateManager} state - The StateManager.
    */
    this.state = new Phaser.StateManager(this, state);

    /**
    * @property {boolean} isBooted - Whether the game engine is booted, aka available.
    * @readonly
    */
    this.isBooted = false;

    /**
    * @property {boolean} isRunning - Is game running or paused?
    * @readonly
    */
    this.isRunning = false;

    /**
    * @property {Phaser.RequestAnimationFrame} raf - Automatically handles the core game loop via requestAnimationFrame or setTimeout
    * @protected
    */
    this.raf = null;

    /**
    * @property {Phaser.GameObject.Factory} add - Reference to the Phaser GameObject Factory.
    */
    this.add = null;

    /**
    * @property {Phaser.GameObjectCreator} make - Reference to the GameObject Creator.
    */
    this.make = null;

    /**
    * @property {Phaser.TextureManager} textures - Reference to the Phaser Texture Manager.
    */
    this.textures = null;

    /**
    * @property {Phaser.UpdateManager} updates - Reference to the Phaser Update Manager.
    */
    this.updates = null;

    /**
    * @property {Phaser.Cache} cache - Reference to the assets cache.
    */
    this.cache = null;

    /**
    * @property {Phaser.Input} input - Reference to the input manager
    */
    this.input = null;

    /**
    * @property {Phaser.Loader} load - Reference to the assets loader.
    */
    this.load = null;

    /**
    * @property {Phaser.Math} math - Reference to the math helper.
    */
    this.math = null;

    /**
    * @property {Phaser.Net} net - Reference to the network class.
    */
    this.net = null;

    /**
    * @property {Phaser.ScaleManager} scale - The game scale manager.
    */
    this.scale = null;

    /**
    * @property {Phaser.SoundManager} sound - Reference to the sound manager.
    */
    this.sound = null;

    /**
    * @property {Phaser.Stage} stage - Reference to the stage.
    */
    this.stage = null;

    /**
    * @property {Phaser.Time} time - Reference to the core game clock.
    */
    this.time = null;

    /**
    * @property {Phaser.TweenManager} tweens - Reference to the tween manager.
    */
    this.tweens = null;

    /**
    * @property {Phaser.World} world - Reference to the world.
    */
    this.world = null;

    /**
    * @property {Phaser.Physics} physics - Reference to the physics manager.
    */
    this.physics = null;

    /**
    * @property {Phaser.PluginManager} plugins - Reference to the plugin manager.
    */
    this.plugins = null;

    /**
    * @property {Phaser.RandomDataGenerator} rnd - Instance of repeatable random data generator helper.
    */
    this.rnd = null;

    /**
    * @property {Phaser.Device} device - Contains device information and capabilities.
    */
    this.device = Phaser.Device;

    /**
    * @property {Phaser.Camera} camera - A handy reference to world.camera.
    */
    this.camera = null;

    /**
    * @property {HTMLCanvasElement} canvas - A handy reference to renderer.view, the canvas that the game is being rendered in to.
    */
    this.canvas = null;

    /**
    * @property {CanvasRenderingContext2D} context - A handy reference to renderer.context (only set for CANVAS games, not WebGL)
    */
    this.context = null;

    /**
    * @property {Phaser.Utils.Debug} debug - A set of useful debug utilities.
    */
    this.debug = null;

    /**
    * @property {Phaser.Particles} particles - The Particle Manager.
    */
    this.particles = null;

    /**
    * @property {Phaser.Create} create - The Asset Generator.
    */
    this.create = null;

    /**
    * If `false` Phaser will automatically render the display list every update. If `true` the render loop will be skipped.
    * You can toggle this value at run-time to gain exact control over when Phaser renders. This can be useful in certain types of game or application.
    * Please note that if you don't render the display list then none of the game object transforms will be updated, so use this value carefully.
    * @property {boolean} lockRender
    * @default
    */
    this.lockRender = false;

    /**
    * @property {boolean} stepping - Enable core loop stepping with Game.enableStep().
    * @default
    * @readonly
    */
    this.stepping = false;

    /**
    * @property {boolean} pendingStep - An internal property used by enableStep, but also useful to query from your own game objects.
    * @default
    * @readonly
    */
    this.pendingStep = false;

    /**
    * @property {number} stepCount - When stepping is enabled this contains the current step cycle.
    * @default
    * @readonly
    */
    this.stepCount = 0;

    /**
    * @property {Phaser.Signal} onPause - This event is fired when the game pauses.
    */
    this.onPause = null;

    /**
    * @property {Phaser.Signal} onResume - This event is fired when the game resumes from a paused state.
    */
    this.onResume = null;

    /**
    * @property {Phaser.Signal} onBlur - This event is fired when the game no longer has focus (typically on page hide).
    */
    this.onBlur = null;

    /**
    * @property {Phaser.Signal} onFocus - This event is fired when the game has focus (typically on page show).
    */
    this.onFocus = null;

    /**
    * @property {boolean} _paused - Is game paused?
    * @private
    */
    this._paused = false;

    /**
    * @property {boolean} _codePaused - Was the game paused via code or a visibility change?
    * @private
    */
    this._codePaused = false;

    /**
    * The ID of the current/last logic update applied this render frame, starting from 0.
    * The first update is `currentUpdateID === 0` and the last update is `currentUpdateID === updatesThisFrame.`
    * @property {integer} currentUpdateID
    * @protected
    */
    this.currentUpdateID = 0;

    /**
    * Number of logic updates expected to occur this render frame; will be 1 unless there are catch-ups required (and allowed).
    * @property {integer} updatesThisFrame
    * @protected
    */
    this.updatesThisFrame = 1;

    /**
    * @property {number} _deltaTime - Accumulate elapsed time until a logic update is due.
    * @private
    */
    this._deltaTime = 0;

    /**
    * @property {number} _lastCount - Remember how many 'catch-up' iterations were used on the logicUpdate last frame.
    * @private
    */
    this._lastCount = 0;

    /**
    * @property {number} _spiraling - If the 'catch-up' iterations are spiraling out of control, this counter is incremented.
    * @private
    */
    this._spiraling = 0;

    /**
    * @property {boolean} _kickstart - Force a logic update + render by default (always set on Boot and State swap)
    * @private
    */
    this._kickstart = true;

    /**
    * If the game is struggling to maintain the desired FPS, this signal will be dispatched.
    * The desired/chosen FPS should probably be closer to the {@link Phaser.Time#suggestedFps} value.
    * @property {Phaser.Signal} fpsProblemNotifier
    * @public
    */
    this.fpsProblemNotifier = new Phaser.Signal();

    /**
    * @property {boolean} forceSingleUpdate - Should the game loop force a logic update, regardless of the delta timer? Set to true if you know you need this. You can toggle it on the fly.
    */
    this.forceSingleUpdate = true;

    /**
    * @property {number} _nextNotification - The soonest game.time.time value that the next fpsProblemNotifier can be dispatched.
    * @private
    */
    this._nextFpsNotification = 0;

    //  Parse the configuration object (if any)
    if (arguments.length === 1 && typeof arguments[0] === 'object')
    {
        this.parseConfig(arguments[0]);
    }
    else
    {
        this.config = { enableDebug: true };

        if (typeof width !== 'undefined')
        {
            this._width = width;
        }

        if (typeof height !== 'undefined')
        {
            this._height = height;
        }

        if (typeof renderer !== 'undefined')
        {
            this.renderType = renderer;
        }

        if (typeof parent !== 'undefined')
        {
            this.parent = parent;
        }

        if (typeof pixelArt !== 'undefined')
        {
            this.antialias = !pixelArt;
        }

        this.rnd = new Phaser.RandomDataGenerator([(Date.now() * Math.random()).toString()]);
    }

    this.device.whenReady(this.boot, this);

    return this;

};

Phaser.Game.prototype = {

    /**
    * Parses a Game configuration object.
    *
    * @method Phaser.Game#parseConfig
    * @protected
    */
    parseConfig: function (config)
    {
        this.config = config;

        if (config['enableDebug'] === undefined)
        {
            this.config.enableDebug = true;
        }

        if (config['width'])
        {
            this._width = config['width'];
        }

        if (config['height'])
        {
            this._height = config['height'];
        }

        if (config['renderer'])
        {
            this.renderType = config['renderer'];
        }

        if (config['parent'])
        {
            this.parent = config['parent'];
        }

        if (config['antialias'] !== undefined)
        {
            this.antialias = config['antialias'];
        }

        if (config['multiTexture'] !== undefined)
        {
            this.multiTexture = config['multiTexture'];
        }

        if (config['resolution'])
        {
            this.resolution = config['resolution'];
        }

        if (config['preserveDrawingBuffer'] !== undefined)
        {
            this.preserveDrawingBuffer = config['preserveDrawingBuffer'];
        }

        if (config['physicsConfig'])
        {
            this.physicsConfig = config['physicsConfig'];
        }

        var seed = [(Date.now() * Math.random()).toString()];

        if (config['seed'])
        {
            seed = config['seed'];
        }

        this.rnd = new Phaser.RandomDataGenerator(seed);

        if (config['state'])
        {
            this.state.add(null, config['state'], true);
        }
    },

    /**
    * Initialize engine sub modules and start the game.
    *
    * @method Phaser.Game#boot
    * @protected
    */
    boot: function ()
    {
        if (this.isBooted)
        {
            return;
        }

        //  Inject any new Factory helpers that exist in the build
        for (var gameobject in Phaser.GameObject)
        {
            if (Phaser.GameObject[gameobject].hasOwnProperty('FACTORY_KEY'))
            {
                var key = Phaser.GameObject[gameobject]['FACTORY_KEY'];

                // console.log('found', key);

                Phaser.GameObject.Factory.prototype[key] = Phaser.GameObject[gameobject]['FACTORY_ADD'];
            }
        }

        this.onPause = new Phaser.Signal();
        this.onResume = new Phaser.Signal();
        this.onBlur = new Phaser.Signal();
        this.onFocus = new Phaser.Signal();

        this.isBooted = true;

        this.math = Phaser.Math;

        this.camera = {
            _shake: {
                x: 0,
                y: 0
            }
        };

        this.scale = new Phaser.ScaleManager(this, this._width, this._height);

        // this.stage = new Phaser.Stage(this);

        this.setUpRenderer();

        this.textures = new Phaser.TextureManager(this);

        // this.world = new Phaser.World(this);

        console.log('UpdateManager alive');

        this.updates = new Phaser.UpdateManager(this);

        // this.state = new Phaser.StateManager(this, this._pendingState);

        this.add = new Phaser.GameObject.Factory(this);

        // this.make = new Phaser.GameObjectCreator(this);
        this.cache = new Phaser.Cache(this);
        // this.load = new Phaser.Loader(this);
        this.time = new Phaser.Time(this);
        this.tweens = new Phaser.TweenManager(this);
        this.input = new Phaser.Input(this);
        this.sound = new Phaser.SoundManager(this);
        this.physics = new Phaser.Physics(this, this.physicsConfig);
        this.particles = new Phaser.Particles(this);
        // this.create = new Phaser.Create(this);
        this.plugins = new Phaser.PluginManager(this);
        this.net = new Phaser.Net(this);

        this.time.boot();
        // this.stage.boot();
        // this.world.boot();
        this.scale.boot();
        this.input.boot();
        this.sound.boot();

        this.state.boot();

        // if (this.config['enableDebug'])
        // {
        //     this.debug = new Phaser.Utils.Debug(this);
        //     this.debug.boot();
        // }
        // else
        // {
            this.debug = { preUpdate: function () {}, update: function () {}, reset: function () {} };
        // }

        this.showDebugHeader();

        this.isRunning = true;

        if (this.config && this.config['forceSetTimeOut'])
        {
            this.raf = new Phaser.RequestAnimationFrame(this, this.config['forceSetTimeOut']);
        }
        else
        {
            this.raf = new Phaser.RequestAnimationFrame(this, false);
        }

        this._kickstart = true;

        if (window['focus'])
        {
            if (!window['PhaserGlobal'] || (window['PhaserGlobal'] && !window['PhaserGlobal'].stopFocus))
            {
                window.focus();
            }
        }

        this.raf.start();

    },

    /**
    * Displays a Phaser version debug header in the console.
    *
    * @method Phaser.Game#showDebugHeader
    * @protected
    */
    showDebugHeader: function () {

        if (window['PhaserGlobal'] && window['PhaserGlobal'].hideBanner)
        {
            return;
        }

        var c = (this.renderType === Phaser.CANVAS) ? 'Canvas' : 'WebGL';

        if (!this.device.ie)
        {
            var args = [
                '%c %c %c %c %c Phaser v' + Phaser.VERSION + ' / Pixi.js / ' + c + '  %c http://phaser.io',
                'background: #ff0000',
                'background: #ffff00',
                'background: #00ff00',
                'background: #00ffff',
                'color: #ffffff; background: #000;',
                'background: #fff'
            ];

            console.log.apply(console, args);
        }
        else if (window['console'])
        {
            console.log('Phaser v' + Phaser.VERSION + ' / Pixi.js / http://phaser.io');
        }

    },

    /**
    * Checks if the device is capable of using the requested renderer and sets it up or an alternative if not.
    *
    * @method Phaser.Game#setUpRenderer
    * @protected
    */
    setUpRenderer: function ()
    {
        if (this.config['canvas'])
        {
            this.canvas = this.config['canvas'];
        }
        else
        {
            this.canvas = Phaser.Canvas.create(this, this.width, this.height, this.config['canvasID'], true);
        }

        if (this.config['canvasStyle'])
        {
            this.canvas.style = this.config['canvasStyle'];
        }
        else
        {
            this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
        }

        if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && !this.device.webGL))
        {
            if (this.device.canvas)
            {
                //  They requested Canvas and their browser supports it
                this.renderType = Phaser.CANVAS;

                // this.renderer = new PIXI.CanvasRenderer(this);
                this.renderer = new Phaser.Renderer.Canvas(this);

                this.context = this.renderer.context;
            }
            else
            {
                throw new Error('Phaser.Game - Cannot create Canvas or WebGL context, aborting.');
            }
        }
        else
        {
            //  They requested WebGL and their browser supports it

            this.renderType = Phaser.WEBGL;

            this.renderer = new Phaser.Renderer.WebGL(this);

            this.context = null;

            //  Move to renderer class
            this.canvas.addEventListener('webglcontextlost', this.contextLost.bind(this), false);
            this.canvas.addEventListener('webglcontextrestored', this.contextRestored.bind(this), false);
        }

        // if (this.device.cocoonJS)
        // {
        //     this.canvas.screencanvas = (this.renderType === Phaser.CANVAS) ? true : false;
        // }

        if (this.renderType !== Phaser.HEADLESS)
        {
            // this.stage.smoothed = this.antialias;

            Phaser.Canvas.addToDOM(this.canvas, this.parent, false);
            Phaser.Canvas.setTouchAction(this.canvas);
        }

    },

    /**
    * Handles WebGL context loss.
    *
    * @method Phaser.Game#contextLost
    * @private
    * @param {Event} event - The webglcontextlost event.
    */
    contextLost: function (event) {

        event.preventDefault();

        this.renderer.contextLost = true;

    },

    /**
    * Handles WebGL context restoration.
    *
    * @method Phaser.Game#contextRestored
    * @private
    */
    contextRestored: function () {

        this.renderer.initContext();

        this.cache.clearGLTextures();

        this.renderer.contextLost = false;

    },

    /**
    * The core game loop.
    *
    * @method Phaser.Game#update
    * @protected
    * @param {number} time - The current time as provided by RequestAnimationFrame.
    */
    update: function (time) {

        this.time.update(time);
        this.updateLogic(this.time.desiredFpsMult);
        this.updateRender(this.time.slowMotion * this.time.desiredFps);
        return;

        /*
        if (this._kickstart)
        {
            this.updateLogic(this.time.desiredFpsMult);

            // call the game render update exactly once every frame
            this.updateRender(this.time.slowMotion * this.time.desiredFps);

            this._kickstart = false;

            return;
        }

        // if the logic time is spiraling upwards, skip a frame entirely
        if (this._spiraling > 1 && !this.forceSingleUpdate)
        {
            // cause an event to warn the program that this CPU can't keep up with the current desiredFps rate
            if (this.time.time > this._nextFpsNotification)
            {
                // only permit one fps notification per 10 seconds
                this._nextFpsNotification = this.time.time + 10000;

                // dispatch the notification signal
                this.fpsProblemNotifier.dispatch();
            }

            // reset the _deltaTime accumulator which will cause all pending dropped frames to be permanently skipped
            this._deltaTime = 0;
            this._spiraling = 0;

            // call the game render update exactly once every frame
            this.updateRender(this.time.slowMotion * this.time.desiredFps);
        }
        else
        {
            // step size taking into account the slow motion speed
            var slowStep = this.time.slowMotion * 1000.0 / this.time.desiredFps;

            // accumulate time until the slowStep threshold is met or exceeded... up to a limit of 3 catch-up frames at slowStep intervals
            this._deltaTime += Math.max(Math.min(slowStep * 3, this.time.elapsed), 0);

            // call the game update logic multiple times if necessary to "catch up" with dropped frames
            // unless forceSingleUpdate is true
            var count = 0;

            this.updatesThisFrame = Math.floor(this._deltaTime / slowStep);

            if (this.forceSingleUpdate)
            {
                this.updatesThisFrame = Math.min(1, this.updatesThisFrame);
            }

            while (this._deltaTime >= slowStep)
            {
                this._deltaTime -= slowStep;
                this.currentUpdateID = count;

                this.updateLogic(this.time.desiredFpsMult);

                count++;

                if (this.forceSingleUpdate && count === 1)
                {
                    break;
                }
                else
                {
                    this.time.refresh();
                }
            }

            // detect spiraling (if the catch-up loop isn't fast enough, the number of iterations will increase constantly)
            if (count > this._lastCount)
            {
                this._spiraling++;
            }
            else if (count < this._lastCount)
            {
                // looks like it caught up successfully, reset the spiral alert counter
                this._spiraling = 0;
            }

            this._lastCount = count;

            // call the game render update exactly once every frame unless we're playing catch-up from a spiral condition
            this.updateRender(this._deltaTime / slowStep);
        }
        */

    },

    /**
    * Updates all logic subsystems in Phaser. Called automatically by Game.update.
    *
    * @method Phaser.Game#updateLogic
    * @protected
    * @param {number} timeStep - The current timeStep value as determined by Game.update.
    */
    updateLogic: function (timeStep)
    {
        if (!this._paused && !this.pendingStep)
        {
            if (this.stepping)
            {
                this.pendingStep = true;
            }

            // this.updates.preUpdate();

            // this.scale.preUpdate();
            // this.debug.preUpdate();
            // this.camera.preUpdate();
            // this.physics.preUpdate();
            this.state.preUpdate(timeStep);
            // this.plugins.preUpdate(timeStep);
            // this.stage.preUpdate();

            this.tweens.update();
            this.state.update();
            // this.stage.update();
            // this.tweens.update();

            // this.sound.update();
            this.input.update();
            // this.physics.update();
            // this.particles.update();
            // this.plugins.update();

            this.state.postUpdate();

            this.plugins.postUpdate();
        }
        else
        {
            // Scaling and device orientation changes are still reflected when paused.
            this.scale.pauseUpdate();
            this.state.pauseUpdate();
            this.debug.preUpdate();
        }

    },

    /**
    * Runs the Render cycle.
    * It starts by calling State.preRender. In here you can do any last minute adjustments of display objects as required.
    * It then calls the renderer, which renders the entire display list, starting from the Stage object and working down.
    * It then calls plugin.render on any loaded plugins, in the order in which they were enabled.
    * After this State.render is called. Any rendering that happens here will take place on-top of the display list.
    * Finally plugin.postRender is called on any loaded plugins, in the order in which they were enabled.
    * This method is called automatically by Game.update, you don't need to call it directly.
    * Should you wish to have fine-grained control over when Phaser renders then use the `Game.lockRender` boolean.
    * Phaser will only render when this boolean is `false`.
    *
    * @method Phaser.Game#updateRender
    * @protected
    * @param {number} elapsedTime - The time elapsed since the last update.
    */
    updateRender: function (elapsedTime)
    {
        if (this.lockRender)
        {
            return;
        }

        // this.state.preRender(elapsedTime);

        this.updates.start();

        this.state.render(this.renderer);

        //  Disabled while building out the new State Manager
        // this.renderer.render();

        // this.plugins.render(elapsedTime);
        // this.state.render(elapsedTime);
        // this.plugins.postRender(elapsedTime);

        this.updates.stop();
    },

    /**
    * Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?)
    * Calling step will advance the game loop by one frame. This is extremely useful for hard to track down errors!
    *
    * @method Phaser.Game#enableStep
    */
    enableStep: function () {

        this.stepping = true;
        this.pendingStep = false;
        this.stepCount = 0;

    },

    /**
    * Disables core game loop stepping.
    *
    * @method Phaser.Game#disableStep
    */
    disableStep: function () {

        this.stepping = false;
        this.pendingStep = false;

    },

    /**
    * When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame.
    * This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress.
    *
    * @method Phaser.Game#step
    */
    step: function () {

        this.pendingStep = false;
        this.stepCount++;

    },

    /**
    * Nukes the entire game from orbit.
    *
    * Calls destroy on Game.state, Game.sound, Game.scale, Game.stage, Game.input, Game.physics and Game.plugins.
    *
    * Then sets all of those local handlers to null, destroys the renderer, removes the canvas from the DOM
    * and resets the PIXI default renderer.
    *
    * @method Phaser.Game#destroy
    */
    destroy: function () {

        this.raf.stop();

        this.state.destroy();
        this.sound.destroy();
        this.scale.destroy();
        this.stage.destroy();
        this.input.destroy();
        this.physics.destroy();
        this.plugins.destroy();

        this.state = null;
        this.sound = null;
        this.scale = null;
        this.stage = null;
        this.input = null;
        this.physics = null;
        this.plugins = null;

        this.cache = null;
        this.load = null;
        this.time = null;
        this.world = null;

        this.isBooted = false;

        this.renderer.destroy(false);

        Phaser.Canvas.removeFromDOM(this.canvas);

        PIXI.defaultRenderer = null;

        Phaser.GAMES[this.id] = null;

    },

    /**
    * Called by the Stage visibility handler.
    *
    * @method Phaser.Game#gamePaused
    * @param {object} event - The DOM event that caused the game to pause, if any.
    * @protected
    */
    gamePaused: function (event) {

        //   If the game is already paused it was done via game code, so don't re-pause it
        if (!this._paused)
        {
            this._paused = true;

            this.time.gamePaused();

            if (this.sound.muteOnPause)
            {
                this.sound.setMute();
            }

            this.onPause.dispatch(event);

            //  Avoids Cordova iOS crash event: https://github.com/photonstorm/phaser/issues/1800
            if (this.device.cordova && this.device.iOS)
            {
                this.lockRender = true;
            }
        }

    },

    /**
    * Called by the Stage visibility handler.
    *
    * @method Phaser.Game#gameResumed
    * @param {object} event - The DOM event that caused the game to pause, if any.
    * @protected
    */
    gameResumed: function (event) {

        //  Game is paused, but wasn't paused via code, so resume it
        if (this._paused && !this._codePaused)
        {
            this._paused = false;

            this.time.gameResumed();

            this.input.reset();

            if (this.sound.muteOnPause)
            {
                this.sound.unsetMute();
            }

            this.onResume.dispatch(event);

            //  Avoids Cordova iOS crash event: https://github.com/photonstorm/phaser/issues/1800
            if (this.device.cordova && this.device.iOS)
            {
                this.lockRender = false;
            }
        }

    },

    /**
    * Called by the Stage visibility handler.
    *
    * @method Phaser.Game#focusLoss
    * @param {object} event - The DOM event that caused the game to pause, if any.
    * @protected
    */
    focusLoss: function (event) {

        this.onBlur.dispatch(event);

        if (!this.stage.disableVisibilityChange)
        {
            this.gamePaused(event);
        }

    },

    /**
    * Called by the Stage visibility handler.
    *
    * @method Phaser.Game#focusGain
    * @param {object} event - The DOM event that caused the game to pause, if any.
    * @protected
    */
    focusGain: function (event) {

        this.onFocus.dispatch(event);

        if (!this.stage.disableVisibilityChange)
        {
            this.gameResumed(event);
        }

    }

};

Phaser.Game.prototype.constructor = Phaser.Game;

/**
* The paused state of the Game. A paused game doesn't update any of its subsystems.
* When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched.
* @name Phaser.Game#paused
* @property {boolean} paused - Gets and sets the paused state of the Game.
*/
Object.defineProperty(Phaser.Game.prototype, "paused", {

    get: function () {
        return this._paused;
    },

    set: function (value) {

        if (value === true)
        {
            if (this._paused === false)
            {
                this._paused = true;
                this.sound.setMute();
                this.time.gamePaused();
                this.onPause.dispatch(this);
            }
            this._codePaused = true;
        }
        else
        {
            if (this._paused)
            {
                this._paused = false;
                this.input.reset();
                this.sound.unsetMute();
                this.time.gameResumed();
                this.onResume.dispatch(this);
            }
            this._codePaused = false;
        }

    }

});

/**
 *
 * "Deleted code is debugged code." - Jeff Sickel
 *
 * ヽ(〃＾▽＾〃)ﾉ
 *
*/


for (var i = 0; i < this.data.length; i++)

var LineToLine = require('./LineToLine');
var Contains = require('../triangle/Contains');

var TriangleToLine = function (triangle, line)
{
    //  If the Triangle contains either the start or end point of the line, it intersects
    if (Contains(triangle, line.getPointA()) || Contains(triangle, line.getPointB()))
    {
        return true;
    }

    //  Now check the line against each line of the Triangle
    if (LineToLine(triangle.getLineA(), line))
    {
        return true;
    }

    if (LineToLine(triangle.getLineB(), line))
    {
        return true;
    }

    if (LineToLine(triangle.getLineC(), line))
    {
        return true;
    }

    return false;
};

module.exports = TriangleToLine;


//  Phaser.Physics

module.exports = {
    Impact: require('./impact'),
    PolyDecomp: require('./poly-decomp/')
};

/*
module.exports = {
    Impact: require('./impact'),
    PolyDecomp: require('./poly-decomp/'),
    MatterJS: require('./matter-js/module/main')
};
*/


keep keep keep add keep keep keep keep keep

var Class = require('../../utils/Class');
var TweenBuilder = require('../builder/TweenBuilder');
var TWEEN_CONST = require('../tween/const');

var Timeline = new Class({

    initialize:

    function Timeline (manager)
    {
        this.manager = manager;

        this.isTimeline = true;

        //  An array of Tween objects, each containing a unique property and target being tweened.
        this.data = [];

        //  data array doesn't usually change, so we can cache the length
        this.totalData = 0;

        //  If true then duration, delay, etc values are all frame totals
        this.useFrames = false;

        //  Scales the time applied to this Tween. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on.
        //  Value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only.
        this.timeScale = 1;

        //  Loop this tween? Can be -1 for an infinite loop, or an integer.
        //  When enabled it will play through ALL TweenDatas again (use TweenData.repeat to loop a single TD)
        this.loop = 0;

        //  Time in ms/frames before the tween loops.
        this.loopDelay = 0;

        //  How many loops are left to run?
        this.loopCounter = 0;

        //  Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes)
        this.completeDelay = 0;

        //  Countdown timer (used by loopDelay and completeDelay)
        this.countdown = 0;

        //  The current state of the tween
        this.state = TWEEN_CONST.PENDING_ADD;

        //  The state of the tween when it was paused (used by Resume)
        this._pausedState = TWEEN_CONST.PENDING_ADD;

        //  Does the Tween start off paused? (if so it needs to be started with Tween.play)
        this.paused = false;

        //  Elapsed time in ms/frames of this run through the Tween.
        this.elapsed = 0;

        //  Total elapsed time in ms/frames of the entire Tween, including looping.
        this.totalElapsed = 0;

        //  Time in ms/frames for the whole Tween to play through once, excluding loop amounts and loop delays
        this.duration = 0;

        //  Value between 0 and 1. The amount through the Tween, excluding loops.
        this.progress = 0;

        //  Time in ms/frames for all Tweens to complete (including looping)
        this.totalDuration = 0;

        //  Value between 0 and 1. The amount through the entire Tween, including looping.
        this.totalProgress = 0;

        this.callbacks = {
            onComplete: null,
            onLoop: null,
            onStart: null,
            onUpdate: null,
            onYoyo: null
        };

        this.callbackScope;
    },

    setTimeScale: function (value)
    {
        this.timeScale = value;

        return this;
    },

    getTimeScale: function ()
    {
        return this.timeScale;
    },

    isPlaying: function ()
    {
        return (this.state === TWEEN_CONST.ACTIVE);
    },

    add: function (config)
    {
        return this.queue(TweenBuilder(this, config));
    },

    queue: function (tween)
    {
        tween.parent = this;
        tween.parentIsTimeline = true;

        this.data.push(tween);

        this.totalData = this.data.length;

        return this;
    },

    hasOffset: function (tween)
    {
        return (tween.offset !== null);
    },

    isOffsetAbsolute: function (value)
    {
        return (typeof(value) === 'number');
    },

    isOffsetRelative: function (value)
    {
        var t = typeof(value);

        if (t === 'string')
        {
            var op = value[0];

            if (op === '-' || op === '+')
            {
                return true;
            }
        }

        return false;
    },

    getRelativeOffset: function (value, base)
    {
        var op = value[0];
        var num = parseFloat(value.substr(2));
        var result = base;

        switch (op)
        {
            case '+':
                result += num;
                break;

            case '-':
                result -= num;
                break;
        }

        //  Cannot ever be < 0
        return Math.max(0, result);
    },

    calcDuration: function ()
    {
        var prevEnd = 0;
        var totalDuration = 0;
        var offsetDuration = 0;

        for (var i = 0; i < this.totalData; i++)
        {
            var tween = this.data[i];

            tween.init();

            if (this.hasOffset(tween))
            {
                if (this.isOffsetAbsolute(tween.offset))
                {
                    //  An actual number, so it defines the start point from the beginning of the timeline
                    tween.calculatedOffset = tween.offset;

                    if (tween.offset === 0)
                    {
                        offsetDuration = 0;
                    }

                    // console.log('Timeline.calcDuration', i, 'absolute', tween.calculatedOffset);
                }
                else if (this.isOffsetRelative(tween.offset))
                {
                    //  A relative offset (i.e. '-=1000', so starts at 'offset' ms relative to the PREVIOUS Tweens ending time)
                    tween.calculatedOffset = this.getRelativeOffset(tween.offset, prevEnd);

                    // console.log('Timeline.calcDuration', i, 'relative', tween.calculatedOffset);
                }
            }
            else
            {
                //  Sequential
                tween.calculatedOffset = offsetDuration;

                // console.log('Timeline.calcDuration', i, 'sequential', tween.calculatedOffset);
            }

            prevEnd = tween.totalDuration + tween.calculatedOffset;

            // console.log('Span', i, tween.calculatedOffset, 'to', prevEnd);

            totalDuration += tween.totalDuration;
            offsetDuration += tween.totalDuration;
        }

        //  Excludes loop values
        this.duration = totalDuration;

        this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop;

        if (this.loopCounter > 0)
        {
            this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter);
        }
        else
        {
            this.totalDuration = this.duration + this.completeDelay;
        }
    },

    init: function ()
    {
        this.calcDuration();

        this.progress = 0;
        this.totalProgress = 0;

        if (this.paused)
        {
            this.state = TWEEN_CONST.PAUSED;

            return false;
        }
        else
        {
            return true;
        }
    },

    resetTweens: function (resetFromLoop)
    {
        for (var i = 0; i < this.totalData; i++)
        {
            var tween = this.data[i];

            tween.play(resetFromLoop);
        }
    },

    setCallback: function (type, callback, params, scope)
    {
        if (Timeline.TYPES.indexOf(type) !== -1)
        {
            this.callbacks[type] = { func: callback, scope: scope, params: params };
        }

        return this;
    },

    play: function ()
    {
        if (this.state === TWEEN_CONST.ACTIVE)
        {
            return;
        }

        if (this.paused)
        {
            this.paused = false;

            this.manager.makeActive(this);

            return;
        }
        else
        {
            this.resetTweens(false);

            this.state = TWEEN_CONST.ACTIVE;
        }

        var onStart = this.callbacks.onStart;

        if (onStart)
        {
            onStart.func.apply(onStart.scope, onStart.params);
        }
    },

    nextState: function ()
    {
        if (this.loopCounter > 0)
        {
            this.resetTweens(true);

            //  Reset the elapsed time
            //  TODO: Probably ought to be set to the remainder from elapsed - duration
            //  as the tweens nearly always over-run by a few ms due to rAf

            this.elapsed = 0;
            this.progress = 0;

            this.loopCounter--;

            var onLoop = this.callbacks.onLoop;

            if (onLoop)
            {
                onLoop.func.apply(onLoop.scope, onLoop.params);
            }

            if (this.loopDelay > 0)
            {
                this.countdown = this.loopDelay;
                this.state = TWEEN_CONST.LOOP_DELAY;
            }
            else
            {
                this.state = TWEEN_CONST.ACTIVE;
            }
        }
        else if (this.completeDelay > 0)
        {
            this.countdown = this.completeDelay;
            this.state = TWEEN_CONST.COMPLETE_DELAY;
        }
        else
        {
            var onComplete = this.callbacks.onComplete;

            if (onComplete)
            {
                onComplete.func.apply(onComplete.scope, onComplete.params);
            }

            this.state = TWEEN_CONST.PENDING_REMOVE;
        }
    },

    //  Returns 'true' if this Timeline has finished and should be removed from the Tween Manager
    //  Otherwise, returns false
    update: function (timestamp, delta)
    {
        if (this.state === TWEEN_CONST.PAUSED)
        {
            return;
        }

        var rawDelta = delta;

        if (this.useFrames)
        {
            delta = 1 * this.manager.timeScale;
        }

        delta *= this.timeScale;

        this.elapsed += delta;
        this.progress = Math.min(this.elapsed / this.duration, 1);

        this.totalElapsed += delta;
        this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1);

        switch (this.state)
        {
            case TWEEN_CONST.ACTIVE:

                var stillRunning = this.totalData;

                for (var i = 0; i < this.totalData; i++)
                {
                    var tween = this.data[i];

                    if (tween.update(timestamp, rawDelta))
                    {
                        stillRunning--;
                    }
                }

                var onUpdate = this.callbacks.onUpdate;

                if (onUpdate)
                {
                    onUpdate.func.apply(onUpdate.scope, onUpdate.params);
                }

                //  Anything still running? If not, we're done
                if (stillRunning === 0)
                {
                    this.nextState();
                }

                break;

            case TWEEN_CONST.LOOP_DELAY:

                this.countdown -= delta;

                if (this.countdown <= 0)
                {
                    this.state = TWEEN_CONST.ACTIVE;
                }

                break;

            case TWEEN_CONST.COMPLETE_DELAY:

                this.countdown -= delta;

                if (this.countdown <= 0)
                {
                    var onComplete = this.callbacks.onComplete;

                    if (onComplete)
                    {
                        onComplete.func.apply(onComplete.scope, onComplete.params);
                    }

                    this.state = TWEEN_CONST.PENDING_REMOVE;
                }

                break;
        }

        return (this.state === TWEEN_CONST.PENDING_REMOVE);
    },

    //  Stops the Tween immediately, whatever stage of progress it is at and flags it for removal by the TweenManager
    stop: function ()
    {
        this.state = TWEEN_CONST.PENDING_REMOVE;
    },

    pause: function ()
    {
        if (this.state === TWEEN_CONST.PAUSED)
        {
            return;
        }

        this.paused = true;

        this._pausedState = this.state;

        this.state = TWEEN_CONST.PAUSED;

        return this;
    },

    resume: function ()
    {
        if (this.state === TWEEN_CONST.PAUSED)
        {
            this.paused = false;

            this.state = this._pausedState;
        }

        return this;
    },

    hasTarget: function ()
    {

    },

    destroy: function ()
    {

    }
});

Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ];

module.exports = Timeline;


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Phaser Source: src/gameobjects/components/Crop.js</title>

	<link type="text/css" rel="stylesheet" href="styles/default.css">

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			Phaser API

					Namespaces

							Phaser

							PIXI

					Classes

							Event

							EventTarget

							Animation

							AnimationManager

							AnimationParser

							ArraySet

							ArrayUtils

							AudioSprite

							BitmapData

							BitmapText

							Bullet

							Button

							Cache

							Camera

							Canvas

							Circle

							Color

							Angle

							Animation

							AutoCull

							Bounds

							BringToTop

							Core

							Crop

							Delta

							Destroy

							FixedToCamera

							Health

							InCamera

							InputEnabled

							InWorld

							LifeSpan

							LoadTexture

							Overlap

							PhysicsBody

							Reset

							ScaleMinMax

							Smoothed

							Create

							Creature

							Device

							DeviceButton

							DOM

							Easing

							Back

							Bounce

							Circular

							Cubic

							Elastic

							Exponential

							Linear

							Quadratic

							Quartic

							Quintic

							Sinusoidal

							Ellipse

							Events

							Filter

							FlexGrid

							FlexLayer

							Frame

							FrameData

							Game

							GameObjectCreator

							GameObjectFactory

							Gamepad

							Graphics

							Group

							Hermite

							Image

							ImageCollection

							Input

							InputHandler

							Key

							Keyboard

							KeyCode

							Line

							LinkedList

							Loader

							LoaderParser

							Math

							Matrix

							Mouse

							MSPointer

							Net

							Particle

							Particles

							Arcade

							Emitter

							Path

							PathFollower

							PathPoint

							Physics

							Arcade

							Body

							TilemapCollision

							Ninja

							AABB

							Body

							Circle

							Tile

							P2

							Body

							BodyDebug

							CollisionGroup

							ContactMaterial

							DistanceConstraint

							FixtureList

							GearConstraint

							InversePointProxy

							LockConstraint

							Material

							PointProxy

							PrismaticConstraint

							RevoluteConstraint

							RotationalSpring

							Spring

							Plugin

							PathManager

							PluginManager

							Point

							Pointer

							PointerMode

							Polygon

							QuadTree

							RandomDataGenerator

							Rectangle

							RenderTexture

							RequestAnimationFrame

							RetroFont

							Rope

							RoundedRectangle

							ScaleManager

							Signal

							SignalBinding

							SinglePad

							Sound

							SoundManager

							Sprite

							SpriteBatch

							Stage

							State

							StateManager

							Text

							Tile

							Tilemap

							TilemapLayer

							TilemapParser

							Tileset

							TileSprite

							Time

							Timer

							TimerEvent

							Touch

							Tween

							TweenData

							TweenManager

							Utils

							Debug

							Video

							Weapon

							World

							AbstractFilter

							BaseTexture

							CanvasBuffer

							CanvasGraphics

							CanvasMaskManager

							CanvasPool

							CanvasRenderer

							CanvasTinter

							ComplexPrimitiveShader

							DisplayObjectContainer

							EarCut

							Event

							EventTarget

							FilterTexture

							Graphics

							GraphicsData

							PIXI

							DisplayObject

							PixiFastShader

							PixiShader

							PrimitiveShader

							RenderTexture

							Rope

							Sprite

							SpriteBatch

							Strip

							StripShader

							Texture

							TilingSprite

							WebGLBlendModeManager

							WebGLFastSpriteBatch

							WebGLFilterManager

							WebGLRenderer

					Global

							ANGLE_DOWN

							ANGLE_LEFT

							ANGLE_NORTH_EAST

							ANGLE_NORTH_WEST

							ANGLE_RIGHT

							ANGLE_SOUTH_EAST

							ANGLE_SOUTH_WEST

							ANGLE_UP

							AUTO

							BITMAPDATA

							BITMAPTEXT

							blendModes

							BOTTOM_CENTER

							BOTTOM_LEFT

							BOTTOM_RIGHT

							BUTTON

							CANVAS

							CANVAS_FILTER

							CENTER

							CIRCLE

							CREATURE

							displayList

							DOWN

							ELLIPSE

							emit

							EMITTER

							GAMES

							GRAPHICS

							GROUP

							HEADLESS

							HORIZONTAL

							IMAGE

							LANDSCAPE

							LEFT

							LEFT_BOTTOM

							LEFT_CENTER

							LEFT_TOP

							LINE

							listeners

							MATRIX

							mixin

							NONE

							off

							on

							once

							PENDING_ATLAS

							Phaser.Path#numPoints
return {number} The total number of PathPoints in this Path.

							POINT

							POINTER

							POLYGON

							PORTRAIT

							RECTANGLE

							removeAllListeners

							RENDERTEXTURE

							RETROFONT

							RIGHT

							RIGHT_BOTTOM

							RIGHT_CENTER

							RIGHT_TOP

							ROPE

							ROUNDEDRECTANGLE

							scaleModes

							SPRITE

							SPRITEBATCH

							stopImmediatePropagation

							stopPropagation

							TEXT

							TILEMAP

							TILEMAPLAYER

							TILESPRITE

							TOP_CENTER

							TOP_LEFT

							TOP_RIGHT

							UP

							VERSION

							VERTICAL

							VIDEO

							WEBGL

							WEBGL_FILTER

					Core

Game

Group

World

Loader

Cache

Time

Camera

State Manager

Tween Manager

Sound Manager

Input Manager

Scale Manager

					Game Objects

Factory (game.add)

Creator (game.make)

Sprite

Image

Sound

Video

Particle Emitter

Particle

Text

Tween

BitmapText

Tilemap

BitmapData

RetroFont

Button

Animation

Graphics

RenderTexture

TileSprite

					Geometry

Circle

Ellipse

Line

Matrix

Point

Polygon

Rectangle

Rounded Rectangle

					Physics

Arcade Physics

Body

Weapon

P2 Physics

Body

Spring

CollisionGroup

ContactMaterial

Ninja Physics

Body

					Input

Input Handler

Pointer

Device Button

Mouse

Keyboard

Key

Key Codes

Gamepad

					Community

Phaser Web Site

Phaser Github

Phaser Examples

Phaser Plugins

Forum

Stack Overflow

Tutorials

Newsletter

Twitter

Slack

Donate

Texture Packer

Source: src/gameobjects/components/Crop.js

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

/**
* The Crop component provides the ability to crop a texture based Game Object to a defined rectangle,
* which can be updated in real-time.
*
* @class
*/
Phaser.Component.Crop = function () {};

Phaser.Component.Crop.prototype = {

    /**
    * The Rectangle used to crop the texture this Game Object uses.
    * Set this property via `crop`.
    * If you modify this property directly you must call `updateCrop` in order to have the change take effect.
    * @property {Phaser.Rectangle} cropRect
    * @default
    */
    cropRect: null,

    /**
    * @property {Phaser.Rectangle} _crop - Internal cache var.
    * @private
    */
    _crop: null,

    /**
    * Crop allows you to crop the texture being used to display this Game Object.
    * Setting a crop rectangle modifies the core texture frame. The Game Object width and height properties will be adjusted accordingly.
    *
    * Cropping takes place from the top-left and can be modified in real-time either by providing an updated rectangle object to this method,
    * or by modifying `cropRect` property directly and then calling `updateCrop`.
    *
    * The rectangle object given to this method can be either a `Phaser.Rectangle` or any other object
    * so long as it has public `x`, `y`, `width`, `height`, `right` and `bottom` properties.
    *
    * A reference to the rectangle is stored in `cropRect` unless the `copy` parameter is `true`,
    * in which case the values are duplicated to a local object.
    *
    * @method
    * @param {Phaser.Rectangle} rect - The Rectangle used during cropping. Pass null or no parameters to clear a previously set crop rectangle.
    * @param {boolean} [copy=false] - If false `cropRect` will be stored as a reference to the given rect. If true it will copy the rect values into a local Phaser Rectangle object stored in cropRect.
    */
    crop: function (rect, copy) {

        if (copy === undefined) { copy = false; }

        if (rect)
        {
            if (copy && this.cropRect !== null)
            {
                this.cropRect.setTo(rect.x, rect.y, rect.width, rect.height);
            }
            else if (copy && this.cropRect === null)
            {
                this.cropRect = new Phaser.Rectangle(rect.x, rect.y, rect.width, rect.height);
            }
            else
            {
                this.cropRect = rect;
            }

            this.updateCrop();
        }
        else
        {
            this._crop = null;
            this.cropRect = null;

            this.resetFrame();
        }

    },

    /**
    * If you have set a crop rectangle on this Game Object via `crop` and since modified the `cropRect` property,
    * or the rectangle it references, then you need to update the crop frame by calling this method.
    *
    * @method
    */
    updateCrop: function () {

        if (!this.cropRect)
        {
            return;
        }

        var oldX = this.texture.crop.x;
        var oldY = this.texture.crop.y;
        var oldW = this.texture.crop.width;
        var oldH = this.texture.crop.height;

        this._crop = Phaser.Rectangle.clone(this.cropRect, this._crop);
        this._crop.x += this._frame.x;
        this._crop.y += this._frame.y;

        var cx = Math.max(this._frame.x, this._crop.x);
        var cy = Math.max(this._frame.y, this._crop.y);
        var cw = Math.min(this._frame.right, this._crop.right) - cx;
        var ch = Math.min(this._frame.bottom, this._crop.bottom) - cy;

        this.texture.crop.x = cx;
        this.texture.crop.y = cy;
        this.texture.crop.width = cw;
        this.texture.crop.height = ch;

        this.texture.frame.width = Math.min(cw, this.cropRect.width);
        this.texture.frame.height = Math.min(ch, this.cropRect.height);

        this.texture.width = this.texture.frame.width;
        this.texture.height = this.texture.frame.height;

        this.texture._updateUvs();

        if (this.tint !== 0xffffff && (oldX !== cx || oldY !== cy || oldW !== cw || oldH !== ch))
        {
            this.texture.requiresReTint = true;
        }

    }

};

		Phaser Copyright © 2012-2016 Photon Storm Ltd.

		Documentation generated by JSDoc 3.4.0
		on Fri Aug 26 2016 01:16:09 GMT+0100 (BST) using the DocStrap template.


var Triangle = require('../../../geom/triangle/Triangle');
var TriangleContains = require('../../../geom/triangle/Contains');

var SetHitAreaTriangle = function (gameObjects, x1, y1, x2, y2, x3, y3, callback)
{
    if (callback === undefined) { callback = TriangleContains; }

    var shape = new Triangle(x1, y1, x2, y2, x3, y3);

    return this.setHitArea(gameObjects, shape, callback);
};

module.exports = SetHitAreaTriangle;


let vec2 = Float32Array;

export default function (dst = new vec2(2)) {

    dst[0] = 1;
    dst[1] = 0;

    return dst;

}


As for standalone style files, any files ending with `.module.(css|sass|scss|less|styl|stylus)` will be processed as CSS modules.

If you wish to be able to use CSS modules without the `.module` postfix, you can set `css: { modules: true }` in `vue.config.js`. This option does not affect `*.vue` files.

You can select pre-processors (Sass/Less/Stylus) when creating the project. If you did not do so, you can also just manually install the corresponding webpack loaders. The loaders are pre-configured and will automatically be picked up. For example, to add Sass to an existing project, simply run:

If you wish to customize the CSS modules class name output you can set the `css: { localIdentName: [name]__[local]--[hash:base64:5]}` in `vue.config.js`.

const { createSchema, validate } = require('@vue/cli-shared-utils')

const schema = createSchema(joi => joi.object({
  baseUrl: joi.string(),
  outputDir: joi.string(),
  compiler: joi.boolean(),
  productionSourceMap: joi.boolean(),
  vueLoader: joi.object(),
  parallel: joi.boolean(),
  devServer: joi.object(),
  dll: joi.alternatives().try(
    joi.boolean(),
    joi.array().items(joi.string())
  ),

  // css
  css: joi.object({
    modules: joi.boolean(),
    extract: joi.boolean(),
    sourceMap: joi.boolean(),
    loaderOptions: joi.object({
      sass: joi.object(),
      less: joi.object(),
      stylus: joi.object()
    })
  }),

  // webpack
  chainWebpack: joi.func(),
  configureWebpack: joi.alternatives().try(
    joi.object(),
    joi.func()
  ),

  // known runtime options for built-in plugins
  lintOnSave: joi.any().valid([true, false, 'error']),
  pwa: joi.object(),

  // 3rd party plugin options
  pluginOptions: joi.object()
}))

exports.validate = (options, cb) => {
  validate(options, schema, cb)
}

exports.defaults = () => ({
  // project deployment base
  baseUrl: '/',

  // where to output built files
  outputDir: 'dist',

  // boolean, use full build?
  compiler: false,

  // vue-loader options
  vueLoader: {
    preserveWhitespace: false,
    template: {
      // for pug
      doctype: 'html'
    }
  },

  // sourceMap for production build?
  productionSourceMap: true,

  // use thread-loader for babel & TS in production build
  // enabled by default if the machine has more than 1 cores
  parallel: require('os').cpus().length > 1,

  // split vendors using autoDLLPlugin?
  // can be an explicit list of dependencies to include in the DLL chunk.
  dll: false,

  css: {
    // extract: true,
    // modules: false,
    // sourceMap: false,
    // loaderOptions: {}
  },

  // whether to use eslint-loader
  lintOnSave: true,

  devServer: {
  /*
    open: process.platform === 'darwin',
    host: '0.0.0.0',
    port: 8080,
    https: false,
    hotOnly: false,
    proxy: null, // string | Object
    before: app => {}
  */
  }
})


/* eslint-disable no-console */

import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n' +
        'For more details, visit https://goo.gl/AFskqB'
      )
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
}


@vue/cli-plugin-unit-jest

unit-jest plugin for vue-cli


keep keep keep keep add keep keep keep keep keep

const localIdentName = '[name]__[local]--[hash:base64:5]'

## CSS

- [PostCSS](#postcss)
- [CSS Modules](#css-modules)
- [Pre-Processors](#pre-processors)
- [Passing Options to Pre-Processor Loaders](#passing-options-to-pre-processor-loaders)

### PostCSS

Vue CLI uses PostCSS internally, and enables [autoprefixer](https://github.com/postcss/autoprefixer) by default. You can configure PostCSS via `.postcssrc` or any config source supported by [postcss-load-config](https://github.com/michael-ciniawsky/postcss-load-config).

### CSS Modules

You can [use CSS Modules in `*.vue` files](https://vue-loader.vuejs.org/en/features/css-modules.html) out of the box with `<style module>`.

As for standalone style files, any files ending with `.module.(css|sass|scss|less|styl|stylus)` will be processed as CSS modules.

If you wish to be able to use CSS modules without the `.module` postfix, you can set `css: { modules: true }` in `vue.config.js`. This option does not affect `*.vue` files.

### Pre-Processors

You can select pre-processors (Sass/Less/Stylus) when creating the project. If you did not do so, you can also just manually install the corresponding webpack loaders. The loaders are pre-configured and will automatically be picked up. For example, to add Sass to an existing project, simply run:

``` sh
npm install -D sass-loader node-sass
```

Then you can import `.scss` files, or use it in `*.vue` files with:

``` vue
<style lang="scss">
$color = red;
</style>
```

### Passing Options to Pre-Processor Loaders

Sometimes you may want to pass options to the pre-processor's webpack loader. You can do that using the `css.loaderOptions` option in `vue.config.js`. For example, to pass some shared global variables to all your Sass styles:

``` js
// vue.config.js
const fs = require('fs')

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: fs.readFileSync('src/variables.scss', 'utf-8')
      }
    }
  }
}
```


@vue/eslint-config-prettier

eslint-config-prettier for vue-cli


## Git Commit Message Convention

> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-angular/readme.md).

#### TL;DR:

Messages must be matched by the following regex:

``` js
/^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|ci|chore|types)(\(.+\))?: .{1,50}/
```

#### Examples

Appears under "Features" header, `compiler` subheader:

```
feat(compiler): add 'comments' option
```

Appears under "Bug Fixes" header, `v-model` subheader, with a link to issue #28:

```
fix(v-model): handle events on blur

close #28
```

Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:

```
perf(core): improve vdom diffing by removing 'foo' option

BREAKING CHANGE: The 'foo' option has been removed.
```

The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.

```
revert: feat(compiler): add 'comments' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
```

### Full Message Format

A commit message consists of a **header**, **body** and **footer**.  The header has a **type**, **scope** and **subject**:

```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

The **header** is mandatory and the **scope** of the header is optional.

### Revert

If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

### Type

If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.

Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.

### Scope

The scope could be anything specifying place of the commit change. For example `core`, `compiler`, `ssr`, `v-model`, `transition` etc...

### Subject

The subject contains succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end

### Body

Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

### Footer

The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.


const babel = require('@babel/core')
const preset = require('../index')
const defaultOptions = {
  babelrc: false,
  presets: [preset]
}

test('polyfill detection', () => {
  let { code } = babel.transformSync(`
    const a = Promise.resolve()
  `.trim(), {
    babelrc: false,
    presets: [[preset, {
      targets: { node: 'current' }
    }]]
  })
  expect(code).not.toMatch(`import "core-js/modules/es6.promise"`)

  ;({ code } = babel.transformSync(`
    const a = Promise.resolve()
  `.trim(), {
    babelrc: false,
    presets: [[preset, {
      targets: { ie: 9 }
    }]]
  }))
  expect(code).toMatch(`import "core-js/modules/es6.promise"`)
})

test('object spread', () => {
  const { code } = babel.transformSync(`
    const a = { ...b }
  `.trim(), defaultOptions)
  expect(code).toMatch(`import "core-js/modules/es6.object.assign"`)
  expect(code).toMatch(`var a = Object.assign({}, b)`)
})

test('dynamic import', () => {
  expect(() => {
    babel.transformSync(`const Foo = () => import('./Foo.vue')`, defaultOptions)
  }).not.toThrow()
})

test('async/await', () => {
  const { code } = babel.transformSync(`
    async function hello () {
      await Promise.resolve()
    }
    hello()
  `.trim(), defaultOptions)
  expect(code).toMatch(`import "core-js/modules/es6.promise"`)
  // should use regenerator runtime
  expect(code).toMatch(`import "regenerator-runtime/runtime"`)
  // should use required helper instead of inline
  expect(code).toMatch(/@babel.*runtime\/helpers\/asyncToGenerator/)
})

test('jsx', () => {
  const { code } = babel.transformSync(`
    export default {
      render () {
        return
bar

      }
    }
  `.trim(), defaultOptions)
  expect(code).toMatch(`var h = arguments[0]`)
  expect(code).toMatch(`return h("div", null, ["bar"])`)
})


const isProd = process.env.NODE_ENV === 'production'

const userOptions = Object.assign(defaultOptions, options.css || {})

const extract = isProd && userOptions.extract !== false

keep keep keep keep keep replace keep keep keep

/**
 * https://github.com/egoist/webpack-handle-css-loader
 * The MIT License (MIT)
 * Copyright (c) EGOIST <0x142857@gmail.com> (github.com/egoist)
 *
 * Modified by Yuxi Evan You
 */

const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = class CSSLoaderResolver {
  /**
   * @param {Object} options
   * @param {boolean} [options.sourceMap=undefined] Enable sourcemaps.
   * @param {boolean} [options.modules=undefined]  Enable CSS modules.
   * @param {boolean} [options.extract=undefined] Extract CSS.
   * @param {boolean} [options.minimize=undefined] Minimize CSS.
   * @param {boolean} [options.postcss=undefined] Enable postcss-loader.
   * @param {Object} [options.loaderOptions={}] Options to pass on to loaders.
   */
  constructor ({
    sourceMap,
    modules,
    extract,
    minimize,
    postcss,
    loaderOptions
  } = {}) {
    this.cssLoader = 'css-loader'
    this.fallbackLoader = 'vue-style-loader'
    this.sourceMap = sourceMap
    this.extract = extract && !process.env.VUE_CLI_CSS_SHADOW_MODE
    this.minimize = minimize
    this.modules = modules
    this.postcss = postcss
    this.loaderOptions = loaderOptions || {}
  }

  getLoader (test, loader, options = {}) {
    const cssLoaderOptions = {
      sourceMap: this.sourceMap,
      minimize: this.minimize
    }

    if (this.modules) {
      cssLoaderOptions.modules = true
      cssLoaderOptions.importLoaders = 1
      cssLoaderOptions.localIdentName = '[name]_[local]__[hash:base64:5]'
    }

    if (loader === 'css') {
      Object.assign(cssLoaderOptions, options)
    }

    const use = [{
      loader: this.cssLoader,
      options: cssLoaderOptions
    }]

    if (loader !== 'postcss' && this.postcss !== false) {
      use.push({
        loader: 'postcss-loader',
        options: {
          sourceMap: this.sourceMap
        }
      })
    }

    if (loader && loader !== 'css') {
      use.push({
        loader: loader + '-loader',
        options: Object.assign({}, this.loaderOptions[loader] || {}, options, {
          sourceMap: this.sourceMap
        })
      })
    }

    return {
      test,
      use: this.extract ? ExtractTextPlugin.extract({
        use,
        fallback: this.fallbackLoader
      }) : [{
        loader: this.fallbackLoader,
        options: {
          shadowMode: !!process.env.VUE_CLI_CSS_SHADOW_MODE,
          sourceMap: this.sourceMap
        }
      }, ...use]
    }
  }

  css (test = /\.css$/) {
    return this.getLoader(test, 'css')
  }

  sass (test = /\.sass$/) {
    return this.getLoader(test, 'sass', {
      indentedSyntax: true
    })
  }

  scss (test = /\.scss$/) {
    return this.getLoader(test, 'sass')
  }

  less (test = /\.less$/) {
    return this.getLoader(test, 'less')
  }

  styl (test = /\.styl$/) {
    return this.getLoader(test, 'stylus')
  }

  stylus (test = /\.stylus$/) {
    return this.getLoader(test, 'stylus')
  }

  vue () {
    const originalPostcss = this.postcss
    const originalModules = this.modules
    this.postcss = false
    this.modules = false
    const loaders = {}
    for (const lang of ['css', 'sass', 'scss', 'less', 'stylus', 'styl']) {
      loaders[lang] = this[lang]().use
    }
    this.postcss = originalPostcss
    this.modules = originalModules
    return loaders
  }
}


module.exports = {
  extends: [
    require.resolve('eslint-config-standard')
  ]
}


function removeArg (rawArgs, arg) {
  const matchRE = new RegExp(`^--${arg}`)
  const equalRE = new RegExp(`^--${arg}=`)
  const i = rawArgs.findIndex(arg => matchRE.test(arg))
  if (i > -1) {
    rawArgs.splice(i, equalRE.test(rawArgs[i]) ? 1 : 2)
  }
}

module.exports = (api, options) => {
  api.registerCommand('e2e', {
    description: 'run e2e tests with nightwatch',
    usage: 'vue-cli-service e2e [options]',
    options: {
      '--url': 'run e2e tests against given url instead of auto-starting dev server',
      '-e, --env': 'specify comma-delimited browser envs to run in (default: chrome)',
      '-t, --test': 'sepcify a test to run by name',
      '-f, --filter': 'glob to filter tests by filename'
    },
    details:
      `All Nightwatch CLI options are also supported.\n` +
      `https://github.com/nightwatchjs/nightwatch/blob/master/lib/runner/cli/cli.js`
  }, (args, rawArgs) => {
    removeArg(rawArgs, 'url')
    removeArg(rawArgs, 'mode')

    const serverPromise = args.url
      ? Promise.resolve({ url: args.url })
      : api.service.run('serve', { mode: args.mode || 'production' })

    return serverPromise.then(({ server, url }) => {
      // expose dev server url to tests
      process.env.VUE_DEV_SERVER_URL = url
      // expose user options to config file
      const fs = require('fs')
      let userOptionsPath, userOptions
      if (fs.existsSync(userOptionsPath = api.resolve('nightwatch.config.js'))) {
        userOptions = require(userOptionsPath)
      } else if (fs.existsSync(userOptionsPath = api.resolve('nightwatch.json'))) {
        userOptions = require(userOptionsPath)
      }
      process.env.VUE_NIGHTWATCH_USER_OPTIONS = JSON.stringify(userOptions || {})

      rawArgs.push('--config', require.resolve('./nightwatch.config.js'))
      if (rawArgs.indexOf('--env') === -1) {
        rawArgs.push('--env', 'chrome')
      }

      const execa = require('execa')
      const nightWatchBinPath = require.resolve('nightwatch/bin/nightwatch')
      const runner = execa(nightWatchBinPath, rawArgs, { stdio: 'inherit' })
      if (server) {
        runner.on('exit', () => server.close())
        runner.on('error', () => server.close())
      }

      if (process.env.VUE_CLI_TEST) {
        runner.on('exit', code => {
          process.exit(code)
        })
      }

      return runner
    })
  })
}


<template>

{{ msg }}

      For guide and recipes on how to configure / customize this project,

      check out the
      vue-cli documentation.

Installed CLI Plugins

      <%_ for (plugin of plugins) { _%>

<a href="<%- plugin.link %>" target="_blank"><%- plugin.name %>

      <%_ } _%>

Essential Links

Core Docs

Forum

Community Chat

Twitter

Ecosystem

vue-router

vuex

vue-devtools

vue-loader

awesome-vue

</template>


// ensure user injected vueLoader options take higher priority

options.loaders = Object.assign(resolver.vue(), options.loaders)

keep keep keep keep replace keep keep keep


module.exports = api => {
  api.render('./template', {
    hasTS: api.hasPlugin('typescript')
  })

  api.extendPackage({
    scripts: {
      e2e: 'vue-cli-service e2e'
    }
  })
}


const fs = require('fs')

module.exports = function loadEnv (path = '.env') {
  const config = parse(fs.readFileSync(path, 'utf-8'))
  Object.keys(config).forEach(key => {
    process.env[key] = config[key]
  })
  return config
}

function parse (src) {
  const res = {}
  src.split('\n').forEach(line => {
    // matching "KEY' and 'VAL' in 'KEY=VAL'
    const keyValueArr = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/)
    // matched?
    if (keyValueArr != null) {
      const key = keyValueArr[1]
      let value = keyValueArr[2] || ''

      // expand newlines in quoted values
      const len = value ? value.length : 0
      if (len > 0 && value.charAt(0) === '"' && value.charAt(len - 1) === '"') {
        value = value.replace(/\\n/gm, '\n')
      }

      // remove any surrounding quotes and extra spaces
      value = value.replace(/(^['"]|['"]$)/g, '').trim()

      res[key] = value
    }
  })
  return res
}


// css
css: joi.object({
modules: joi.boolean(),
extract: joi.boolean(),
sourceMap: joi.boolean(),
loaderOptions: joi.object({
sass: joi.object(),
less: joi.object(),
stylus: joi.object()


// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')


@vue/cli-plugin-pwa

pwa plugin for vue-cli


css: {
// extract: true,
// modules: false,
// sourceMap: false,
// loaderOptions: {}
},


version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: vuejs/ci

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "yarn.lock" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run: yarn install

      - save_cache:
          paths:
            - node_modules
            - ~/.cache/yarn
          key: v1-dependencies-{{ checksum "yarn.lock" }}

      # run tests!
      - run: yarn test


# @vue/cli-plugin-e2e-cypress

> e2e-cypress plugin for vue-cli

This adds E2E testing support using [Cypress](https://www.cypress.io/).

Cypress offers a rich interactive interface for running E2E tests, but currently only supports running the tests in Chromium. If you have a hard requirement on E2E testing in multiple browsers, consider using the Selenium-based [@vue/cli-plugin-e2e-nightwatch](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-nightwatch).

## Injected Commands

- **`vue-cli-service e2e`**

  run e2e tests headlessly with `cypress run`.

  Options:

  ```
  --url      run e2e tests against given url instead of auto-starting dev server
  -s, --spec runs a specific spec file. defaults to "all"
  ```

  Additionally, [all Cypress CLI options for `cypress run` are also supported](https://docs.cypress.io/guides/guides/command-line.html#cypress-run).

- **`vue-cli-service e2e:open`**

  run e2e tests in interactive mode with `cypress open`.

  Options:

  ```
  --url      run e2e tests against given url instead of auto-starting dev server
  ```

  Additionally, [all Cypress CLI options for `cypress open` are also supported](https://docs.cypress.io/guides/guides/command-line.html#cypress-open).

  Both commands automatically starts a server in production mode to run the e2e tests against. If you want to run the tests multiple times without having to restart the server every time, you can start the server with `vue-cli-service serve --mode production` in one terminal, and then run e2e tests against that server using the `--url` option.

## Configuration

We've pre-configured Cypress to place most of the e2e testing related files under `<projectRoot>/tests/e2e`. You can also check out [how to configure Cypress via `cypress.json`](https://docs.cypress.io/guides/references/configuration.html#Options).

## Installing in an Already Created Project

``` sh
npm install -D @vue/cli-plugin-e2e-cypress
vue invoke e2e-cypress
```


* @param {boolean} [options.sourceMap=undefined] Enable sourcemaps.

* @param {boolean} [options.modules=undefined]  Enable CSS modules.

* @param {boolean} [options.extract=undefined] Extract CSS.

* @param {boolean} [options.minimize=undefined] Minimize CSS.

* @param {boolean} [options.postcss=undefined] Enable postcss-loader.

* @param {Object} [options.loaderOptions={}] Options to pass on to loaders.

* @param {string} [options.localIdentName='[name]_[local]__[hash:base64:5]']  Customizes CSS modules localIdentName.


@vue/cli-plugin-babel

babel plugin for vue-cli


const fs = require('fs')
const path = require('path')

const findExisting = (context, files) => {
  for (const file of files) {
    if (fs.existsSync(path.join(context, file))) {
      return file
    }
  }
}

module.exports = (api, options) => {
  api.chainWebpack(webpackConfig => {
    const CSSLoaderResolver = require('../webpack/CSSLoaderResolver')
    const ExtractTextPlugin = require('extract-text-webpack-plugin')

    const isProd = process.env.NODE_ENV === 'production'
    const defaultOptions = {
      extract: true,
      modules: false,
      sourceMap: false,
      loaderOptions: {}
    }
    const userOptions = Object.assign(defaultOptions, options.css || {})
    const extract = isProd && userOptions.extract !== false

    // check if the project has a valid postcss config
    // if it doesn't, don't use postcss-loader for direct style imports
    // because otherwise it would throw error when attempting to load postcss config
    const hasPostCSSConfig = !!(api.service.pkg.postcss || findExisting(api.resolve('.'), [
      '.postcssrc',
      '.postcssrc.js',
      'postcss.config.js',
      '.postcssrc.yaml',
      '.postcssrc.json'
    ]))

    const baseOptions = Object.assign({}, userOptions, {
      extract,
      minimize: isProd,
      postcss: hasPostCSSConfig
    })

    const resolver = new CSSLoaderResolver(baseOptions)

    // apply css loaders for vue-loader
    webpackConfig.module
      .rule('vue')
        .use('vue-loader')
        .tap(options => {
          // ensure user injected vueLoader options take higher priority
          options.loaders = Object.assign(resolver.vue(), options.loaders)
          options.cssSourceMap = !!userOptions.cssSourceMap
          options.cssModules = Object.assign({
            localIdentName: '[name]_[local]__[hash:base64:5]'
          }, options.cssModules)
          return options
        })

    // apply css loaders for standalone style files outside vue-loader
    const langs = ['css', 'stylus', 'styl', 'sass', 'scss', 'less']
    for (const lang of langs) {
      const rule = resolver[lang]()
      const context = webpackConfig.module
        .rule(lang)
        .test(rule.test)
        .include
          .add(filepath => {
            // Not ends with `.module.xxx`
            return !/\.module\.[a-z]+$/.test(filepath)
          })
          .end()

      rule.use.forEach(use => {
        context
          .use(use.loader)
            .loader(use.loader)
            .options(use.options)
      })
    }

    // handle cssModules for *.module.js
    const cssModulesResolver = new CSSLoaderResolver(Object.assign({}, baseOptions, {
      modules: true
    }))

    const cssModulesLangs = langs.map(lang => [lang, new RegExp(`\\.module\\.${lang}$`)])
    for (const cssModulesLang of cssModulesLangs) {
      const [lang, test] = cssModulesLang
      const rule = cssModulesResolver[lang](test)
      const context = webpackConfig.module
        .rule(`${lang}-module`)
        .test(rule.test)

      rule.use.forEach(use => {
        context
          .use(use.loader)
            .loader(use.loader)
            .options(use.options)
      })
    }

    // inject CSS extraction plugin
    if (extract) {
      const userOptions = options.extractCSS && typeof options.extractCSS === 'object'
        ? options.extractCSS
        : {}
      webpackConfig
        .plugin('extract-css')
          .use(ExtractTextPlugin, [Object.assign({
            filename: `css/[name].[contenthash:8].css`,
            allChunks: true
          }, userOptions)])
    }

    // TODO document receipe for using css.loaderOptions to add `data` option
    // to sass-loader
  })
}


const fs = require('fs')
const path = require('path')
const execa = require('execa')
const resolve = require('resolve')

module.exports = function inspect (paths, mode) {
  const cwd = process.cwd()
  let servicePath
  try {
    servicePath = resolve.sync('@vue/cli-service', { basedir: cwd })
  } catch (e) {
    const { error } = require('@vue/cli-shared-utils')
    error(`Failed to locate @vue/cli-service. Make sure you are in the right directory.`)
    process.exit(1)
  }
  const binPath = path.resolve(servicePath, '../../bin/vue-cli-service.js')
  if (fs.existsSync(binPath)) {
    execa('node', [
      binPath,
      'inspect',
      ...(mode ? ['--mode', mode] : []),
      ...paths
    ], { cwd, stdio: 'inherit' })
  }
}


module.exports = function silence (logName, exports) {
  const logs = {}
  Object.keys(exports).forEach(key => {
    if (key !== 'error') {
      exports[key] = (...args) => {
        if (!logs[key]) logs[key] = []
        logs[key].push(args)
      }
    }
  })
  exports[logName] = logs
}


this.extract = extract && !process.env.VUE_CLI_CSS_SHADOW_MODE

this.loaderOptions = loaderOptions || {}

getLoader (test, loader, options = {}) {


/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file at
 * https://github.com/facebookincubator/create-react-app/blob/master/LICENSE
 */

const fs = require('fs')
const url = require('url')
const path = require('path')
const chalk = require('chalk')
const address = require('address')

module.exports = function prepareProxy (proxy, appPublicFolder) {
  // `proxy` lets you specify alternate servers for specific requests.
  // It can either be a string or an object conforming to the Webpack dev server proxy configuration
  // https://webpack.github.io/docs/webpack-dev-server.html
  if (!proxy) {
    return undefined
  }
  if (typeof proxy !== 'object' && typeof proxy !== 'string') {
    console.log(
      chalk.red(
        'When specified, "proxy" in package.json must be a string or an object.'
      )
    )
    console.log(
      chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')
    )
    console.log(
      chalk.red(
        'Either remove "proxy" from package.json, or make it an object.'
      )
    )
    process.exit(1)
  }

  // Otherwise, if proxy is specified, we will let it handle any request except for files in the public folder.
  function mayProxy (pathname) {
    const maybePublicPath = path.resolve(appPublicFolder, pathname.slice(1))
    return !fs.existsSync(maybePublicPath)
  }

  // Support proxy as a string for those who are using the simple proxy option
  if (typeof proxy === 'string') {
    if (!/^http(s)?:\/\//.test(proxy)) {
      console.log(
        chalk.red(
          'When "proxy" is specified in package.json it must start with either http:// or https://'
        )
      )
      process.exit(1)
    }

    let target
    if (process.platform === 'win32') {
      target = resolveLoopback(proxy)
    } else {
      target = proxy
    }
    return [
      {
        target,
        logLevel: 'silent',
        // For single page apps, we generally want to fallback to /index.html.
        // However we also want to respect `proxy` for API calls.
        // So if `proxy` is specified as a string, we need to decide which fallback to use.
        // We use a heuristic: if request `accept`s text/html, we pick /index.html.
        // Modern browsers include text/html into `accept` header when navigating.
        // However API calls like `fetch()` won’t generally accept text/html.
        // If this heuristic doesn’t work well for you, use a custom `proxy` object.
        context: function (pathname, req) {
          return (
            mayProxy(pathname) &&
            req.headers.accept &&
            req.headers.accept.indexOf('text/html') === -1
          )
        },
        onProxyReq: proxyReq => {
          // Browers may send Origin headers even with same-origin
          // requests. To prevent CORS issues, we have to change
          // the Origin to match the target URL.
          if (proxyReq.getHeader('origin')) {
            proxyReq.setHeader('origin', target)
          }
        },
        onError: onProxyError(target),
        secure: false,
        changeOrigin: true,
        ws: true,
        xfwd: true
      }
    ]
  }

  // Otherwise, proxy is an object so create an array of proxies to pass to webpackDevServer
  return Object.keys(proxy).map(function (context) {
    if (!proxy[context].hasOwnProperty('target')) {
      console.log(
        chalk.red(
          'When `proxy` in package.json is as an object, each `context` object must have a ' +
            '`target` property specified as a url string'
        )
      )
      process.exit(1)
    }
    let target
    if (process.platform === 'win32') {
      target = resolveLoopback(proxy[context].target)
    } else {
      target = proxy[context].target
    }
    return Object.assign({}, proxy[context], {
      context: function (pathname) {
        return mayProxy(pathname) && pathname.match(context)
      },
      onProxyReq: proxyReq => {
        // Browers may send Origin headers even with same-origin
        // requests. To prevent CORS issues, we have to change
        // the Origin to match the target URL.
        if (proxyReq.getHeader('origin')) {
          proxyReq.setHeader('origin', target)
        }
      },
      target,
      onError: onProxyError(target)
    })
  })
}

function resolveLoopback (proxy) {
  const o = url.parse(proxy)
  o.host = undefined
  if (o.hostname !== 'localhost') {
    return proxy
  }
  // Unfortunately, many languages (unlike node) do not yet support IPv6.
  // This means even though localhost resolves to ::1, the application
  // must fall back to IPv4 (on 127.0.0.1).
  // We can re-enable this in a few years.
  /* try {
    o.hostname = address.ipv6() ? '::1' : '127.0.0.1';
  } catch (_ignored) {
    o.hostname = '127.0.0.1';
  }*/

  try {
    // Check if we're on a network; if we are, chances are we can resolve
    // localhost. Otherwise, we can just be safe and assume localhost is
    // IPv4 for maximum compatibility.
    if (!address.ip()) {
      o.hostname = '127.0.0.1'
    }
  } catch (_ignored) {
    o.hostname = '127.0.0.1'
  }
  return url.format(o)
}

// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError (proxy) {
  return (err, req, res) => {
    const host = req.headers && req.headers.host
    console.log(
      chalk.red('Proxy error:') +
        ' Could not proxy request ' +
        chalk.cyan(req.url) +
        ' from ' +
        chalk.cyan(host) +
        ' to ' +
        chalk.cyan(proxy) +
        '.'
    )
    console.log(
      'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
        chalk.cyan(err.code) +
        ').'
    )
    console.log()

    // And immediately send the proper error response to the client.
    // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
    if (res.writeHead && !res.headersSent) {
      res.writeHead(500)
    }
    res.end(
      'Proxy error: Could not proxy request ' +
        req.url +
        ' from ' +
        host +
        ' to ' +
        proxy +
        ' (' +
        err.code +
        ').'
    )
  }
}


@vue/cli-plugin-typescript

typescript plugin for vue-cli


jest.mock('fs')
jest.mock('inquirer')

const assertPromptModule = require('@vue/cli-test-utils/assertPromptModule')

const moduleToTest = require('../pwa')

test('pwa', async () => {
  const expectedPrompts = [
    {
      message: 'features',
      choices: ['PWA'],
      check: [0]
    }
  ]

  const expectedOptions = {
    plugins: {
      '@vue/cli-plugin-pwa': {}
    }
  }

  await assertPromptModule(
    moduleToTest,
    expectedPrompts,
    expectedOptions,
    { plguinsOnly: true }
  )
})


keep keep keep keep keep replace keep keep keep keep keep


module.exports = async function getVersions () {
  const current = require(`../../package.json`).version
  let latest
  if (process.env.VUE_CLI_LATEST_VERSION) {
    // cached value
    latest = process.env.VUE_CLI_LATEST_VERSION
  } else if (process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG) {
    // test/debug, use local version
    latest = process.env.VUE_CLI_LATEST_VERSION = current
  } else {
    const request = require('./request')
    const options = require('../options').loadOptions()
    const registry = options.useTaobaoRegistry
      ? `https://registry.npm.taobao.org`
      : `https://registry.npmjs.org`

    const res = await request.get(`${registry}/vue-cli-version-marker/latest`)
    if (res.statusCode === 200) {
      latest = process.env.VUE_CLI_LATEST_VERSION = res.body.version
    } else {
      // fallback to local version
      latest = process.env.VUE_CLI_LATEST_VERSION = current
    }
  }
  return {
    current,
    latest
  }
}


@vue/eslint-config-standard

eslint-config-standard for vue-cli


const fs = require('fs')
const path = require('path')

exports.toPlugin = id => ({ id, apply: require(id) })

exports.findExisting = (context, files) => {
  for (const file of files) {
    if (fs.existsSync(path.join(context, file))) {
      return file
    }
  }
}