text: /**
  * The `Matter.Engine` module contains methods for creating and manipulating engines.
  * An engine is a controller that manages updating the simulation of the world.
  * See `Matter.Runner` for an optional game loop utility.
  *
  * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
  *
  * @class Engine
  */
  
  var Engine = {};
  
  module.exports = Engine;
  
  var World = require('../body/World');
  var Sleeping = require('./Sleeping');
  var Resolver = require('../collision/Resolver');
  var Render = require('../render/Render');
  var Pairs = require('../collision/Pairs');
  var Metrics = require('./Metrics');
  var Grid = require('../collision/Grid');
  var Events = require('./Events');
  var Composite = require('../body/Composite');
  var Constraint = require('../constraint/Constraint');
  var Common = require('./Common');
  var Body = require('../body/Body');
  
  (function() {
  
      /**
       * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
       * All properties have default values, and many are pre-calculated automatically based on other properties.
       * See the properties section below for detailed information on what you can pass via the `options` object.
       * @method create
       * @param {object} [options]
       * @return {engine} engine
       */
      Engine.create = function(element, options) {
          // options may be passed as the first (and only) argument
          options = Common.isElement(element) ? options : element;
          element = Common.isElement(element) ? element : null;
          options = options || {};
  
          if (element || options.render) {
              Common.warn('Engine.create: engine.render is deprecated (see docs)');
          }
  
          var defaults = {
              positionIterations: 6,
              velocityIterations: 4,
              constraintIterations: 2,
              enableSleeping: false,
              events: [],
              plugin: {},
              timing: {
                  timestamp: 0,
                  timeScale: 1
              },
              broadphase: {
                  controller: Grid
              }
          };
  
          var engine = Common.extend(defaults, options);
  
          // @deprecated
          if (element || engine.render) {
              var renderDefaults = {
                  element: element,
                  controller: Render
              };
              
              engine.render = Common.extend(renderDefaults, engine.render);
          }
  
          // @deprecated
          if (engine.render && engine.render.controller) {
              engine.render = engine.render.controller.create(engine.render);
          }
  
          // @deprecated
          if (engine.render) {
              engine.render.engine = engine;
          }
  
          engine.world = options.world || World.create(engine.world);
          engine.pairs = Pairs.create();
          engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
          engine.metrics = engine.metrics || { extended: false };
  
          // @if DEBUG
          engine.metrics = Metrics.create(engine.metrics);
          // @endif
  
          return engine;
      };
  
      /**
       * Moves the simulation forward in time by `delta` ms.
       * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
       * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
       * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
       * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
       * See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
       *
       * Triggers `beforeUpdate` and `afterUpdate` events.
       * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
       * @method update
       * @param {engine} engine
       * @param {number} [delta=16.666]
       * @param {number} [correction=1]
       */
      Engine.update = function(engine, delta, correction) {
          delta = delta || 1000 / 60;
          correction = correction || 1;
  
          var world = engine.world,
              timing = engine.timing,
              broadphase = engine.broadphase,
              broadphasePairs = [],
              i;
  
          // increment timestamp
          timing.timestamp += delta * timing.timeScale;
  
          // create an event object
          var event = {
              timestamp: timing.timestamp
          };
  
          Events.trigger(engine, 'beforeUpdate', event);
  
          // get lists of all bodies and constraints, no matter what composites they are in
          var allBodies = Composite.allBodies(world),
              allConstraints = Composite.allConstraints(world);
  
          // @if DEBUG
          // reset metrics logging
          Metrics.reset(engine.metrics);
          // @endif
  
          // if sleeping enabled, call the sleeping controller
          if (engine.enableSleeping)
              Sleeping.update(allBodies, timing.timeScale);
  
          // applies gravity to all bodies
          _bodiesApplyGravity(allBodies, world.gravity);
  
          // update all body position and rotation by integration
          _bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
  
          // update all constraints
          for (i = 0; i < engine.constraintIterations; i++) {
              Constraint.solveAll(allConstraints, timing.timeScale);
          }
          Constraint.postSolveAll(allBodies);
  
          // broadphase pass: find potential collision pairs
          if (broadphase.controller) {
  
              // if world is dirty, we must flush the whole grid
              if (world.isModified)
                  broadphase.controller.clear(broadphase);
  
              // update the grid buckets based on current bodies
              broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
              broadphasePairs = broadphase.pairsList;
          } else {
  
              // if no broadphase set, we just pass all bodies
              broadphasePairs = allBodies;
          }
  
          // clear all composite modified flags
          if (world.isModified) {
              Composite.setModified(world, false, false, true);
          }
  
          // narrowphase pass: find actual collisions, then create or update collision pairs
          var collisions = broadphase.detector(broadphasePairs, engine);
  
          // update collision pairs
          var pairs = engine.pairs,
              timestamp = timing.timestamp;
          Pairs.update(pairs, collisions, timestamp);
          Pairs.removeOld(pairs, timestamp);
  
          // wake up bodies involved in collisions
          if (engine.enableSleeping)
              Sleeping.afterCollisions(pairs.list, timing.timeScale);
  
          // trigger collision events
          if (pairs.collisionStart.length > 0)
              Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart });
  
          // iteratively resolve position between collisions
          Resolver.preSolvePosition(pairs.list);
          for (i = 0; i < engine.positionIterations; i++) {
              Resolver.solvePosition(pairs.list, timing.timeScale);
          }
          Resolver.postSolvePosition(allBodies);
  
          // iteratively resolve velocity between collisions
          Resolver.preSolveVelocity(pairs.list);
          for (i = 0; i < engine.velocityIterations; i++) {
              Resolver.solveVelocity(pairs.list, timing.timeScale);
          }
  
          // trigger collision events
          if (pairs.collisionActive.length > 0)
              Events.trigger(engine, 'collisionActive', { pairs: pairs.collisionActive });
  
          if (pairs.collisionEnd.length > 0)
              Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
  
          // @if DEBUG
          // update metrics log
          Metrics.update(engine.metrics, engine);
          // @endif
  
          // clear force buffers
          _bodiesClearForces(allBodies);
  
          Events.trigger(engine, 'afterUpdate', event);
  
          return engine;
      };
      
      /**
       * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
       * @method merge
       * @param {engine} engineA
       * @param {engine} engineB
       */
      Engine.merge = function(engineA, engineB) {
          Common.extend(engineA, engineB);
          
          if (engineB.world) {
              engineA.world = engineB.world;
  
              Engine.clear(engineA);
  
              var bodies = Composite.allBodies(engineA.world);
  
              for (var i = 0; i < bodies.length; i++) {
                  var body = bodies[i];
                  Sleeping.set(body, false);
                  body.id = Common.nextId();
              }
          }
      };
  
      /**
       * Clears the engine including the world, pairs and broadphase.
       * @method clear
       * @param {engine} engine
       */
      Engine.clear = function(engine) {
          var world = engine.world;
          
          Pairs.clear(engine.pairs);
  
          var broadphase = engine.broadphase;
          if (broadphase.controller) {
              var bodies = Composite.allBodies(world);
              broadphase.controller.clear(broadphase);
              broadphase.controller.update(broadphase, bodies, engine, true);
          }
      };
  
      /**
       * Zeroes the `body.force` and `body.torque` force buffers.
       * @method bodiesClearForces
       * @private
       * @param {body[]} bodies
       */
      var _bodiesClearForces = function(bodies) {
          for (var i = 0; i < bodies.length; i++) {
              var body = bodies[i];
  
              // reset force buffers
              body.force.x = 0;
              body.force.y = 0;
              body.torque = 0;
          }
      };
  
      /**
       * Applys a mass dependant force to all given bodies.
       * @method bodiesApplyGravity
       * @private
       * @param {body[]} bodies
       * @param {vector} gravity
       */
      var _bodiesApplyGravity = function(bodies, gravity) {
          var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;
  
          if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
              return;
          }
          
          for (var i = 0; i < bodies.length; i++) {
              var body = bodies[i];
  
              if (body.isStatic || body.isSleeping)
                  continue;
  
              // apply gravity
              body.force.y += body.mass * gravity.y * gravityScale;
              body.force.x += body.mass * gravity.x * gravityScale;
          }
      };
  
      /**
       * Applys `Body.update` to all given `bodies`.
       * @method updateAll
       * @private
       * @param {body[]} bodies
       * @param {number} deltaTime 
       * The amount of time elapsed between updates
       * @param {number} timeScale
       * @param {number} correction 
       * The Verlet correction factor (deltaTime / lastDeltaTime)
       * @param {bounds} worldBounds
       */
      var _bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) {
          for (var i = 0; i < bodies.length; i++) {
              var body = bodies[i];
  
              if (body.isStatic || body.isSleeping)
                  continue;
  
              Body.update(body, deltaTime, timeScale, correction);
          }
      };
  
      /**
       * An alias for `Runner.run`, see `Matter.Runner` for more information.
       * @method run
       * @param {engine} engine
       */
  
      /**
      * Fired just before an update
      *
      * @event beforeUpdate
      * @param {} event An event object
      * @param {number} event.timestamp The engine.timing.timestamp of the event
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /**
      * Fired after engine update and all collision events
      *
      * @event afterUpdate
      * @param {} event An event object
      * @param {number} event.timestamp The engine.timing.timestamp of the event
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /**
      * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
      *
      * @event collisionStart
      * @param {} event An event object
      * @param {} event.pairs List of affected pairs
      * @param {number} event.timestamp The engine.timing.timestamp of the event
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /**
      * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
      *
      * @event collisionActive
      * @param {} event An event object
      * @param {} event.pairs List of affected pairs
      * @param {number} event.timestamp The engine.timing.timestamp of the event
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /**
      * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
      *
      * @event collisionEnd
      * @param {} event An event object
      * @param {} event.pairs List of affected pairs
      * @param {number} event.timestamp The engine.timing.timestamp of the event
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /*
      *
      *  Properties Documentation
      *
      */
  
      /**
       * An integer `Number` that specifies the number of position iterations to perform each update.
       * The higher the value, the higher quality the simulation will be at the expense of performance.
       *
       * @property positionIterations
       * @type number
       * @default 6
       */
  
      /**
       * An integer `Number` that specifies the number of velocity iterations to perform each update.
       * The higher the value, the higher quality the simulation will be at the expense of performance.
       *
       * @property velocityIterations
       * @type number
       * @default 4
       */
  
      /**
       * An integer `Number` that specifies the number of constraint iterations to perform each update.
       * The higher the value, the higher quality the simulation will be at the expense of performance.
       * The default value of `2` is usually very adequate.
       *
       * @property constraintIterations
       * @type number
       * @default 2
       */
  
      /**
       * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module.
       * Sleeping can improve stability and performance, but often at the expense of accuracy.
       *
       * @property enableSleeping
       * @type boolean
       * @default false
       */
  
      /**
       * An `Object` containing properties regarding the timing systems of the engine. 
       *
       * @property timing
       * @type object
       */
  
      /**
       * A `Number` that specifies the global scaling factor of time for all bodies.
       * A value of `0` freezes the simulation.
       * A value of `0.1` gives a slow-motion effect.
       * A value of `1.2` gives a speed-up effect.
       *
       * @property timing.timeScale
       * @type number
       * @default 1
       */
  
      /**
       * A `Number` that specifies the current simulation-time in milliseconds starting from `0`. 
       * It is incremented on every `Engine.update` by the given `delta` argument. 
       *
       * @property timing.timestamp
       * @type number
       * @default 0
       */
  
      /**
       * An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
       * One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
       *
       * A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
       * It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
       *
       * @property render
       * @type render
       * @deprecated see Demo.js for an example of creating a renderer
       * @default a Matter.Render instance
       */
  
      /**
       * An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
       *
       * @property broadphase
       * @type grid
       * @default a Matter.Grid instance
       */
  
      /**
       * A `World` composite object that will contain all simulated bodies and constraints.
       *
       * @property world
       * @type world
       * @default a Matter.World instance
       */
  
      /**
       * An object reserved for storing plugin-specific properties.
       *
       * @property plugin
       * @type {}
       */
  
  })();
  