From d4cb938941d49a6ceb8dfb14d93b7a66eb6e286a Mon Sep 17 00:00:00 2001 From: liabru Date: Thu, 16 Feb 2023 14:19:15 +0000 Subject: [PATCH] release 0.19.0 --- CHANGELOG.md | 36 + RELEASE.md | 53 + build/matter.js | 7843 +++++++++-------- build/matter.min.js | 4 +- demo/index.html | 2 +- demo/js/matter-demo.6283b1.min.js | 6 + demo/js/matter-demo.a280d3.min.js | 6 - demo/js/matter-demo.main.5754e1.min.js | 2 +- .../js/matter-demo.matter-tools.97f38a.min.js | 2 +- demo/js/matter-demo.matter-wrap.dbda1f.min.js | 2 +- demo/js/matter-demo.pathseg.cf21c2.min.js | 2 +- demo/js/matter-demo.poly-decomp.c3d015.min.js | 2 +- package-lock.json | 4 +- package.json | 2 +- 14 files changed, 4149 insertions(+), 3817 deletions(-) create mode 100644 demo/js/matter-demo.6283b1.min.js delete mode 100644 demo/js/matter-demo.a280d3.min.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 3119f18..f8a2e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,39 @@ +## 0.19.0 (2023-02-16) + +See the release [readme](https://github.com/liabru/matter-js/blob/0.19.0/README.md) for further information. + +* added readme note about vue watchers ([035481c](https://github.com/liabru/matter-js/commit/035481c)) +* added readonly body.deltaTime ([0784a5b](https://github.com/liabru/matter-js/commit/0784a5b)) +* added speed setters to Body.set ([3ff6ff4](https://github.com/liabru/matter-js/commit/3ff6ff4)) +* added support for Matter.Runner and Matter.Render in tests ([7d7bad0](https://github.com/liabru/matter-js/commit/7d7bad0)) +* added updateVelocity argument to Body.setPosition, Body.setAngle, Body.translate, Body.rotate ([db8b73f](https://github.com/liabru/matter-js/commit/db8b73f)) +* changed engine collisionStart event to trigger after resolving and after updating body velocities ([70600a8](https://github.com/liabru/matter-js/commit/70600a8)) +* changed examples to be delta independent ([d7e4f58](https://github.com/liabru/matter-js/commit/d7e4f58)) +* deprecated render.controller property ([04d229e](https://github.com/liabru/matter-js/commit/04d229e)) +* derived velocity from position in setters ([b6de9ed](https://github.com/liabru/matter-js/commit/b6de9ed)) +* fixed issues with engine event.delta ([6f5af77](https://github.com/liabru/matter-js/commit/6f5af77)) +* handle null constraint points in Constraint.pointAWorld and Constraint.pointBWorld ([e414464](https://github.com/liabru/matter-js/commit/e414464)) +* improved Body.applyForce docs ([3a8264c](https://github.com/liabru/matter-js/commit/3a8264c)) +* improved delta factors in resolver and constraint stiffness ([9dc6be7](https://github.com/liabru/matter-js/commit/9dc6be7)) +* improved Matter.Body docs for functions and properties including readonly ([85a9eb2](https://github.com/liabru/matter-js/commit/85a9eb2)) +* improved Matter.Engine docs ([50fc8f2](https://github.com/liabru/matter-js/commit/50fc8f2)) +* improved slingshot example constraint ([c6a1a6d](https://github.com/liabru/matter-js/commit/c6a1a6d)) +* improved delta consistency ([87af8a1](https://github.com/liabru/matter-js/commit/87af8a1)) +* improved Example.newtonsCradle ([b2bd492](https://github.com/liabru/matter-js/commit/b2bd492)) +* removed render element warning ([459425b](https://github.com/liabru/matter-js/commit/459425b)) +* removed unused delta params ([a572968](https://github.com/liabru/matter-js/commit/a572968)) +* updated body docs ([6bb2855](https://github.com/liabru/matter-js/commit/6bb2855)) +* updated body velocity properties after resolving ([d52f7e6](https://github.com/liabru/matter-js/commit/d52f7e6)) +* updated Example.manipulation ([5ddac71](https://github.com/liabru/matter-js/commit/5ddac71)) +* updated Example.ragdoll ([ec38638](https://github.com/liabru/matter-js/commit/ec38638)) +* updated Example.staticFriction and Example.timeScale ([11d5e73](https://github.com/liabru/matter-js/commit/11d5e73)) +* updated Matter.Body docs ([db780c3](https://github.com/liabru/matter-js/commit/db780c3)) +* updated timing improvements ([10a2a07](https://github.com/liabru/matter-js/commit/10a2a07)) +* used Body.getVelocity in Matter.Render ([bf90bdd](https://github.com/liabru/matter-js/commit/bf90bdd)) +* used speed getter in Matter.Sleeping and Matter.Render ([6579dfd](https://github.com/liabru/matter-js/commit/6579dfd)) + + + ## 0.18.0 (2021-12-15) * added test capture sort to improve comparison ([ea3c11b](https://github.com/liabru/matter-js/commit/ea3c11b)) diff --git a/RELEASE.md b/RELEASE.md index 069318a..818faed 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,56 @@ +## ▲.● matter.js `0.19.0` + +Release notes for `0.19.0`. See the release [readme](https://github.com/liabru/matter-js/blob/0.19.0/README.md) for further information. + +### Highlights ✺ + +- Changed `Body.setAngularVelocity` and `Body.setVelocity` to be timestep independent +- Improved similarity of results between different timesteps based on `60hz` as a baseline +- Added timestep independent `Body.setSpeed`, `Body.setAngularSpeed`, `Body.getSpeed`, `Body.getVelocity`, `Body.getAngularVelocity` +- Added optional `updateVelocity` argument to `Body.setPosition`, `Body.setAngle`, `Body.translate`, `Body.rotate` +- Added extended documentation for `Body.applyForce` +- Moved time correction feature from `Engine.update` to be built-in to `Matter.Body` +- Improved [documentation](https://brm.io/matter-js/docs/) pages + +### Changes ✲ + +See the release [compare page](https://github.com/liabru/matter-js/compare/0.18.0...0.19.0) and the [changelog](https://github.com/liabru/matter-js/blob/0.19.0/CHANGELOG.md) for a more detailed list of changes. + +### Migration ⌲ + +See [PR #777](https://github.com/liabru/matter-js/pull/777#issue-487893963) for related changes and notes useful for migration. + +### Comparison ⎄ + +For more information see [comparison method](https://github.com/liabru/matter-js/pull/794). + +```ocaml +Output comparison of 43 examples at 60hz against previous release matter-js@0.18.0 + +Behaviour 100.00% Similarity 100.00% Overlap +0.00% +Performance -0.80% Memory +0.05% Filesize +1.67% 78.97 KB + +airFriction · · avalanche · · ballPool · · bridge · · car · · catapult · · +chains · · circleStack · · cloth · · collisionFiltering · · compositeManipulation · · +compound · · compoundStack · · concave · · constraints · · doublePendulum · · +events · · friction · · gravity · · gyro · · manipulation · · +mixed · · newtonsCradle · · pyramid · · ragdoll · · raycasting · · +remove · · restitution · · rounded · · sensors · · sleeping · ◆ +slingshot · · softBody · · sprites · · stack · · staticFriction · · +stats · · stress · · stress2 · · stress3 · · timescale · · +views · · wreckingBall · · + +where · no change ● extrinsics changed ◆ intrinsics changed + +▶ code -n -d test/__compare__/examples-build.json test/__compare__/examples-dev.json +``` + +### Contributors ♥︎ + +Many thanks to the [contributors](https://github.com/liabru/matter-js/compare/0.18.0...0.19.0) of this release, [past contributors](https://github.com/liabru/matter-js/graphs/contributors) as well those involved in the [community](https://github.com/liabru/matter-js/issues) for your input and support. + +--- + ## ▲.● matter.js `0.18.0` Release notes for `0.18.0`. See the release [readme](https://github.com/liabru/matter-js/blob/0.18.0/README.md) for further information. diff --git a/build/matter.js b/build/matter.js index ae3bc3d..8a80bbb 100644 --- a/build/matter.js +++ b/build/matter.js @@ -1,5 +1,5 @@ /*! - * matter-js 0.18.0 by @liabru + * matter-js 0.19.0 by @liabru * http://brm.io/matter-js/ * License MIT * @@ -118,7 +118,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 21); +/******/ return __webpack_require__(__webpack_require__.s = 20); /******/ }) /************************************************************************/ /******/ ([ @@ -137,6 +137,7 @@ module.exports = Common; (function() { + Common._baseDelta = 1000 / 60; Common._nextId = 0; Common._seed = 0; Common._nowStartTime = +(new Date()); @@ -449,7 +450,8 @@ module.exports = Common; * - 2 = Info * - 3 = Warn * - 4 = Error - * @property Common.logLevel + * @static + * @property logLevel * @type {Number} * @default 1 */ @@ -1579,6 +1581,1452 @@ var Common = __webpack_require__(0); /* 4 */ /***/ (function(module, exports, __webpack_require__) { +/** +* The `Matter.Body` module contains methods for creating and manipulating rigid bodies. +* For creating bodies with common configurations such as rectangles, circles and other polygons see the module `Matter.Bodies`. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). + +* @class Body +*/ + +var Body = {}; + +module.exports = Body; + +var Vertices = __webpack_require__(3); +var Vector = __webpack_require__(2); +var Sleeping = __webpack_require__(7); +var Common = __webpack_require__(0); +var Bounds = __webpack_require__(1); +var Axes = __webpack_require__(11); + +(function() { + + Body._timeCorrection = true; + Body._inertiaScale = 4; + Body._nextCollidingGroupId = 1; + Body._nextNonCollidingGroupId = -1; + Body._nextCategory = 0x0001; + Body._baseDelta = 1000 / 60; + + /** + * Creates a new rigid body model. 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. + * Vertices must be specified in clockwise order. + * See the properties section below for detailed information on what you can pass via the `options` object. + * @method create + * @param {} options + * @return {body} body + */ + Body.create = function(options) { + var defaults = { + id: Common.nextId(), + type: 'body', + label: 'Body', + parts: [], + plugin: {}, + angle: 0, + vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'), + position: { x: 0, y: 0 }, + force: { x: 0, y: 0 }, + torque: 0, + positionImpulse: { x: 0, y: 0 }, + constraintImpulse: { x: 0, y: 0, angle: 0 }, + totalContacts: 0, + speed: 0, + angularSpeed: 0, + velocity: { x: 0, y: 0 }, + angularVelocity: 0, + isSensor: false, + isStatic: false, + isSleeping: false, + motion: 0, + sleepThreshold: 60, + density: 0.001, + restitution: 0, + friction: 0.1, + frictionStatic: 0.5, + frictionAir: 0.01, + collisionFilter: { + category: 0x0001, + mask: 0xFFFFFFFF, + group: 0 + }, + slop: 0.05, + timeScale: 1, + render: { + visible: true, + opacity: 1, + strokeStyle: null, + fillStyle: null, + lineWidth: null, + sprite: { + xScale: 1, + yScale: 1, + xOffset: 0, + yOffset: 0 + } + }, + events: null, + bounds: null, + chamfer: null, + circleRadius: 0, + positionPrev: null, + anglePrev: 0, + parent: null, + axes: null, + area: 0, + mass: 0, + inertia: 0, + deltaTime: 1000 / 60, + _original: null + }; + + var body = Common.extend(defaults, options); + + _initProperties(body, options); + + return body; + }; + + /** + * Returns the next unique group index for which bodies will collide. + * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide. + * See `body.collisionFilter` for more information. + * @method nextGroup + * @param {bool} [isNonColliding=false] + * @return {Number} Unique group index + */ + Body.nextGroup = function(isNonColliding) { + if (isNonColliding) + return Body._nextNonCollidingGroupId--; + + return Body._nextCollidingGroupId++; + }; + + /** + * Returns the next unique category bitfield (starting after the initial default category `0x0001`). + * There are 32 available. See `body.collisionFilter` for more information. + * @method nextCategory + * @return {Number} Unique category bitfield + */ + Body.nextCategory = function() { + Body._nextCategory = Body._nextCategory << 1; + return Body._nextCategory; + }; + + /** + * Initialises body properties. + * @method _initProperties + * @private + * @param {body} body + * @param {} [options] + */ + var _initProperties = function(body, options) { + options = options || {}; + + // init required properties (order is important) + Body.set(body, { + bounds: body.bounds || Bounds.create(body.vertices), + positionPrev: body.positionPrev || Vector.clone(body.position), + anglePrev: body.anglePrev || body.angle, + vertices: body.vertices, + parts: body.parts || [body], + isStatic: body.isStatic, + isSleeping: body.isSleeping, + parent: body.parent || body + }); + + Vertices.rotate(body.vertices, body.angle, body.position); + Axes.rotate(body.axes, body.angle); + Bounds.update(body.bounds, body.vertices, body.velocity); + + // allow options to override the automatically calculated properties + Body.set(body, { + axes: options.axes || body.axes, + area: options.area || body.area, + mass: options.mass || body.mass, + inertia: options.inertia || body.inertia + }); + + // render properties + var defaultFillStyle = (body.isStatic ? '#14151f' : Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1'])), + defaultStrokeStyle = body.isStatic ? '#555' : '#ccc', + defaultLineWidth = body.isStatic && body.render.fillStyle === null ? 1 : 0; + body.render.fillStyle = body.render.fillStyle || defaultFillStyle; + body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle; + body.render.lineWidth = body.render.lineWidth || defaultLineWidth; + body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x); + body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y); + }; + + /** + * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist. + * Prefer to use the actual setter functions in performance critical situations. + * @method set + * @param {body} body + * @param {} settings A property name (or map of properties and values) to set on the body. + * @param {} value The value to set if `settings` is a single property name. + */ + Body.set = function(body, settings, value) { + var property; + + if (typeof settings === 'string') { + property = settings; + settings = {}; + settings[property] = value; + } + + for (property in settings) { + if (!Object.prototype.hasOwnProperty.call(settings, property)) + continue; + + value = settings[property]; + switch (property) { + + case 'isStatic': + Body.setStatic(body, value); + break; + case 'isSleeping': + Sleeping.set(body, value); + break; + case 'mass': + Body.setMass(body, value); + break; + case 'density': + Body.setDensity(body, value); + break; + case 'inertia': + Body.setInertia(body, value); + break; + case 'vertices': + Body.setVertices(body, value); + break; + case 'position': + Body.setPosition(body, value); + break; + case 'angle': + Body.setAngle(body, value); + break; + case 'velocity': + Body.setVelocity(body, value); + break; + case 'angularVelocity': + Body.setAngularVelocity(body, value); + break; + case 'speed': + Body.setSpeed(body, value); + break; + case 'angularSpeed': + Body.setAngularSpeed(body, value); + break; + case 'parts': + Body.setParts(body, value); + break; + case 'centre': + Body.setCentre(body, value); + break; + default: + body[property] = value; + + } + } + }; + + /** + * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity. + * @method setStatic + * @param {body} body + * @param {bool} isStatic + */ + Body.setStatic = function(body, isStatic) { + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + part.isStatic = isStatic; + + if (isStatic) { + part._original = { + restitution: part.restitution, + friction: part.friction, + mass: part.mass, + inertia: part.inertia, + density: part.density, + inverseMass: part.inverseMass, + inverseInertia: part.inverseInertia + }; + + part.restitution = 0; + part.friction = 1; + part.mass = part.inertia = part.density = Infinity; + part.inverseMass = part.inverseInertia = 0; + + part.positionPrev.x = part.position.x; + part.positionPrev.y = part.position.y; + part.anglePrev = part.angle; + part.angularVelocity = 0; + part.speed = 0; + part.angularSpeed = 0; + part.motion = 0; + } else if (part._original) { + part.restitution = part._original.restitution; + part.friction = part._original.friction; + part.mass = part._original.mass; + part.inertia = part._original.inertia; + part.density = part._original.density; + part.inverseMass = part._original.inverseMass; + part.inverseInertia = part._original.inverseInertia; + + part._original = null; + } + } + }; + + /** + * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change. + * @method setMass + * @param {body} body + * @param {number} mass + */ + Body.setMass = function(body, mass) { + var moment = body.inertia / (body.mass / 6); + body.inertia = moment * (mass / 6); + body.inverseInertia = 1 / body.inertia; + + body.mass = mass; + body.inverseMass = 1 / body.mass; + body.density = body.mass / body.area; + }; + + /** + * Sets the density of the body. Mass and inertia are automatically updated to reflect the change. + * @method setDensity + * @param {body} body + * @param {number} density + */ + Body.setDensity = function(body, density) { + Body.setMass(body, density * body.area); + body.density = density; + }; + + /** + * Sets the moment of inertia of the body. This is the second moment of area in two dimensions. + * Inverse inertia is automatically updated to reflect the change. Mass is not changed. + * @method setInertia + * @param {body} body + * @param {number} inertia + */ + Body.setInertia = function(body, inertia) { + body.inertia = inertia; + body.inverseInertia = 1 / body.inertia; + }; + + /** + * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`). + * Vertices will be automatically transformed to be orientated around their centre of mass as the origin. + * They are then automatically translated to world space based on `body.position`. + * + * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array). + * Vertices must form a convex hull. Concave vertices must be decomposed into convex parts. + * + * @method setVertices + * @param {body} body + * @param {vector[]} vertices + */ + Body.setVertices = function(body, vertices) { + // change vertices + if (vertices[0].body === body) { + body.vertices = vertices; + } else { + body.vertices = Vertices.create(vertices, body); + } + + // update properties + body.axes = Axes.fromVertices(body.vertices); + body.area = Vertices.area(body.vertices); + Body.setMass(body, body.density * body.area); + + // orient vertices around the centre of mass at origin (0, 0) + var centre = Vertices.centre(body.vertices); + Vertices.translate(body.vertices, centre, -1); + + // update inertia while vertices are at origin (0, 0) + Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass)); + + // update geometry + Vertices.translate(body.vertices, body.position); + Bounds.update(body.bounds, body.vertices, body.velocity); + }; + + /** + * Sets the parts of the `body` and updates mass, inertia and centroid. + * Each part will have its parent set to `body`. + * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.` + * Note that this method will ensure that the first part in `body.parts` will always be the `body`. + * @method setParts + * @param {body} body + * @param {body[]} parts + * @param {bool} [autoHull=true] + */ + Body.setParts = function(body, parts, autoHull) { + var i; + + // add all the parts, ensuring that the first part is always the parent body + parts = parts.slice(0); + body.parts.length = 0; + body.parts.push(body); + body.parent = body; + + for (i = 0; i < parts.length; i++) { + var part = parts[i]; + if (part !== body) { + part.parent = body; + body.parts.push(part); + } + } + + if (body.parts.length === 1) + return; + + autoHull = typeof autoHull !== 'undefined' ? autoHull : true; + + // find the convex hull of all parts to set on the parent body + if (autoHull) { + var vertices = []; + for (i = 0; i < parts.length; i++) { + vertices = vertices.concat(parts[i].vertices); + } + + Vertices.clockwiseSort(vertices); + + var hull = Vertices.hull(vertices), + hullCentre = Vertices.centre(hull); + + Body.setVertices(body, hull); + Vertices.translate(body.vertices, hullCentre); + } + + // sum the properties of all compound parts of the parent body + var total = Body._totalProperties(body); + + body.area = total.area; + body.parent = body; + body.position.x = total.centre.x; + body.position.y = total.centre.y; + body.positionPrev.x = total.centre.x; + body.positionPrev.y = total.centre.y; + + Body.setMass(body, total.mass); + Body.setInertia(body, total.inertia); + Body.setPosition(body, total.centre); + }; + + /** + * Set the centre of mass of the body. + * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. + * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. + * This is equal to moving `body.position` but not the `body.vertices`. + * Invalid if the `centre` falls outside the body's convex hull. + * @method setCentre + * @param {body} body + * @param {vector} centre + * @param {bool} relative + */ + Body.setCentre = function(body, centre, relative) { + if (!relative) { + body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x); + body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y); + body.position.x = centre.x; + body.position.y = centre.y; + } else { + body.positionPrev.x += centre.x; + body.positionPrev.y += centre.y; + body.position.x += centre.x; + body.position.y += centre.y; + } + }; + + /** + * Sets the position of the body. By default velocity is unchanged. + * If `updateVelocity` is `true` then velocity is inferred from the change in position. + * @method setPosition + * @param {body} body + * @param {vector} position + * @param {boolean} [updateVelocity=false] + */ + Body.setPosition = function(body, position, updateVelocity) { + var delta = Vector.sub(position, body.position); + + if (updateVelocity) { + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + body.velocity.x = delta.x; + body.velocity.y = delta.y; + body.speed = Vector.magnitude(delta); + } else { + body.positionPrev.x += delta.x; + body.positionPrev.y += delta.y; + } + + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + part.position.x += delta.x; + part.position.y += delta.y; + Vertices.translate(part.vertices, delta); + Bounds.update(part.bounds, part.vertices, body.velocity); + } + }; + + /** + * Sets the angle of the body. By default angular velocity is unchanged. + * If `updateVelocity` is `true` then angular velocity is inferred from the change in angle. + * @method setAngle + * @param {body} body + * @param {number} angle + * @param {boolean} [updateVelocity=false] + */ + Body.setAngle = function(body, angle, updateVelocity) { + var delta = angle - body.angle; + + if (updateVelocity) { + body.anglePrev = body.angle; + body.angularVelocity = delta; + body.angularSpeed = Math.abs(delta); + } else { + body.anglePrev += delta; + } + + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + part.angle += delta; + Vertices.rotate(part.vertices, delta, body.position); + Axes.rotate(part.axes, delta); + Bounds.update(part.bounds, part.vertices, body.velocity); + if (i > 0) { + Vector.rotateAbout(part.position, delta, body.position, part.position); + } + } + }; + + /** + * Sets the current linear velocity of the body. + * Affects body speed. + * @method setVelocity + * @param {body} body + * @param {vector} velocity + */ + Body.setVelocity = function(body, velocity) { + var timeScale = body.deltaTime / Body._baseDelta; + body.positionPrev.x = body.position.x - velocity.x * timeScale; + body.positionPrev.y = body.position.y - velocity.y * timeScale; + body.velocity.x = (body.position.x - body.positionPrev.x) / timeScale; + body.velocity.y = (body.position.y - body.positionPrev.y) / timeScale; + body.speed = Vector.magnitude(body.velocity); + }; + + /** + * Gets the current linear velocity of the body. + * @method getVelocity + * @param {body} body + * @return {vector} velocity + */ + Body.getVelocity = function(body) { + var timeScale = Body._baseDelta / body.deltaTime; + + return { + x: (body.position.x - body.positionPrev.x) * timeScale, + y: (body.position.y - body.positionPrev.y) * timeScale + }; + }; + + /** + * Gets the current linear speed of the body. + * Equivalent to the magnitude of its velocity. + * @method getSpeed + * @param {body} body + * @return {number} speed + */ + Body.getSpeed = function(body) { + return Vector.magnitude(Body.getVelocity(body)); + }; + + /** + * Sets the current linear speed of the body. + * Direction is maintained. Affects body velocity. + * @method setSpeed + * @param {body} body + * @param {number} speed + */ + Body.setSpeed = function(body, speed) { + Body.setVelocity(body, Vector.mult(Vector.normalise(Body.getVelocity(body)), speed)); + }; + + /** + * Sets the current rotational velocity of the body. + * Affects body angular speed. + * @method setAngularVelocity + * @param {body} body + * @param {number} velocity + */ + Body.setAngularVelocity = function(body, velocity) { + var timeScale = body.deltaTime / Body._baseDelta; + body.anglePrev = body.angle - velocity * timeScale; + body.angularVelocity = (body.angle - body.anglePrev) / timeScale; + body.angularSpeed = Math.abs(body.angularVelocity); + }; + + /** + * Gets the current rotational velocity of the body. + * @method getAngularVelocity + * @param {body} body + * @return {number} angular velocity + */ + Body.getAngularVelocity = function(body) { + return (body.angle - body.anglePrev) * Body._baseDelta / body.deltaTime; + }; + + /** + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. + * @method getAngularSpeed + * @param {body} body + * @return {number} angular speed + */ + Body.getAngularSpeed = function(body) { + return Math.abs(Body.getAngularVelocity(body)); + }; + + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * @method setAngularSpeed + * @param {body} body + * @param {number} speed + */ + Body.setAngularSpeed = function(body, speed) { + Body.setAngularVelocity(body, Common.sign(Body.getAngularVelocity(body)) * speed); + }; + + /** + * Moves a body by a given vector relative to its current position. By default velocity is unchanged. + * If `updateVelocity` is `true` then velocity is inferred from the change in position. + * @method translate + * @param {body} body + * @param {vector} translation + * @param {boolean} [updateVelocity=false] + */ + Body.translate = function(body, translation, updateVelocity) { + Body.setPosition(body, Vector.add(body.position, translation), updateVelocity); + }; + + /** + * Rotates a body by a given angle relative to its current angle. By default angular velocity is unchanged. + * If `updateVelocity` is `true` then angular velocity is inferred from the change in angle. + * @method rotate + * @param {body} body + * @param {number} rotation + * @param {vector} [point] + * @param {boolean} [updateVelocity=false] + */ + Body.rotate = function(body, rotation, point, updateVelocity) { + if (!point) { + Body.setAngle(body, body.angle + rotation, updateVelocity); + } else { + var cos = Math.cos(rotation), + sin = Math.sin(rotation), + dx = body.position.x - point.x, + dy = body.position.y - point.y; + + Body.setPosition(body, { + x: point.x + (dx * cos - dy * sin), + y: point.y + (dx * sin + dy * cos) + }, updateVelocity); + + Body.setAngle(body, body.angle + rotation, updateVelocity); + } + }; + + /** + * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre). + * @method scale + * @param {body} body + * @param {number} scaleX + * @param {number} scaleY + * @param {vector} [point] + */ + Body.scale = function(body, scaleX, scaleY, point) { + var totalArea = 0, + totalInertia = 0; + + point = point || body.position; + + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + + // scale vertices + Vertices.scale(part.vertices, scaleX, scaleY, point); + + // update properties + part.axes = Axes.fromVertices(part.vertices); + part.area = Vertices.area(part.vertices); + Body.setMass(part, body.density * part.area); + + // update inertia (requires vertices to be at origin) + Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y }); + Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass)); + Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y }); + + if (i > 0) { + totalArea += part.area; + totalInertia += part.inertia; + } + + // scale position + part.position.x = point.x + (part.position.x - point.x) * scaleX; + part.position.y = point.y + (part.position.y - point.y) * scaleY; + + // update bounds + Bounds.update(part.bounds, part.vertices, body.velocity); + } + + // handle parent body + if (body.parts.length > 1) { + body.area = totalArea; + + if (!body.isStatic) { + Body.setMass(body, body.density * totalArea); + Body.setInertia(body, totalInertia); + } + } + + // handle circles + if (body.circleRadius) { + if (scaleX === scaleY) { + body.circleRadius *= scaleX; + } else { + // body is no longer a circle + body.circleRadius = null; + } + } + }; + + /** + * Performs an update by integrating the equations of motion on the `body`. + * This is applied every update by `Matter.Engine` automatically. + * @method update + * @param {body} body + * @param {number} [deltaTime=16.666] + */ + Body.update = function(body, deltaTime) { + deltaTime = (typeof deltaTime !== 'undefined' ? deltaTime : (1000 / 60)) * body.timeScale; + + var deltaTimeSquared = deltaTime * deltaTime, + correction = Body._timeCorrection ? deltaTime / (body.deltaTime || deltaTime) : 1; + + // from the previous step + var frictionAir = 1 - body.frictionAir * (deltaTime / Common._baseDelta), + velocityPrevX = (body.position.x - body.positionPrev.x) * correction, + velocityPrevY = (body.position.y - body.positionPrev.y) * correction; + + // update velocity with Verlet integration + body.velocity.x = (velocityPrevX * frictionAir) + (body.force.x / body.mass) * deltaTimeSquared; + body.velocity.y = (velocityPrevY * frictionAir) + (body.force.y / body.mass) * deltaTimeSquared; + + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + body.position.x += body.velocity.x; + body.position.y += body.velocity.y; + body.deltaTime = deltaTime; + + // update angular velocity with Verlet integration + body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared; + body.anglePrev = body.angle; + body.angle += body.angularVelocity; + + // transform the body geometry + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + + Vertices.translate(part.vertices, body.velocity); + + if (i > 0) { + part.position.x += body.velocity.x; + part.position.y += body.velocity.y; + } + + if (body.angularVelocity !== 0) { + Vertices.rotate(part.vertices, body.angularVelocity, body.position); + Axes.rotate(part.axes, body.angularVelocity); + if (i > 0) { + Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position); + } + } + + Bounds.update(part.bounds, part.vertices, body.velocity); + } + }; + + /** + * Updates properties `body.velocity`, `body.speed`, `body.angularVelocity` and `body.angularSpeed` which are normalised in relation to `Body._baseDelta`. + * @method updateVelocities + * @param {body} body + */ + Body.updateVelocities = function(body) { + var timeScale = Body._baseDelta / body.deltaTime, + bodyVelocity = body.velocity; + + bodyVelocity.x = (body.position.x - body.positionPrev.x) * timeScale; + bodyVelocity.y = (body.position.y - body.positionPrev.y) * timeScale; + body.speed = Math.sqrt((bodyVelocity.x * bodyVelocity.x) + (bodyVelocity.y * bodyVelocity.y)); + + body.angularVelocity = (body.angle - body.anglePrev) * timeScale; + body.angularSpeed = Math.abs(body.angularVelocity); + }; + + /** + * Applies the `force` to the `body` from the force origin `position` in world-space, over a single timestep, including applying any resulting angular torque. + * + * Forces are useful for effects like gravity, wind or rocket thrust, but can be difficult in practice when precise control is needed. In these cases see `Body.setVelocity` and `Body.setPosition` as an alternative. + * + * The force from this function is only applied once for the duration of a single timestep, in other words the duration depends directly on the current engine update `delta` and the rate of calls to this function. + * + * Therefore to account for time, you should apply the force constantly over as many engine updates as equivalent to the intended duration. + * + * If all or part of the force duration is some fraction of a timestep, first multiply the force by `duration / timestep`. + * + * The force origin `position` in world-space must also be specified. Passing `body.position` will result in zero angular effect as the force origin would be at the centre of mass. + * + * The `body` will take time to accelerate under a force, the resulting effect depends on duration of the force, the body mass and other forces on the body including friction combined. + * @method applyForce + * @param {body} body + * @param {vector} position The force origin in world-space. Pass `body.position` to avoid angular torque. + * @param {vector} force + */ + Body.applyForce = function(body, position, force) { + var offset = { x: position.x - body.position.x, y: position.y - body.position.y }; + body.force.x += force.x; + body.force.y += force.y; + body.torque += offset.x * force.y - offset.y * force.x; + }; + + /** + * Returns the sums of the properties of all compound parts of the parent body. + * @method _totalProperties + * @private + * @param {body} body + * @return {} + */ + Body._totalProperties = function(body) { + // from equations at: + // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory + // http://output.to/sideway/default.asp?qno=121100087 + + var properties = { + mass: 0, + area: 0, + inertia: 0, + centre: { x: 0, y: 0 } + }; + + // sum the properties of all compound parts of the parent body + for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) { + var part = body.parts[i], + mass = part.mass !== Infinity ? part.mass : 1; + + properties.mass += mass; + properties.area += part.area; + properties.inertia += part.inertia; + properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass)); + } + + properties.centre = Vector.div(properties.centre, properties.mass); + + return properties; + }; + + /* + * + * Events Documentation + * + */ + + /** + * Fired when a body starts sleeping (where `this` is the body). + * + * @event sleepStart + * @this {body} The body that has started sleeping + * @param {} event An event object + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when a body ends sleeping (where `this` is the body). + * + * @event sleepEnd + * @this {body} The body that has ended sleeping + * @param {} event An event object + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /* + * + * Properties Documentation + * + */ + + /** + * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`. + * + * @property id + * @type number + */ + + /** + * _Read only_. Set by `Body.create`. + * + * A `String` denoting the type of object. + * + * @readOnly + * @property type + * @type string + * @default "body" + */ + + /** + * An arbitrary `String` name to help the user identify and manage bodies. + * + * @property label + * @type string + * @default "Body" + */ + + /** + * _Read only_. Use `Body.setParts` to set. + * + * An array of bodies that make up this body. + * The first body in the array must always be a self reference to the current body instance. + * All bodies in the `parts` array together form a single rigid compound body. + * Parts are allowed to overlap, have gaps or holes or even form concave bodies. + * Parts themselves should never be added to a `World`, only the parent body should be. + * Use `Body.setParts` when setting parts to ensure correct updates of all properties. + * + * @readOnly + * @property parts + * @type body[] + */ + + /** + * An object reserved for storing plugin-specific properties. + * + * @property plugin + * @type {} + */ + + /** + * _Read only_. Updated by `Body.setParts`. + * + * A reference to the body that this is a part of. See `body.parts`. + * This is a self reference if the body is not a part of another body. + * + * @readOnly + * @property parent + * @type body + */ + + /** + * A `Number` specifying the angle of the body, in radians. + * + * @property angle + * @type number + * @default 0 + */ + + /** + * _Read only_. Use `Body.setVertices` or `Body.setParts` to set. See also `Bodies.fromVertices`. + * + * An array of `Vector` objects that specify the convex hull of the rigid body. + * These should be provided about the origin `(0, 0)`. E.g. + * + * `[{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]` + * + * Vertices must always be convex, in clockwise order and must not contain any duplicate points. + * + * Concave vertices should be decomposed into convex `parts`, see `Bodies.fromVertices` and `Body.setParts`. + * + * When set the vertices are translated such that `body.position` is at the centre of mass. + * Many other body properties are automatically calculated from these vertices when set including `density`, `area` and `inertia`. + * + * The module `Matter.Vertices` contains useful methods for working with vertices. + * + * @readOnly + * @property vertices + * @type vector[] + */ + + /** + * _Read only_. Use `Body.setPosition` to set. + * + * A `Vector` that specifies the current world-space position of the body. + * + * @readOnly + * @property position + * @type vector + * @default { x: 0, y: 0 } + */ + + /** + * A `Vector` that accumulates the total force applied to the body for a single update. + * Force is zeroed after every `Engine.update`, so constant forces should be applied for every update they are needed. See also `Body.applyForce`. + * + * @property force + * @type vector + * @default { x: 0, y: 0 } + */ + + /** + * A `Number` that accumulates the total torque (turning force) applied to the body for a single update. See also `Body.applyForce`. + * Torque is zeroed after every `Engine.update`, so constant torques should be applied for every update they are needed. + * + * Torques result in angular acceleration on every update, which depends on body inertia and the engine update delta. + * + * @property torque + * @type number + * @default 0 + */ + + /** + * _Read only_. Use `Body.setSpeed` to set. + * + * See `Body.getSpeed` for details. + * + * Equivalent to the magnitude of `body.velocity` (always positive). + * + * @readOnly + * @property speed + * @type number + * @default 0 + */ + + /** + * _Read only_. Use `Body.setVelocity` to set. + * + * See `Body.getVelocity` for details. + * + * Equivalent to the magnitude of `body.angularVelocity` (always positive). + * + * @readOnly + * @property velocity + * @type vector + * @default { x: 0, y: 0 } + */ + + /** + * _Read only_. Use `Body.setAngularSpeed` to set. + * + * See `Body.getAngularSpeed` for details. + * + * + * @readOnly + * @property angularSpeed + * @type number + * @default 0 + */ + + /** + * _Read only_. Use `Body.setAngularVelocity` to set. + * + * See `Body.getAngularVelocity` for details. + * + * + * @readOnly + * @property angularVelocity + * @type number + * @default 0 + */ + + /** + * _Read only_. Use `Body.setStatic` to set. + * + * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed. + * + * @readOnly + * @property isStatic + * @type boolean + * @default false + */ + + /** + * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically. + * + * @property isSensor + * @type boolean + * @default false + */ + + /** + * _Read only_. Use `Sleeping.set` to set. + * + * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken. + * + * @readOnly + * @property isSleeping + * @type boolean + * @default false + */ + + /** + * _Read only_. Calculated during engine update only when sleeping is enabled. + * + * A `Number` that loosely measures the amount of movement a body currently has. + * + * Derived from `body.speed^2 + body.angularSpeed^2`. See `Sleeping.update`. + * + * @readOnly + * @property motion + * @type number + * @default 0 + */ + + /** + * A `Number` that defines the length of time during which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine). + * + * @property sleepThreshold + * @type number + * @default 60 + */ + + /** + * _Read only_. Use `Body.setDensity` to set. + * + * A `Number` that defines the density of the body (mass per unit area). + * + * Mass will also be updated when set. + * + * @readOnly + * @property density + * @type number + * @default 0.001 + */ + + /** + * _Read only_. Use `Body.setMass` to set. + * + * A `Number` that defines the mass of the body. + * + * Density will also be updated when set. + * + * @readOnly + * @property mass + * @type number + */ + + /** + * _Read only_. Use `Body.setMass` to set. + * + * A `Number` that defines the inverse mass of the body (`1 / mass`). + * + * @readOnly + * @property inverseMass + * @type number + */ + + /** + * _Read only_. Automatically calculated when vertices, mass or density are set or set through `Body.setInertia`. + * + * A `Number` that defines the moment of inertia of the body. This is the second moment of area in two dimensions. + * + * Can be manually set to `Infinity` to prevent rotation of the body. See `Body.setInertia`. + * + * @readOnly + * @property inertia + * @type number + */ + + /** + * _Read only_. Automatically calculated when vertices, mass or density are set or calculated by `Body.setInertia`. + * + * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`). + * + * @readOnly + * @property inverseInertia + * @type number + */ + + /** + * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`. + * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. + * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy. + * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula: + * + * `Math.max(bodyA.restitution, bodyB.restitution)` + * + * @property restitution + * @type number + * @default 0 + */ + + /** + * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`. + * A value of `0` means that the body may slide indefinitely. + * A value of `1` means the body may come to a stop almost instantly after a force is applied. + * + * The effects of the value may be non-linear. + * High values may be unstable depending on the body. + * The engine uses a Coulomb friction model including static and kinetic friction. + * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula: + * + * `Math.min(bodyA.friction, bodyB.friction)` + * + * @property friction + * @type number + * @default 0.1 + */ + + /** + * A `Number` that defines the static friction of the body (in the Coulomb friction model). + * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used. + * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary. + * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction. + * + * @property frictionStatic + * @type number + * @default 0.5 + */ + + /** + * A `Number` that defines the air friction of the body (air resistance). + * A value of `0` means the body will never slow as it moves through space. + * The higher the value, the faster a body slows when moving through space. + * The effects of the value are non-linear. + * + * @property frictionAir + * @type number + * @default 0.01 + */ + + /** + * An `Object` that specifies the collision filtering properties of this body. + * + * Collisions between two bodies will obey the following rules: + * - If the two bodies have the same non-zero value of `collisionFilter.group`, + * they will always collide if the value is positive, and they will never collide + * if the value is negative. + * - If the two bodies have different values of `collisionFilter.group` or if one + * (or both) of the bodies has a value of 0, then the category/mask rules apply as follows: + * + * Each body belongs to a collision category, given by `collisionFilter.category`. This + * value is used as a bit field and the category should have only one bit set, meaning that + * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32 + * different collision categories available. + * + * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies + * the categories it collides with (the value is the bitwise AND value of all these categories). + * + * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's + * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0` + * are both true. + * + * @property collisionFilter + * @type object + */ + + /** + * An Integer `Number`, that specifies the collision group this body belongs to. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter.group + * @type object + * @default 0 + */ + + /** + * A bit field that specifies the collision category this body belongs to. + * The category value should have only one bit set, for example `0x0001`. + * This means there are up to 32 unique collision categories available. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter.category + * @type object + * @default 1 + */ + + /** + * A bit mask that specifies the collision categories this body may collide with. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter.mask + * @type object + * @default -1 + */ + + /** + * A `Number` that specifies a thin boundary around the body where it is allowed to slightly sink into other bodies. + * + * This is required for proper collision response, including friction and restitution effects. + * + * The default should generally suffice in most cases. You may need to decrease this value for very small bodies that are nearing the default value in scale. + * + * @property slop + * @type number + * @default 0.05 + */ + + /** + * A `Number` that specifies per-body time scaling. + * + * @property timeScale + * @type number + * @default 1 + */ + + /** + * _Read only_. Updated during engine update. + * + * A `Number` that records the last delta time value used to update this body. + * Used to calculate speed and velocity. + * + * @readOnly + * @property deltaTime + * @type number + * @default 1000 / 60 + */ + + /** + * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. + * + * @property render + * @type object + */ + + /** + * A flag that indicates if the body should be rendered. + * + * @property render.visible + * @type boolean + * @default true + */ + + /** + * Sets the opacity to use when rendering. + * + * @property render.opacity + * @type number + * @default 1 + */ + + /** + * An `Object` that defines the sprite properties to use when rendering, if any. + * + * @property render.sprite + * @type object + */ + + /** + * An `String` that defines the path to the image to use as the sprite texture, if any. + * + * @property render.sprite.texture + * @type string + */ + + /** + * A `Number` that defines the scaling in the x-axis for the sprite, if any. + * + * @property render.sprite.xScale + * @type number + * @default 1 + */ + + /** + * A `Number` that defines the scaling in the y-axis for the sprite, if any. + * + * @property render.sprite.yScale + * @type number + * @default 1 + */ + + /** + * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width). + * + * @property render.sprite.xOffset + * @type number + * @default 0 + */ + + /** + * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height). + * + * @property render.sprite.yOffset + * @type number + * @default 0 + */ + + /** + * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined). + * A value of `0` means no outline will be rendered. + * + * @property render.lineWidth + * @type number + * @default 0 + */ + + /** + * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined). + * It is the same as when using a canvas, so it accepts CSS style property values. + * + * @property render.fillStyle + * @type string + * @default a random colour + */ + + /** + * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined). + * It is the same as when using a canvas, so it accepts CSS style property values. + * + * @property render.strokeStyle + * @type string + * @default a random colour + */ + + /** + * _Read only_. Calculated automatically when vertices are set. + * + * An array of unique axis vectors (edge normals) used for collision detection. + * These are automatically calculated when vertices are set. + * They are constantly updated by `Body.update` during the simulation. + * + * @readOnly + * @property axes + * @type vector[] + */ + + /** + * _Read only_. Calculated automatically when vertices are set. + * + * A `Number` that measures the area of the body's convex hull. + * + * @readOnly + * @property area + * @type string + * @default + */ + + /** + * A `Bounds` object that defines the AABB region for the body. + * It is automatically calculated when vertices are set and constantly updated by `Body.update` during simulation. + * + * @property bounds + * @type bounds + */ + +})(); + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + /** * The `Matter.Events` module contains methods to fire and listen to events on other objects. * @@ -1694,7 +3142,7 @@ var Common = __webpack_require__(0); /***/ }), -/* 5 */ +/* 6 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -1714,10 +3162,10 @@ var Composite = {}; module.exports = Composite; -var Events = __webpack_require__(4); +var Events = __webpack_require__(5); var Common = __webpack_require__(0); var Bounds = __webpack_require__(1); -var Body = __webpack_require__(6); +var Body = __webpack_require__(4); (function() { @@ -2421,1247 +3869,6 @@ var Body = __webpack_require__(6); })(); -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Body` module contains methods for creating and manipulating body models. -* A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`. -* Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). - -* @class Body -*/ - -var Body = {}; - -module.exports = Body; - -var Vertices = __webpack_require__(3); -var Vector = __webpack_require__(2); -var Sleeping = __webpack_require__(7); -var Render = __webpack_require__(16); -var Common = __webpack_require__(0); -var Bounds = __webpack_require__(1); -var Axes = __webpack_require__(11); - -(function() { - - Body._inertiaScale = 4; - Body._nextCollidingGroupId = 1; - Body._nextNonCollidingGroupId = -1; - Body._nextCategory = 0x0001; - - /** - * Creates a new rigid body model. 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. - * Vertices must be specified in clockwise order. - * See the properties section below for detailed information on what you can pass via the `options` object. - * @method create - * @param {} options - * @return {body} body - */ - Body.create = function(options) { - var defaults = { - id: Common.nextId(), - type: 'body', - label: 'Body', - parts: [], - plugin: {}, - angle: 0, - vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'), - position: { x: 0, y: 0 }, - force: { x: 0, y: 0 }, - torque: 0, - positionImpulse: { x: 0, y: 0 }, - constraintImpulse: { x: 0, y: 0, angle: 0 }, - totalContacts: 0, - speed: 0, - angularSpeed: 0, - velocity: { x: 0, y: 0 }, - angularVelocity: 0, - isSensor: false, - isStatic: false, - isSleeping: false, - motion: 0, - sleepThreshold: 60, - density: 0.001, - restitution: 0, - friction: 0.1, - frictionStatic: 0.5, - frictionAir: 0.01, - collisionFilter: { - category: 0x0001, - mask: 0xFFFFFFFF, - group: 0 - }, - slop: 0.05, - timeScale: 1, - render: { - visible: true, - opacity: 1, - strokeStyle: null, - fillStyle: null, - lineWidth: null, - sprite: { - xScale: 1, - yScale: 1, - xOffset: 0, - yOffset: 0 - } - }, - events: null, - bounds: null, - chamfer: null, - circleRadius: 0, - positionPrev: null, - anglePrev: 0, - parent: null, - axes: null, - area: 0, - mass: 0, - inertia: 0, - _original: null - }; - - var body = Common.extend(defaults, options); - - _initProperties(body, options); - - return body; - }; - - /** - * Returns the next unique group index for which bodies will collide. - * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide. - * See `body.collisionFilter` for more information. - * @method nextGroup - * @param {bool} [isNonColliding=false] - * @return {Number} Unique group index - */ - Body.nextGroup = function(isNonColliding) { - if (isNonColliding) - return Body._nextNonCollidingGroupId--; - - return Body._nextCollidingGroupId++; - }; - - /** - * Returns the next unique category bitfield (starting after the initial default category `0x0001`). - * There are 32 available. See `body.collisionFilter` for more information. - * @method nextCategory - * @return {Number} Unique category bitfield - */ - Body.nextCategory = function() { - Body._nextCategory = Body._nextCategory << 1; - return Body._nextCategory; - }; - - /** - * Initialises body properties. - * @method _initProperties - * @private - * @param {body} body - * @param {} [options] - */ - var _initProperties = function(body, options) { - options = options || {}; - - // init required properties (order is important) - Body.set(body, { - bounds: body.bounds || Bounds.create(body.vertices), - positionPrev: body.positionPrev || Vector.clone(body.position), - anglePrev: body.anglePrev || body.angle, - vertices: body.vertices, - parts: body.parts || [body], - isStatic: body.isStatic, - isSleeping: body.isSleeping, - parent: body.parent || body - }); - - Vertices.rotate(body.vertices, body.angle, body.position); - Axes.rotate(body.axes, body.angle); - Bounds.update(body.bounds, body.vertices, body.velocity); - - // allow options to override the automatically calculated properties - Body.set(body, { - axes: options.axes || body.axes, - area: options.area || body.area, - mass: options.mass || body.mass, - inertia: options.inertia || body.inertia - }); - - // render properties - var defaultFillStyle = (body.isStatic ? '#14151f' : Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1'])), - defaultStrokeStyle = body.isStatic ? '#555' : '#ccc', - defaultLineWidth = body.isStatic && body.render.fillStyle === null ? 1 : 0; - body.render.fillStyle = body.render.fillStyle || defaultFillStyle; - body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle; - body.render.lineWidth = body.render.lineWidth || defaultLineWidth; - body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x); - body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y); - }; - - /** - * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist. - * Prefer to use the actual setter functions in performance critical situations. - * @method set - * @param {body} body - * @param {} settings A property name (or map of properties and values) to set on the body. - * @param {} value The value to set if `settings` is a single property name. - */ - Body.set = function(body, settings, value) { - var property; - - if (typeof settings === 'string') { - property = settings; - settings = {}; - settings[property] = value; - } - - for (property in settings) { - if (!Object.prototype.hasOwnProperty.call(settings, property)) - continue; - - value = settings[property]; - switch (property) { - - case 'isStatic': - Body.setStatic(body, value); - break; - case 'isSleeping': - Sleeping.set(body, value); - break; - case 'mass': - Body.setMass(body, value); - break; - case 'density': - Body.setDensity(body, value); - break; - case 'inertia': - Body.setInertia(body, value); - break; - case 'vertices': - Body.setVertices(body, value); - break; - case 'position': - Body.setPosition(body, value); - break; - case 'angle': - Body.setAngle(body, value); - break; - case 'velocity': - Body.setVelocity(body, value); - break; - case 'angularVelocity': - Body.setAngularVelocity(body, value); - break; - case 'parts': - Body.setParts(body, value); - break; - case 'centre': - Body.setCentre(body, value); - break; - default: - body[property] = value; - - } - } - }; - - /** - * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity. - * @method setStatic - * @param {body} body - * @param {bool} isStatic - */ - Body.setStatic = function(body, isStatic) { - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.isStatic = isStatic; - - if (isStatic) { - part._original = { - restitution: part.restitution, - friction: part.friction, - mass: part.mass, - inertia: part.inertia, - density: part.density, - inverseMass: part.inverseMass, - inverseInertia: part.inverseInertia - }; - - part.restitution = 0; - part.friction = 1; - part.mass = part.inertia = part.density = Infinity; - part.inverseMass = part.inverseInertia = 0; - - part.positionPrev.x = part.position.x; - part.positionPrev.y = part.position.y; - part.anglePrev = part.angle; - part.angularVelocity = 0; - part.speed = 0; - part.angularSpeed = 0; - part.motion = 0; - } else if (part._original) { - part.restitution = part._original.restitution; - part.friction = part._original.friction; - part.mass = part._original.mass; - part.inertia = part._original.inertia; - part.density = part._original.density; - part.inverseMass = part._original.inverseMass; - part.inverseInertia = part._original.inverseInertia; - - part._original = null; - } - } - }; - - /** - * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change. - * @method setMass - * @param {body} body - * @param {number} mass - */ - Body.setMass = function(body, mass) { - var moment = body.inertia / (body.mass / 6); - body.inertia = moment * (mass / 6); - body.inverseInertia = 1 / body.inertia; - - body.mass = mass; - body.inverseMass = 1 / body.mass; - body.density = body.mass / body.area; - }; - - /** - * Sets the density of the body. Mass and inertia are automatically updated to reflect the change. - * @method setDensity - * @param {body} body - * @param {number} density - */ - Body.setDensity = function(body, density) { - Body.setMass(body, density * body.area); - body.density = density; - }; - - /** - * Sets the moment of inertia (i.e. second moment of area) of the body. - * Inverse inertia is automatically updated to reflect the change. Mass is not changed. - * @method setInertia - * @param {body} body - * @param {number} inertia - */ - Body.setInertia = function(body, inertia) { - body.inertia = inertia; - body.inverseInertia = 1 / body.inertia; - }; - - /** - * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`). - * Vertices will be automatically transformed to be orientated around their centre of mass as the origin. - * They are then automatically translated to world space based on `body.position`. - * - * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array). - * Vertices must form a convex hull, concave hulls are not supported. - * - * @method setVertices - * @param {body} body - * @param {vector[]} vertices - */ - Body.setVertices = function(body, vertices) { - // change vertices - if (vertices[0].body === body) { - body.vertices = vertices; - } else { - body.vertices = Vertices.create(vertices, body); - } - - // update properties - body.axes = Axes.fromVertices(body.vertices); - body.area = Vertices.area(body.vertices); - Body.setMass(body, body.density * body.area); - - // orient vertices around the centre of mass at origin (0, 0) - var centre = Vertices.centre(body.vertices); - Vertices.translate(body.vertices, centre, -1); - - // update inertia while vertices are at origin (0, 0) - Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass)); - - // update geometry - Vertices.translate(body.vertices, body.position); - Bounds.update(body.bounds, body.vertices, body.velocity); - }; - - /** - * Sets the parts of the `body` and updates mass, inertia and centroid. - * Each part will have its parent set to `body`. - * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.` - * Note that this method will ensure that the first part in `body.parts` will always be the `body`. - * @method setParts - * @param {body} body - * @param [body] parts - * @param {bool} [autoHull=true] - */ - Body.setParts = function(body, parts, autoHull) { - var i; - - // add all the parts, ensuring that the first part is always the parent body - parts = parts.slice(0); - body.parts.length = 0; - body.parts.push(body); - body.parent = body; - - for (i = 0; i < parts.length; i++) { - var part = parts[i]; - if (part !== body) { - part.parent = body; - body.parts.push(part); - } - } - - if (body.parts.length === 1) - return; - - autoHull = typeof autoHull !== 'undefined' ? autoHull : true; - - // find the convex hull of all parts to set on the parent body - if (autoHull) { - var vertices = []; - for (i = 0; i < parts.length; i++) { - vertices = vertices.concat(parts[i].vertices); - } - - Vertices.clockwiseSort(vertices); - - var hull = Vertices.hull(vertices), - hullCentre = Vertices.centre(hull); - - Body.setVertices(body, hull); - Vertices.translate(body.vertices, hullCentre); - } - - // sum the properties of all compound parts of the parent body - var total = Body._totalProperties(body); - - body.area = total.area; - body.parent = body; - body.position.x = total.centre.x; - body.position.y = total.centre.y; - body.positionPrev.x = total.centre.x; - body.positionPrev.y = total.centre.y; - - Body.setMass(body, total.mass); - Body.setInertia(body, total.inertia); - Body.setPosition(body, total.centre); - }; - - /** - * Set the centre of mass of the body. - * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. - * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. - * This is equal to moving `body.position` but not the `body.vertices`. - * Invalid if the `centre` falls outside the body's convex hull. - * @method setCentre - * @param {body} body - * @param {vector} centre - * @param {bool} relative - */ - Body.setCentre = function(body, centre, relative) { - if (!relative) { - body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x); - body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y); - body.position.x = centre.x; - body.position.y = centre.y; - } else { - body.positionPrev.x += centre.x; - body.positionPrev.y += centre.y; - body.position.x += centre.x; - body.position.y += centre.y; - } - }; - - /** - * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. - * @method setPosition - * @param {body} body - * @param {vector} position - */ - Body.setPosition = function(body, position) { - var delta = Vector.sub(position, body.position); - body.positionPrev.x += delta.x; - body.positionPrev.y += delta.y; - - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.position.x += delta.x; - part.position.y += delta.y; - Vertices.translate(part.vertices, delta); - Bounds.update(part.bounds, part.vertices, body.velocity); - } - }; - - /** - * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. - * @method setAngle - * @param {body} body - * @param {number} angle - */ - Body.setAngle = function(body, angle) { - var delta = angle - body.angle; - body.anglePrev += delta; - - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.angle += delta; - Vertices.rotate(part.vertices, delta, body.position); - Axes.rotate(part.axes, delta); - Bounds.update(part.bounds, part.vertices, body.velocity); - if (i > 0) { - Vector.rotateAbout(part.position, delta, body.position, part.position); - } - } - }; - - /** - * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. - * @method setVelocity - * @param {body} body - * @param {vector} velocity - */ - Body.setVelocity = function(body, velocity) { - body.positionPrev.x = body.position.x - velocity.x; - body.positionPrev.y = body.position.y - velocity.y; - body.velocity.x = velocity.x; - body.velocity.y = velocity.y; - body.speed = Vector.magnitude(body.velocity); - }; - - /** - * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. - * @method setAngularVelocity - * @param {body} body - * @param {number} velocity - */ - Body.setAngularVelocity = function(body, velocity) { - body.anglePrev = body.angle - velocity; - body.angularVelocity = velocity; - body.angularSpeed = Math.abs(body.angularVelocity); - }; - - /** - * Moves a body by a given vector relative to its current position, without imparting any velocity. - * @method translate - * @param {body} body - * @param {vector} translation - */ - Body.translate = function(body, translation) { - Body.setPosition(body, Vector.add(body.position, translation)); - }; - - /** - * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity. - * @method rotate - * @param {body} body - * @param {number} rotation - * @param {vector} [point] - */ - Body.rotate = function(body, rotation, point) { - if (!point) { - Body.setAngle(body, body.angle + rotation); - } else { - var cos = Math.cos(rotation), - sin = Math.sin(rotation), - dx = body.position.x - point.x, - dy = body.position.y - point.y; - - Body.setPosition(body, { - x: point.x + (dx * cos - dy * sin), - y: point.y + (dx * sin + dy * cos) - }); - - Body.setAngle(body, body.angle + rotation); - } - }; - - /** - * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre). - * @method scale - * @param {body} body - * @param {number} scaleX - * @param {number} scaleY - * @param {vector} [point] - */ - Body.scale = function(body, scaleX, scaleY, point) { - var totalArea = 0, - totalInertia = 0; - - point = point || body.position; - - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - - // scale vertices - Vertices.scale(part.vertices, scaleX, scaleY, point); - - // update properties - part.axes = Axes.fromVertices(part.vertices); - part.area = Vertices.area(part.vertices); - Body.setMass(part, body.density * part.area); - - // update inertia (requires vertices to be at origin) - Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y }); - Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass)); - Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y }); - - if (i > 0) { - totalArea += part.area; - totalInertia += part.inertia; - } - - // scale position - part.position.x = point.x + (part.position.x - point.x) * scaleX; - part.position.y = point.y + (part.position.y - point.y) * scaleY; - - // update bounds - Bounds.update(part.bounds, part.vertices, body.velocity); - } - - // handle parent body - if (body.parts.length > 1) { - body.area = totalArea; - - if (!body.isStatic) { - Body.setMass(body, body.density * totalArea); - Body.setInertia(body, totalInertia); - } - } - - // handle circles - if (body.circleRadius) { - if (scaleX === scaleY) { - body.circleRadius *= scaleX; - } else { - // body is no longer a circle - body.circleRadius = null; - } - } - }; - - /** - * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. - * @method update - * @param {body} body - * @param {number} deltaTime - * @param {number} timeScale - * @param {number} correction - */ - Body.update = function(body, deltaTime, timeScale, correction) { - var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2); - - // from the previous step - var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale, - velocityPrevX = body.position.x - body.positionPrev.x, - velocityPrevY = body.position.y - body.positionPrev.y; - - // update velocity with Verlet integration - body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared; - body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared; - - body.positionPrev.x = body.position.x; - body.positionPrev.y = body.position.y; - body.position.x += body.velocity.x; - body.position.y += body.velocity.y; - - // update angular velocity with Verlet integration - body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared; - body.anglePrev = body.angle; - body.angle += body.angularVelocity; - - // track speed and acceleration - body.speed = Vector.magnitude(body.velocity); - body.angularSpeed = Math.abs(body.angularVelocity); - - // transform the body geometry - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - - Vertices.translate(part.vertices, body.velocity); - - if (i > 0) { - part.position.x += body.velocity.x; - part.position.y += body.velocity.y; - } - - if (body.angularVelocity !== 0) { - Vertices.rotate(part.vertices, body.angularVelocity, body.position); - Axes.rotate(part.axes, body.angularVelocity); - if (i > 0) { - Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position); - } - } - - Bounds.update(part.bounds, part.vertices, body.velocity); - } - }; - - /** - * Applies a force to a body from a given world-space position, including resulting torque. - * @method applyForce - * @param {body} body - * @param {vector} position - * @param {vector} force - */ - Body.applyForce = function(body, position, force) { - body.force.x += force.x; - body.force.y += force.y; - var offset = { x: position.x - body.position.x, y: position.y - body.position.y }; - body.torque += offset.x * force.y - offset.y * force.x; - }; - - /** - * Returns the sums of the properties of all compound parts of the parent body. - * @method _totalProperties - * @private - * @param {body} body - * @return {} - */ - Body._totalProperties = function(body) { - // from equations at: - // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory - // http://output.to/sideway/default.asp?qno=121100087 - - var properties = { - mass: 0, - area: 0, - inertia: 0, - centre: { x: 0, y: 0 } - }; - - // sum the properties of all compound parts of the parent body - for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) { - var part = body.parts[i], - mass = part.mass !== Infinity ? part.mass : 1; - - properties.mass += mass; - properties.area += part.area; - properties.inertia += part.inertia; - properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass)); - } - - properties.centre = Vector.div(properties.centre, properties.mass); - - return properties; - }; - - /* - * - * Events Documentation - * - */ - - /** - * Fired when a body starts sleeping (where `this` is the body). - * - * @event sleepStart - * @this {body} The body that has started sleeping - * @param {} event An event object - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when a body ends sleeping (where `this` is the body). - * - * @event sleepEnd - * @this {body} The body that has ended sleeping - * @param {} event An event object - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /* - * - * Properties Documentation - * - */ - - /** - * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`. - * - * @property id - * @type number - */ - - /** - * A `String` denoting the type of object. - * - * @property type - * @type string - * @default "body" - * @readOnly - */ - - /** - * An arbitrary `String` name to help the user identify and manage bodies. - * - * @property label - * @type string - * @default "Body" - */ - - /** - * An array of bodies that make up this body. - * The first body in the array must always be a self reference to the current body instance. - * All bodies in the `parts` array together form a single rigid compound body. - * Parts are allowed to overlap, have gaps or holes or even form concave bodies. - * Parts themselves should never be added to a `World`, only the parent body should be. - * Use `Body.setParts` when setting parts to ensure correct updates of all properties. - * - * @property parts - * @type body[] - */ - - /** - * An object reserved for storing plugin-specific properties. - * - * @property plugin - * @type {} - */ - - /** - * A self reference if the body is _not_ a part of another body. - * Otherwise this is a reference to the body that this is a part of. - * See `body.parts`. - * - * @property parent - * @type body - */ - - /** - * A `Number` specifying the angle of the body, in radians. - * - * @property angle - * @type number - * @default 0 - */ - - /** - * An array of `Vector` objects that specify the convex hull of the rigid body. - * These should be provided about the origin `(0, 0)`. E.g. - * - * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] - * - * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation). - * The `Vector` objects are also augmented with additional properties required for efficient collision detection. - * - * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`). - * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices. - * - * @property vertices - * @type vector[] - */ - - /** - * A `Vector` that specifies the current world-space position of the body. - * - * @property position - * @type vector - * @default { x: 0, y: 0 } - */ - - /** - * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`. - * - * @property force - * @type vector - * @default { x: 0, y: 0 } - */ - - /** - * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`. - * - * @property torque - * @type number - * @default 0 - */ - - /** - * A `Number` that _measures_ the current speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.velocity`). - * - * @readOnly - * @property speed - * @type number - * @default 0 - */ - - /** - * A `Number` that _measures_ the current angular speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.angularVelocity`). - * - * @readOnly - * @property angularSpeed - * @type number - * @default 0 - */ - - /** - * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's velocity directly, you should either apply a force or simply change the body's `position` (as the engine uses position-Verlet integration). - * - * @readOnly - * @property velocity - * @type vector - * @default { x: 0, y: 0 } - */ - - /** - * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's angular velocity directly, you should apply a torque or simply change the body's `angle` (as the engine uses position-Verlet integration). - * - * @readOnly - * @property angularVelocity - * @type number - * @default 0 - */ - - /** - * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed. - * If you need to set a body as static after its creation, you should use `Body.setStatic` as this requires more than just setting this flag. - * - * @property isStatic - * @type boolean - * @default false - */ - - /** - * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically. - * - * @property isSensor - * @type boolean - * @default false - */ - - /** - * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken. - * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag. - * - * @property isSleeping - * @type boolean - * @default false - */ - - /** - * A `Number` that _measures_ the amount of movement a body currently has (a combination of `speed` and `angularSpeed`). It is read-only and always positive. - * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest. - * - * @readOnly - * @property motion - * @type number - * @default 0 - */ - - /** - * A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine). - * - * @property sleepThreshold - * @type number - * @default 60 - */ - - /** - * A `Number` that defines the density of the body, that is its mass per unit area. - * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object. - * This is generally preferable to simply setting mass and allows for more intuitive definition of materials (e.g. rock has a higher density than wood). - * - * @property density - * @type number - * @default 0.001 - */ - - /** - * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead. - * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`). - * - * @property mass - * @type number - */ - - /** - * A `Number` that defines the inverse mass of the body (`1 / mass`). - * If you modify this value, you must also modify the `body.mass` property. - * - * @property inverseMass - * @type number - */ - - /** - * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body. - * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`. - * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`). - * - * @property inertia - * @type number - */ - - /** - * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`). - * If you modify this value, you must also modify the `body.inertia` property. - * - * @property inverseInertia - * @type number - */ - - /** - * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`. - * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. - * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy. - * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula: - * - * Math.max(bodyA.restitution, bodyB.restitution) - * - * @property restitution - * @type number - * @default 0 - */ - - /** - * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`. - * A value of `0` means that the body may slide indefinitely. - * A value of `1` means the body may come to a stop almost instantly after a force is applied. - * - * The effects of the value may be non-linear. - * High values may be unstable depending on the body. - * The engine uses a Coulomb friction model including static and kinetic friction. - * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula: - * - * Math.min(bodyA.friction, bodyB.friction) - * - * @property friction - * @type number - * @default 0.1 - */ - - /** - * A `Number` that defines the static friction of the body (in the Coulomb friction model). - * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used. - * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary. - * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction. - * - * @property frictionStatic - * @type number - * @default 0.5 - */ - - /** - * A `Number` that defines the air friction of the body (air resistance). - * A value of `0` means the body will never slow as it moves through space. - * The higher the value, the faster a body slows when moving through space. - * The effects of the value are non-linear. - * - * @property frictionAir - * @type number - * @default 0.01 - */ - - /** - * An `Object` that specifies the collision filtering properties of this body. - * - * Collisions between two bodies will obey the following rules: - * - If the two bodies have the same non-zero value of `collisionFilter.group`, - * they will always collide if the value is positive, and they will never collide - * if the value is negative. - * - If the two bodies have different values of `collisionFilter.group` or if one - * (or both) of the bodies has a value of 0, then the category/mask rules apply as follows: - * - * Each body belongs to a collision category, given by `collisionFilter.category`. This - * value is used as a bit field and the category should have only one bit set, meaning that - * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32 - * different collision categories available. - * - * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies - * the categories it collides with (the value is the bitwise AND value of all these categories). - * - * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's - * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0` - * are both true. - * - * @property collisionFilter - * @type object - */ - - /** - * An Integer `Number`, that specifies the collision group this body belongs to. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.group - * @type object - * @default 0 - */ - - /** - * A bit field that specifies the collision category this body belongs to. - * The category value should have only one bit set, for example `0x0001`. - * This means there are up to 32 unique collision categories available. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.category - * @type object - * @default 1 - */ - - /** - * A bit mask that specifies the collision categories this body may collide with. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.mask - * @type object - * @default -1 - */ - - /** - * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies. - * Avoid changing this value unless you understand the purpose of `slop` in physics engines. - * The default should generally suffice, although very large bodies may require larger values for stable stacking. - * - * @property slop - * @type number - * @default 0.05 - */ - - /** - * A `Number` that allows per-body time scaling, e.g. a force-field where bodies inside are in slow-motion, while others are at full speed. - * - * @property timeScale - * @type number - * @default 1 - */ - - /** - * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. - * - * @property render - * @type object - */ - - /** - * A flag that indicates if the body should be rendered. - * - * @property render.visible - * @type boolean - * @default true - */ - - /** - * Sets the opacity to use when rendering. - * - * @property render.opacity - * @type number - * @default 1 - */ - - /** - * An `Object` that defines the sprite properties to use when rendering, if any. - * - * @property render.sprite - * @type object - */ - - /** - * An `String` that defines the path to the image to use as the sprite texture, if any. - * - * @property render.sprite.texture - * @type string - */ - - /** - * A `Number` that defines the scaling in the x-axis for the sprite, if any. - * - * @property render.sprite.xScale - * @type number - * @default 1 - */ - - /** - * A `Number` that defines the scaling in the y-axis for the sprite, if any. - * - * @property render.sprite.yScale - * @type number - * @default 1 - */ - - /** - * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width). - * - * @property render.sprite.xOffset - * @type number - * @default 0 - */ - - /** - * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height). - * - * @property render.sprite.yOffset - * @type number - * @default 0 - */ - - /** - * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined). - * A value of `0` means no outline will be rendered. - * - * @property render.lineWidth - * @type number - * @default 0 - */ - - /** - * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined). - * It is the same as when using a canvas, so it accepts CSS style property values. - * - * @property render.fillStyle - * @type string - * @default a random colour - */ - - /** - * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined). - * It is the same as when using a canvas, so it accepts CSS style property values. - * - * @property render.strokeStyle - * @type string - * @default a random colour - */ - - /** - * An array of unique axis vectors (edge normals) used for collision detection. - * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`. - * They are constantly updated by `Body.update` during the simulation. - * - * @property axes - * @type vector[] - */ - - /** - * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`. - * - * @property area - * @type string - * @default - */ - - /** - * A `Bounds` object that defines the AABB region for the body. - * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation. - * - * @property bounds - * @type bounds - */ - -})(); - - /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { @@ -3676,7 +3883,9 @@ var Sleeping = {}; module.exports = Sleeping; -var Events = __webpack_require__(4); +var Body = __webpack_require__(4); +var Events = __webpack_require__(5); +var Common = __webpack_require__(0); (function() { @@ -3688,15 +3897,18 @@ var Events = __webpack_require__(4); * Puts bodies to sleep or wakes them up depending on their motion. * @method update * @param {body[]} bodies - * @param {number} timeScale + * @param {number} delta */ - Sleeping.update = function(bodies, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; - + Sleeping.update = function(bodies, delta) { + var timeScale = delta / Common._baseDelta, + motionSleepThreshold = Sleeping._motionSleepThreshold; + // update bodies sleeping status for (var i = 0; i < bodies.length; i++) { var body = bodies[i], - motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed; + speed = Body.getSpeed(body), + angularSpeed = Body.getAngularSpeed(body), + motion = speed * speed + angularSpeed * angularSpeed; // wake up bodies if they have a force applied if (body.force.x !== 0 || body.force.y !== 0) { @@ -3709,12 +3921,13 @@ var Events = __webpack_require__(4); // biased average motion estimation between frames body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion; - - if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) { + + if (body.sleepThreshold > 0 && body.motion < motionSleepThreshold) { body.sleepCounter += 1; - if (body.sleepCounter >= body.sleepThreshold) + if (body.sleepCounter >= body.sleepThreshold / timeScale) { Sleeping.set(body, true); + } } else if (body.sleepCounter > 0) { body.sleepCounter -= 1; } @@ -3725,10 +3938,9 @@ var Events = __webpack_require__(4); * Given a set of colliding pairs, wakes the sleeping bodies involved. * @method afterCollisions * @param {pair[]} pairs - * @param {number} timeScale */ - Sleeping.afterCollisions = function(pairs, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; + Sleeping.afterCollisions = function(pairs) { + var motionSleepThreshold = Sleeping._motionSleepThreshold; // wake up bodies involved in collisions for (var i = 0; i < pairs.length; i++) { @@ -3750,7 +3962,7 @@ var Events = __webpack_require__(4); var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB, movingBody = sleepingBody === bodyA ? bodyB : bodyA; - if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) { + if (!sleepingBody.isStatic && movingBody.motion > motionSleepThreshold) { Sleeping.set(sleepingBody, false); } } @@ -4225,7 +4437,7 @@ var Pair = {}; module.exports = Pair; -var Contact = __webpack_require__(17); +var Contact = __webpack_require__(16); (function() { @@ -4457,9 +4669,11 @@ var Common = __webpack_require__(0); * @private * @method solveAll * @param {constraint[]} constraints - * @param {number} timeScale + * @param {number} delta */ - Constraint.solveAll = function(constraints, timeScale) { + Constraint.solveAll = function(constraints, delta) { + var timeScale = Common.clamp(delta / Common._baseDelta, 0, 1); + // Solve fixed constraints first. for (var i = 0; i < constraints.length; i += 1) { var constraint = constraints[i], @@ -4530,7 +4744,10 @@ var Common = __webpack_require__(0); // solve distance constraint with Gauss-Siedel method var difference = (currentLength - constraint.length) / currentLength, - stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness, + isRigid = constraint.stiffness >= 1 || constraint.length === 0, + stiffness = isRigid ? constraint.stiffness * timeScale + : constraint.stiffness * timeScale * timeScale, + damping = constraint.damping * timeScale, force = Vector.mult(delta, difference * stiffness), massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0), inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0), @@ -4540,8 +4757,8 @@ var Common = __webpack_require__(0); normal, normalVelocity, relativeVelocity; - - if (constraint.damping) { + + if (damping > 0) { var zero = Vector.create(); normal = Vector.div(delta, currentLength); @@ -4565,9 +4782,9 @@ var Common = __webpack_require__(0); bodyA.position.y -= force.y * share; // apply damping - if (constraint.damping) { - bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share; - bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share; + if (damping > 0) { + bodyA.positionPrev.x -= damping * normal.x * normalVelocity * share; + bodyA.positionPrev.y -= damping * normal.y * normalVelocity * share; } // apply torque @@ -4588,9 +4805,9 @@ var Common = __webpack_require__(0); bodyB.position.y += force.y * share; // apply damping - if (constraint.damping) { - bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share; - bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share; + if (damping > 0) { + bodyB.positionPrev.x += damping * normal.x * normalVelocity * share; + bodyB.positionPrev.y += damping * normal.y * normalVelocity * share; } // apply torque @@ -4655,8 +4872,10 @@ var Common = __webpack_require__(0); */ Constraint.pointAWorld = function(constraint) { return { - x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + constraint.pointA.x, - y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + constraint.pointA.y + x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + + (constraint.pointA ? constraint.pointA.x : 0), + y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + + (constraint.pointA ? constraint.pointA.y : 0) }; }; @@ -4668,8 +4887,10 @@ var Common = __webpack_require__(0); */ Constraint.pointBWorld = function(constraint) { return { - x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + constraint.pointB.x, - y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + constraint.pointB.y + x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + + (constraint.pointB ? constraint.pointB.x : 0), + y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + + (constraint.pointB ? constraint.pointB.y : 0) }; }; @@ -4917,7 +5138,7 @@ module.exports = Bodies; var Vertices = __webpack_require__(3); var Common = __webpack_require__(0); -var Body = __webpack_require__(6); +var Body = __webpack_require__(4); var Bounds = __webpack_require__(1); var Vector = __webpack_require__(2); @@ -5264,6 +5485,202 @@ var Vector = __webpack_require__(2); /* 13 */ /***/ (function(module, exports, __webpack_require__) { +/** +* The `Matter.Detector` module contains methods for efficiently detecting collisions between a list of bodies using a broadphase algorithm. +* +* @class Detector +*/ + +var Detector = {}; + +module.exports = Detector; + +var Common = __webpack_require__(0); +var Collision = __webpack_require__(8); + +(function() { + + /** + * Creates a new collision detector. + * @method create + * @param {} options + * @return {detector} A new collision detector + */ + Detector.create = function(options) { + var defaults = { + bodies: [], + pairs: null + }; + + return Common.extend(defaults, options); + }; + + /** + * Sets the list of bodies in the detector. + * @method setBodies + * @param {detector} detector + * @param {body[]} bodies + */ + Detector.setBodies = function(detector, bodies) { + detector.bodies = bodies.slice(0); + }; + + /** + * Clears the detector including its list of bodies. + * @method clear + * @param {detector} detector + */ + Detector.clear = function(detector) { + detector.bodies = []; + }; + + /** + * Efficiently finds all collisions among all the bodies in `detector.bodies` using a broadphase algorithm. + * + * _Note:_ The specific ordering of collisions returned is not guaranteed between releases and may change for performance reasons. + * If a specific ordering is required then apply a sort to the resulting array. + * @method collisions + * @param {detector} detector + * @return {collision[]} collisions + */ + Detector.collisions = function(detector) { + var collisions = [], + pairs = detector.pairs, + bodies = detector.bodies, + bodiesLength = bodies.length, + canCollide = Detector.canCollide, + collides = Collision.collides, + i, + j; + + bodies.sort(Detector._compareBoundsX); + + for (i = 0; i < bodiesLength; i++) { + var bodyA = bodies[i], + boundsA = bodyA.bounds, + boundXMax = bodyA.bounds.max.x, + boundYMax = bodyA.bounds.max.y, + boundYMin = bodyA.bounds.min.y, + bodyAStatic = bodyA.isStatic || bodyA.isSleeping, + partsALength = bodyA.parts.length, + partsASingle = partsALength === 1; + + for (j = i + 1; j < bodiesLength; j++) { + var bodyB = bodies[j], + boundsB = bodyB.bounds; + + if (boundsB.min.x > boundXMax) { + break; + } + + if (boundYMax < boundsB.min.y || boundYMin > boundsB.max.y) { + continue; + } + + if (bodyAStatic && (bodyB.isStatic || bodyB.isSleeping)) { + continue; + } + + if (!canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) { + continue; + } + + var partsBLength = bodyB.parts.length; + + if (partsASingle && partsBLength === 1) { + var collision = collides(bodyA, bodyB, pairs); + + if (collision) { + collisions.push(collision); + } + } else { + var partsAStart = partsALength > 1 ? 1 : 0, + partsBStart = partsBLength > 1 ? 1 : 0; + + for (var k = partsAStart; k < partsALength; k++) { + var partA = bodyA.parts[k], + boundsA = partA.bounds; + + for (var z = partsBStart; z < partsBLength; z++) { + var partB = bodyB.parts[z], + boundsB = partB.bounds; + + if (boundsA.min.x > boundsB.max.x || boundsA.max.x < boundsB.min.x + || boundsA.max.y < boundsB.min.y || boundsA.min.y > boundsB.max.y) { + continue; + } + + var collision = collides(partA, partB, pairs); + + if (collision) { + collisions.push(collision); + } + } + } + } + } + } + + return collisions; + }; + + /** + * Returns `true` if both supplied collision filters will allow a collision to occur. + * See `body.collisionFilter` for more information. + * @method canCollide + * @param {} filterA + * @param {} filterB + * @return {bool} `true` if collision can occur + */ + Detector.canCollide = function(filterA, filterB) { + if (filterA.group === filterB.group && filterA.group !== 0) + return filterA.group > 0; + + return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0; + }; + + /** + * The comparison function used in the broadphase algorithm. + * Returns the signed delta of the bodies bounds on the x-axis. + * @private + * @method _sortCompare + * @param {body} bodyA + * @param {body} bodyB + * @return {number} The signed delta used for sorting + */ + Detector._compareBoundsX = function(bodyA, bodyB) { + return bodyA.bounds.min.x - bodyB.bounds.min.x; + }; + + /* + * + * Properties Documentation + * + */ + + /** + * The array of `Matter.Body` between which the detector finds collisions. + * + * _Note:_ The order of bodies in this array _is not fixed_ and will be continually managed by the detector. + * @property bodies + * @type body[] + * @default [] + */ + + /** + * Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage. + * @property pairs + * @type {pairs|null} + * @default null + */ + +})(); + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + /** * The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs. * @@ -5467,202 +5884,6 @@ var Common = __webpack_require__(0); })(); -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Detector` module contains methods for efficiently detecting collisions between a list of bodies using a broadphase algorithm. -* -* @class Detector -*/ - -var Detector = {}; - -module.exports = Detector; - -var Common = __webpack_require__(0); -var Collision = __webpack_require__(8); - -(function() { - - /** - * Creates a new collision detector. - * @method create - * @param {} options - * @return {detector} A new collision detector - */ - Detector.create = function(options) { - var defaults = { - bodies: [], - pairs: null - }; - - return Common.extend(defaults, options); - }; - - /** - * Sets the list of bodies in the detector. - * @method setBodies - * @param {detector} detector - * @param {body[]} bodies - */ - Detector.setBodies = function(detector, bodies) { - detector.bodies = bodies.slice(0); - }; - - /** - * Clears the detector including its list of bodies. - * @method clear - * @param {detector} detector - */ - Detector.clear = function(detector) { - detector.bodies = []; - }; - - /** - * Efficiently finds all collisions among all the bodies in `detector.bodies` using a broadphase algorithm. - * - * _Note:_ The specific ordering of collisions returned is not guaranteed between releases and may change for performance reasons. - * If a specific ordering is required then apply a sort to the resulting array. - * @method collisions - * @param {detector} detector - * @return {collision[]} collisions - */ - Detector.collisions = function(detector) { - var collisions = [], - pairs = detector.pairs, - bodies = detector.bodies, - bodiesLength = bodies.length, - canCollide = Detector.canCollide, - collides = Collision.collides, - i, - j; - - bodies.sort(Detector._compareBoundsX); - - for (i = 0; i < bodiesLength; i++) { - var bodyA = bodies[i], - boundsA = bodyA.bounds, - boundXMax = bodyA.bounds.max.x, - boundYMax = bodyA.bounds.max.y, - boundYMin = bodyA.bounds.min.y, - bodyAStatic = bodyA.isStatic || bodyA.isSleeping, - partsALength = bodyA.parts.length, - partsASingle = partsALength === 1; - - for (j = i + 1; j < bodiesLength; j++) { - var bodyB = bodies[j], - boundsB = bodyB.bounds; - - if (boundsB.min.x > boundXMax) { - break; - } - - if (boundYMax < boundsB.min.y || boundYMin > boundsB.max.y) { - continue; - } - - if (bodyAStatic && (bodyB.isStatic || bodyB.isSleeping)) { - continue; - } - - if (!canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) { - continue; - } - - var partsBLength = bodyB.parts.length; - - if (partsASingle && partsBLength === 1) { - var collision = collides(bodyA, bodyB, pairs); - - if (collision) { - collisions.push(collision); - } - } else { - var partsAStart = partsALength > 1 ? 1 : 0, - partsBStart = partsBLength > 1 ? 1 : 0; - - for (var k = partsAStart; k < partsALength; k++) { - var partA = bodyA.parts[k], - boundsA = partA.bounds; - - for (var z = partsBStart; z < partsBLength; z++) { - var partB = bodyB.parts[z], - boundsB = partB.bounds; - - if (boundsA.min.x > boundsB.max.x || boundsA.max.x < boundsB.min.x - || boundsA.max.y < boundsB.min.y || boundsA.min.y > boundsB.max.y) { - continue; - } - - var collision = collides(partA, partB, pairs); - - if (collision) { - collisions.push(collision); - } - } - } - } - } - } - - return collisions; - }; - - /** - * Returns `true` if both supplied collision filters will allow a collision to occur. - * See `body.collisionFilter` for more information. - * @method canCollide - * @param {} filterA - * @param {} filterB - * @return {bool} `true` if collision can occur - */ - Detector.canCollide = function(filterA, filterB) { - if (filterA.group === filterB.group && filterA.group !== 0) - return filterA.group > 0; - - return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0; - }; - - /** - * The comparison function used in the broadphase algorithm. - * Returns the signed delta of the bodies bounds on the x-axis. - * @private - * @method _sortCompare - * @param {body} bodyA - * @param {body} bodyB - * @return {number} The signed delta used for sorting - */ - Detector._compareBoundsX = function(bodyA, bodyB) { - return bodyA.bounds.min.x - bodyB.bounds.min.x; - }; - - /* - * - * Properties Documentation - * - */ - - /** - * The array of `Matter.Body` between which the detector finds collisions. - * - * _Note:_ The order of bodies in this array _is not fixed_ and will be continually managed by the detector. - * @property bodies - * @type body[] - * @default [] - */ - - /** - * Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage. - * @property pairs - * @type {pairs|null} - * @default null - */ - -})(); - - /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { @@ -6022,6 +6243,2332 @@ var Common = __webpack_require__(0); /***/ }), /* 16 */ +/***/ (function(module, exports) { + +/** +* The `Matter.Contact` module contains methods for creating and manipulating collision contacts. +* +* @class Contact +*/ + +var Contact = {}; + +module.exports = Contact; + +(function() { + + /** + * Creates a new contact. + * @method create + * @param {vertex} vertex + * @return {contact} A new contact + */ + Contact.create = function(vertex) { + return { + vertex: vertex, + normalImpulse: 0, + tangentImpulse: 0 + }; + }; + +})(); + + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* 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 Sleeping = __webpack_require__(7); +var Resolver = __webpack_require__(18); +var Detector = __webpack_require__(13); +var Pairs = __webpack_require__(19); +var Events = __webpack_require__(5); +var Composite = __webpack_require__(6); +var Constraint = __webpack_require__(10); +var Common = __webpack_require__(0); +var Body = __webpack_require__(4); + +(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(options) { + options = options || {}; + + var defaults = { + positionIterations: 6, + velocityIterations: 4, + constraintIterations: 2, + enableSleeping: false, + events: [], + plugin: {}, + gravity: { + x: 0, + y: 1, + scale: 0.001 + }, + timing: { + timestamp: 0, + timeScale: 1, + lastDelta: 0, + lastElapsed: 0 + } + }; + + var engine = Common.extend(defaults, options); + + engine.world = options.world || Composite.create({ label: 'World' }); + engine.pairs = options.pairs || Pairs.create(); + engine.detector = options.detector || Detector.create(); + + // for temporary back compatibility only + engine.grid = { buckets: [] }; + engine.world.gravity = engine.gravity; + engine.broadphase = engine.grid; + engine.metrics = {}; + + return engine; + }; + + /** + * Moves the simulation forward in time by `delta` milliseconds. + * Triggers `beforeUpdate` and `afterUpdate` events. + * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. + * @method update + * @param {engine} engine + * @param {number} [delta=16.666] + */ + Engine.update = function(engine, delta) { + var startTime = Common.now(); + + var world = engine.world, + detector = engine.detector, + pairs = engine.pairs, + timing = engine.timing, + timestamp = timing.timestamp, + i; + + delta = typeof delta !== 'undefined' ? delta : Common._baseDelta; + delta *= timing.timeScale; + + // increment timestamp + timing.timestamp += delta; + timing.lastDelta = delta; + + // create an event object + var event = { + timestamp: timing.timestamp, + delta: delta + }; + + Events.trigger(engine, 'beforeUpdate', event); + + // get all bodies and all constraints in the world + var allBodies = Composite.allBodies(world), + allConstraints = Composite.allConstraints(world); + + // if the world has changed + if (world.isModified) { + // update the detector bodies + Detector.setBodies(detector, allBodies); + + // reset all composite modified flags + Composite.setModified(world, false, false, true); + } + + // update sleeping if enabled + if (engine.enableSleeping) + Sleeping.update(allBodies, delta); + + // apply gravity to all bodies + Engine._bodiesApplyGravity(allBodies, engine.gravity); + + // update all body position and rotation by integration + if (delta > 0) { + Engine._bodiesUpdate(allBodies, delta); + } + + // update all constraints (first pass) + Constraint.preSolveAll(allBodies); + for (i = 0; i < engine.constraintIterations; i++) { + Constraint.solveAll(allConstraints, delta); + } + Constraint.postSolveAll(allBodies); + + // find all collisions + detector.pairs = engine.pairs; + var collisions = Detector.collisions(detector); + + // update collision pairs + Pairs.update(pairs, collisions, timestamp); + + // wake up bodies involved in collisions + if (engine.enableSleeping) + Sleeping.afterCollisions(pairs.list); + + // trigger collision events + if (pairs.collisionStart.length > 0) + Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart }); + + // iteratively resolve position between collisions + var positionDamping = Common.clamp(20 / engine.positionIterations, 0, 1); + + Resolver.preSolvePosition(pairs.list); + for (i = 0; i < engine.positionIterations; i++) { + Resolver.solvePosition(pairs.list, delta, positionDamping); + } + Resolver.postSolvePosition(allBodies); + + // update all constraints (second pass) + Constraint.preSolveAll(allBodies); + for (i = 0; i < engine.constraintIterations; i++) { + Constraint.solveAll(allConstraints, delta); + } + Constraint.postSolveAll(allBodies); + + // iteratively resolve velocity between collisions + Resolver.preSolveVelocity(pairs.list); + for (i = 0; i < engine.velocityIterations; i++) { + Resolver.solveVelocity(pairs.list, delta); + } + + // update body speed and velocity properties + Engine._bodiesUpdateVelocities(allBodies); + + // 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 }); + + // clear force buffers + Engine._bodiesClearForces(allBodies); + + Events.trigger(engine, 'afterUpdate', event); + + // log the time elapsed computing this update + engine.timing.lastElapsed = Common.now() - startTime; + + 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 pairs and detector. + * @method clear + * @param {engine} engine + */ + Engine.clear = function(engine) { + Pairs.clear(engine.pairs); + Detector.clear(engine.detector); + }; + + /** + * Zeroes the `body.force` and `body.torque` force buffers. + * @method _bodiesClearForces + * @private + * @param {body[]} bodies + */ + Engine._bodiesClearForces = function(bodies) { + var bodiesLength = bodies.length; + + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; + + // reset force buffers + body.force.x = 0; + body.force.y = 0; + body.torque = 0; + } + }; + + /** + * Applies gravitational acceleration to all `bodies`. + * This models a [uniform gravitational field](https://en.wikipedia.org/wiki/Gravity_of_Earth), similar to near the surface of a planet. + * + * @method _bodiesApplyGravity + * @private + * @param {body[]} bodies + * @param {vector} gravity + */ + Engine._bodiesApplyGravity = function(bodies, gravity) { + var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001, + bodiesLength = bodies.length; + + if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) { + return; + } + + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; + + if (body.isStatic || body.isSleeping) + continue; + + // add the resultant force of gravity + body.force.y += body.mass * gravity.y * gravityScale; + body.force.x += body.mass * gravity.x * gravityScale; + } + }; + + /** + * Applies `Body.update` to all given `bodies`. + * @method _bodiesUpdate + * @private + * @param {body[]} bodies + * @param {number} delta The amount of time elapsed between updates + */ + Engine._bodiesUpdate = function(bodies, delta) { + var bodiesLength = bodies.length; + + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; + + if (body.isStatic || body.isSleeping) + continue; + + Body.update(body, delta); + } + }; + + /** + * Applies `Body.updateVelocities` to all given `bodies`. + * @method _bodiesUpdateVelocities + * @private + * @param {body[]} bodies + */ + Engine._bodiesUpdateVelocities = function(bodies) { + var bodiesLength = bodies.length; + + for (var i = 0; i < bodiesLength; i++) { + Body.updateVelocities(bodies[i]); + } + }; + + /** + * A deprecated alias for `Runner.run`, use `Matter.Runner.run(engine)` instead and see `Matter.Runner` for more information. + * @deprecated use Matter.Runner.run(engine) instead + * @method run + * @param {engine} engine + */ + + /** + * Fired just before an update + * + * @event beforeUpdate + * @param {object} event An event object + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ + + /** + * Fired after engine update and all collision events + * + * @event afterUpdate + * @param {object} event An event object + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update + * @param {engine} event.source The source object of the event + * @param {string} 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 {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update + * @param {engine} event.source The source object of the event + * @param {string} 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 {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update + * @param {engine} event.source The source object of the event + * @param {string} 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 {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update + * @param {engine} event.source The source object of the event + * @param {string} 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 + */ + + /** + * A `Number` that represents the total execution time elapsed during the last `Engine.update` in milliseconds. + * It is updated by timing from the start of the last `Engine.update` call until it ends. + * + * This value will also include the total execution time of all event handlers directly or indirectly triggered by the engine update. + * + * @property timing.lastElapsed + * @type number + * @default 0 + */ + + /** + * A `Number` that represents the `delta` value used in the last engine update. + * + * @property timing.lastDelta + * @type number + * @default 0 + */ + + /** + * A `Matter.Detector` instance. + * + * @property detector + * @type detector + * @default a Matter.Detector instance + */ + + /** + * A `Matter.Grid` instance. + * + * @deprecated replaced by `engine.detector` + * @property grid + * @type grid + * @default a Matter.Grid instance + */ + + /** + * Replaced by and now alias for `engine.grid`. + * + * @deprecated replaced by `engine.detector` + * @property broadphase + * @type grid + * @default a Matter.Grid instance + */ + + /** + * The root `Matter.Composite` instance that will contain all bodies, constraints and other composites to be simulated by this engine. + * + * @property world + * @type composite + * @default a Matter.Composite instance + */ + + /** + * An object reserved for storing plugin-specific properties. + * + * @property plugin + * @type {} + */ + + /** + * An optional gravitational acceleration applied to all bodies in `engine.world` on every update. + * + * This models a [uniform gravitational field](https://en.wikipedia.org/wiki/Gravity_of_Earth), similar to near the surface of a planet. For gravity in other contexts, disable this and apply forces as needed. + * + * To disable set the `scale` component to `0`. + * + * This is split into three components for ease of use: + * a normalised direction (`x` and `y`) and magnitude (`scale`). + * + * @property gravity + * @type object + */ + + /** + * The gravitational direction normal `x` component, to be multiplied by `gravity.scale`. + * + * @property gravity.x + * @type object + * @default 0 + */ + + /** + * The gravitational direction normal `y` component, to be multiplied by `gravity.scale`. + * + * @property gravity.y + * @type object + * @default 1 + */ + + /** + * The magnitude of the gravitational acceleration. + * + * @property gravity.scale + * @type object + * @default 0.001 + */ + +})(); + + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter.Resolver` module contains methods for resolving collision pairs. +* +* @class Resolver +*/ + +var Resolver = {}; + +module.exports = Resolver; + +var Vertices = __webpack_require__(3); +var Common = __webpack_require__(0); +var Bounds = __webpack_require__(1); + +(function() { + + Resolver._restingThresh = 2; + Resolver._restingThreshTangent = Math.sqrt(6); + Resolver._positionDampen = 0.9; + Resolver._positionWarming = 0.8; + Resolver._frictionNormalMultiplier = 5; + Resolver._frictionMaxStatic = Number.MAX_VALUE; + + /** + * Prepare pairs for position solving. + * @method preSolvePosition + * @param {pair[]} pairs + */ + Resolver.preSolvePosition = function(pairs) { + var i, + pair, + activeCount, + pairsLength = pairs.length; + + // find total contacts on each body + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; + + if (!pair.isActive) + continue; + + activeCount = pair.activeContacts.length; + pair.collision.parentA.totalContacts += activeCount; + pair.collision.parentB.totalContacts += activeCount; + } + }; + + /** + * Find a solution for pair positions. + * @method solvePosition + * @param {pair[]} pairs + * @param {number} delta + * @param {number} [damping=1] + */ + Resolver.solvePosition = function(pairs, delta, damping) { + var i, + pair, + collision, + bodyA, + bodyB, + normal, + contactShare, + positionImpulse, + positionDampen = Resolver._positionDampen * (damping || 1), + slopDampen = Common.clamp(delta / Common._baseDelta, 0, 1), + pairsLength = pairs.length; + + // find impulses required to resolve penetration + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; + + if (!pair.isActive || pair.isSensor) + continue; + + collision = pair.collision; + bodyA = collision.parentA; + bodyB = collision.parentB; + normal = collision.normal; + + // get current separation between body edges involved in collision + pair.separation = + normal.x * (bodyB.positionImpulse.x + collision.penetration.x - bodyA.positionImpulse.x) + + normal.y * (bodyB.positionImpulse.y + collision.penetration.y - bodyA.positionImpulse.y); + } + + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; + + if (!pair.isActive || pair.isSensor) + continue; + + collision = pair.collision; + bodyA = collision.parentA; + bodyB = collision.parentB; + normal = collision.normal; + positionImpulse = pair.separation - pair.slop * slopDampen; + + if (bodyA.isStatic || bodyB.isStatic) + positionImpulse *= 2; + + if (!(bodyA.isStatic || bodyA.isSleeping)) { + contactShare = positionDampen / bodyA.totalContacts; + bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare; + bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare; + } + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + contactShare = positionDampen / bodyB.totalContacts; + bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare; + bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare; + } + } + }; + + /** + * Apply position resolution. + * @method postSolvePosition + * @param {body[]} bodies + */ + Resolver.postSolvePosition = function(bodies) { + var positionWarming = Resolver._positionWarming, + bodiesLength = bodies.length, + verticesTranslate = Vertices.translate, + boundsUpdate = Bounds.update; + + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i], + positionImpulse = body.positionImpulse, + positionImpulseX = positionImpulse.x, + positionImpulseY = positionImpulse.y, + velocity = body.velocity; + + // reset contact count + body.totalContacts = 0; + + if (positionImpulseX !== 0 || positionImpulseY !== 0) { + // update body geometry + for (var j = 0; j < body.parts.length; j++) { + var part = body.parts[j]; + verticesTranslate(part.vertices, positionImpulse); + boundsUpdate(part.bounds, part.vertices, velocity); + part.position.x += positionImpulseX; + part.position.y += positionImpulseY; + } + + // move the body without changing velocity + body.positionPrev.x += positionImpulseX; + body.positionPrev.y += positionImpulseY; + + if (positionImpulseX * velocity.x + positionImpulseY * velocity.y < 0) { + // reset cached impulse if the body has velocity along it + positionImpulse.x = 0; + positionImpulse.y = 0; + } else { + // warm the next iteration + positionImpulse.x *= positionWarming; + positionImpulse.y *= positionWarming; + } + } + } + }; + + /** + * Prepare pairs for velocity solving. + * @method preSolveVelocity + * @param {pair[]} pairs + */ + Resolver.preSolveVelocity = function(pairs) { + var pairsLength = pairs.length, + i, + j; + + for (i = 0; i < pairsLength; i++) { + var pair = pairs[i]; + + if (!pair.isActive || pair.isSensor) + continue; + + var contacts = pair.activeContacts, + contactsLength = contacts.length, + collision = pair.collision, + bodyA = collision.parentA, + bodyB = collision.parentB, + normal = collision.normal, + tangent = collision.tangent; + + // resolve each contact + for (j = 0; j < contactsLength; j++) { + var contact = contacts[j], + contactVertex = contact.vertex, + normalImpulse = contact.normalImpulse, + tangentImpulse = contact.tangentImpulse; + + if (normalImpulse !== 0 || tangentImpulse !== 0) { + // total impulse from contact + var impulseX = normal.x * normalImpulse + tangent.x * tangentImpulse, + impulseY = normal.y * normalImpulse + tangent.y * tangentImpulse; + + // apply impulse from contact + if (!(bodyA.isStatic || bodyA.isSleeping)) { + bodyA.positionPrev.x += impulseX * bodyA.inverseMass; + bodyA.positionPrev.y += impulseY * bodyA.inverseMass; + bodyA.anglePrev += bodyA.inverseInertia * ( + (contactVertex.x - bodyA.position.x) * impulseY + - (contactVertex.y - bodyA.position.y) * impulseX + ); + } + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; + bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; + bodyB.anglePrev -= bodyB.inverseInertia * ( + (contactVertex.x - bodyB.position.x) * impulseY + - (contactVertex.y - bodyB.position.y) * impulseX + ); + } + } + } + } + }; + + /** + * Find a solution for pair velocities. + * @method solveVelocity + * @param {pair[]} pairs + * @param {number} delta + */ + Resolver.solveVelocity = function(pairs, delta) { + var timeScale = delta / Common._baseDelta, + timeScaleSquared = timeScale * timeScale, + timeScaleCubed = timeScaleSquared * timeScale, + restingThresh = -Resolver._restingThresh * timeScale, + restingThreshTangent = Resolver._restingThreshTangent, + frictionNormalMultiplier = Resolver._frictionNormalMultiplier * timeScale, + frictionMaxStatic = Resolver._frictionMaxStatic, + pairsLength = pairs.length, + tangentImpulse, + maxFriction, + i, + j; + + for (i = 0; i < pairsLength; i++) { + var pair = pairs[i]; + + if (!pair.isActive || pair.isSensor) + continue; + + var collision = pair.collision, + bodyA = collision.parentA, + bodyB = collision.parentB, + bodyAVelocity = bodyA.velocity, + bodyBVelocity = bodyB.velocity, + normalX = collision.normal.x, + normalY = collision.normal.y, + tangentX = collision.tangent.x, + tangentY = collision.tangent.y, + contacts = pair.activeContacts, + contactsLength = contacts.length, + contactShare = 1 / contactsLength, + inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, + friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier; + + // update body velocities + bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x; + bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y; + bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x; + bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y; + bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; + bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; + + // resolve each contact + for (j = 0; j < contactsLength; j++) { + var contact = contacts[j], + contactVertex = contact.vertex; + + var offsetAX = contactVertex.x - bodyA.position.x, + offsetAY = contactVertex.y - bodyA.position.y, + offsetBX = contactVertex.x - bodyB.position.x, + offsetBY = contactVertex.y - bodyB.position.y; + + var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity, + velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity, + velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity, + velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity; + + var relativeVelocityX = velocityPointAX - velocityPointBX, + relativeVelocityY = velocityPointAY - velocityPointBY; + + var normalVelocity = normalX * relativeVelocityX + normalY * relativeVelocityY, + tangentVelocity = tangentX * relativeVelocityX + tangentY * relativeVelocityY; + + // coulomb friction + var normalOverlap = pair.separation + normalVelocity; + var normalForce = Math.min(normalOverlap, 1); + normalForce = normalOverlap < 0 ? 0 : normalForce; + + var frictionLimit = normalForce * friction; + + if (tangentVelocity < -frictionLimit || tangentVelocity > frictionLimit) { + maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity); + tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleCubed; + + if (tangentImpulse < -maxFriction) { + tangentImpulse = -maxFriction; + } else if (tangentImpulse > maxFriction) { + tangentImpulse = maxFriction; + } + } else { + tangentImpulse = tangentVelocity; + maxFriction = frictionMaxStatic; + } + + // account for mass, inertia and contact offset + var oAcN = offsetAX * normalY - offsetAY * normalX, + oBcN = offsetBX * normalY - offsetBY * normalX, + share = contactShare / (inverseMassTotal + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN); + + // raw impulses + var normalImpulse = (1 + pair.restitution) * normalVelocity * share; + tangentImpulse *= share; + + // handle high velocity and resting collisions separately + if (normalVelocity < restingThresh) { + // high normal velocity so clear cached contact normal impulse + contact.normalImpulse = 0; + } else { + // solve resting collision constraints using Erin Catto's method (GDC08) + // impulse constraint tends to 0 + var contactNormalImpulse = contact.normalImpulse; + contact.normalImpulse += normalImpulse; + if (contact.normalImpulse > 0) contact.normalImpulse = 0; + normalImpulse = contact.normalImpulse - contactNormalImpulse; + } + + // handle high velocity and resting collisions separately + if (tangentVelocity < -restingThreshTangent || tangentVelocity > restingThreshTangent) { + // high tangent velocity so clear cached contact tangent impulse + contact.tangentImpulse = 0; + } else { + // solve resting collision constraints using Erin Catto's method (GDC08) + // tangent impulse tends to -tangentSpeed or +tangentSpeed + var contactTangentImpulse = contact.tangentImpulse; + contact.tangentImpulse += tangentImpulse; + if (contact.tangentImpulse < -maxFriction) contact.tangentImpulse = -maxFriction; + if (contact.tangentImpulse > maxFriction) contact.tangentImpulse = maxFriction; + tangentImpulse = contact.tangentImpulse - contactTangentImpulse; + } + + // total impulse from contact + var impulseX = normalX * normalImpulse + tangentX * tangentImpulse, + impulseY = normalY * normalImpulse + tangentY * tangentImpulse; + + // apply impulse from contact + if (!(bodyA.isStatic || bodyA.isSleeping)) { + bodyA.positionPrev.x += impulseX * bodyA.inverseMass; + bodyA.positionPrev.y += impulseY * bodyA.inverseMass; + bodyA.anglePrev += (offsetAX * impulseY - offsetAY * impulseX) * bodyA.inverseInertia; + } + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; + bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; + bodyB.anglePrev -= (offsetBX * impulseY - offsetBY * impulseX) * bodyB.inverseInertia; + } + } + } + }; + +})(); + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. +* +* @class Pairs +*/ + +var Pairs = {}; + +module.exports = Pairs; + +var Pair = __webpack_require__(9); +var Common = __webpack_require__(0); + +(function() { + + /** + * Creates a new pairs structure. + * @method create + * @param {object} options + * @return {pairs} A new pairs structure + */ + Pairs.create = function(options) { + return Common.extend({ + table: {}, + list: [], + collisionStart: [], + collisionActive: [], + collisionEnd: [] + }, options); + }; + + /** + * Updates pairs given a list of collisions. + * @method update + * @param {object} pairs + * @param {collision[]} collisions + * @param {number} timestamp + */ + Pairs.update = function(pairs, collisions, timestamp) { + var pairsList = pairs.list, + pairsListLength = pairsList.length, + pairsTable = pairs.table, + collisionsLength = collisions.length, + collisionStart = pairs.collisionStart, + collisionEnd = pairs.collisionEnd, + collisionActive = pairs.collisionActive, + collision, + pairIndex, + pair, + i; + + // clear collision state arrays, but maintain old reference + collisionStart.length = 0; + collisionEnd.length = 0; + collisionActive.length = 0; + + for (i = 0; i < pairsListLength; i++) { + pairsList[i].confirmedActive = false; + } + + for (i = 0; i < collisionsLength; i++) { + collision = collisions[i]; + pair = collision.pair; + + if (pair) { + // pair already exists (but may or may not be active) + if (pair.isActive) { + // pair exists and is active + collisionActive.push(pair); + } else { + // pair exists but was inactive, so a collision has just started again + collisionStart.push(pair); + } + + // update the pair + Pair.update(pair, collision, timestamp); + pair.confirmedActive = true; + } else { + // pair did not exist, create a new pair + pair = Pair.create(collision, timestamp); + pairsTable[pair.id] = pair; + + // push the new pair + collisionStart.push(pair); + pairsList.push(pair); + } + } + + // find pairs that are no longer active + var removePairIndex = []; + pairsListLength = pairsList.length; + + for (i = 0; i < pairsListLength; i++) { + pair = pairsList[i]; + + if (!pair.confirmedActive) { + Pair.setActive(pair, false, timestamp); + collisionEnd.push(pair); + + if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) { + removePairIndex.push(i); + } + } + } + + // remove inactive pairs + for (i = 0; i < removePairIndex.length; i++) { + pairIndex = removePairIndex[i] - i; + pair = pairsList[pairIndex]; + pairsList.splice(pairIndex, 1); + delete pairsTable[pair.id]; + } + }; + + /** + * Clears the given pairs structure. + * @method clear + * @param {pairs} pairs + * @return {pairs} pairs + */ + Pairs.clear = function(pairs) { + pairs.table = {}; + pairs.list.length = 0; + pairs.collisionStart.length = 0; + pairs.collisionActive.length = 0; + pairs.collisionEnd.length = 0; + return pairs; + }; + +})(); + + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +var Matter = module.exports = __webpack_require__(21); + +Matter.Axes = __webpack_require__(11); +Matter.Bodies = __webpack_require__(12); +Matter.Body = __webpack_require__(4); +Matter.Bounds = __webpack_require__(1); +Matter.Collision = __webpack_require__(8); +Matter.Common = __webpack_require__(0); +Matter.Composite = __webpack_require__(6); +Matter.Composites = __webpack_require__(22); +Matter.Constraint = __webpack_require__(10); +Matter.Contact = __webpack_require__(16); +Matter.Detector = __webpack_require__(13); +Matter.Engine = __webpack_require__(17); +Matter.Events = __webpack_require__(5); +Matter.Grid = __webpack_require__(23); +Matter.Mouse = __webpack_require__(14); +Matter.MouseConstraint = __webpack_require__(24); +Matter.Pair = __webpack_require__(9); +Matter.Pairs = __webpack_require__(19); +Matter.Plugin = __webpack_require__(15); +Matter.Query = __webpack_require__(25); +Matter.Render = __webpack_require__(26); +Matter.Resolver = __webpack_require__(18); +Matter.Runner = __webpack_require__(27); +Matter.SAT = __webpack_require__(28); +Matter.Sleeping = __webpack_require__(7); +Matter.Svg = __webpack_require__(29); +Matter.Vector = __webpack_require__(2); +Matter.Vertices = __webpack_require__(3); +Matter.World = __webpack_require__(30); + +// temporary back compatibility +Matter.Engine.run = Matter.Runner.run; +Matter.Common.deprecated(Matter.Engine, 'run', 'Engine.run ➤ use Matter.Runner.run(engine) instead'); + + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library. +* +* @class Matter +*/ + +var Matter = {}; + +module.exports = Matter; + +var Plugin = __webpack_require__(15); +var Common = __webpack_require__(0); + +(function() { + + /** + * The library name. + * @property name + * @readOnly + * @type {String} + */ + Matter.name = 'matter-js'; + + /** + * The library version. + * @property version + * @readOnly + * @type {String} + */ + Matter.version = true ? "0.19.0" : undefined; + + /** + * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`. + * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`. + * @property uses + * @type {Array} + */ + Matter.uses = []; + + /** + * The plugins that have been installed through `Matter.Plugin.install`. Read only. + * @property used + * @readOnly + * @type {Array} + */ + Matter.used = []; + + /** + * Installs the given plugins on the `Matter` namespace. + * This is a short-hand for `Plugin.use`, see it for more information. + * Call this function once at the start of your code, with all of the plugins you wish to install as arguments. + * Avoid calling this function multiple times unless you intend to manually control installation order. + * @method use + * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument). + */ + Matter.use = function() { + Plugin.use(Matter, Array.prototype.slice.call(arguments)); + }; + + /** + * Chains a function to excute before the original function on the given `path` relative to `Matter`. + * See also docs for `Common.chain`. + * @method before + * @param {string} path The path relative to `Matter` + * @param {function} func The function to chain before the original + * @return {function} The chained function that replaced the original + */ + Matter.before = function(path, func) { + path = path.replace(/^Matter./, ''); + return Common.chainPathBefore(Matter, path, func); + }; + + /** + * Chains a function to excute after the original function on the given `path` relative to `Matter`. + * See also docs for `Common.chain`. + * @method after + * @param {string} path The path relative to `Matter` + * @param {function} func The function to chain after the original + * @return {function} The chained function that replaced the original + */ + Matter.after = function(path, func) { + path = path.replace(/^Matter./, ''); + return Common.chainPathAfter(Matter, path, func); + }; + +})(); + + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter.Composites` module contains factory methods for creating composite bodies +* with commonly used configurations (such as stacks and chains). +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Composites +*/ + +var Composites = {}; + +module.exports = Composites; + +var Composite = __webpack_require__(6); +var Constraint = __webpack_require__(10); +var Common = __webpack_require__(0); +var Body = __webpack_require__(4); +var Bodies = __webpack_require__(12); +var deprecated = Common.deprecated; + +(function() { + + /** + * Create a new composite containing bodies created in the callback in a grid arrangement. + * This function uses the body's bounds to prevent overlaps. + * @method stack + * @param {number} xx + * @param {number} yy + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {function} callback + * @return {composite} A new composite containing objects created in the callback + */ + Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) { + var stack = Composite.create({ label: 'Stack' }), + x = xx, + y = yy, + lastBody, + i = 0; + + for (var row = 0; row < rows; row++) { + var maxHeight = 0; + + for (var column = 0; column < columns; column++) { + var body = callback(x, y, column, row, lastBody, i); + + if (body) { + var bodyHeight = body.bounds.max.y - body.bounds.min.y, + bodyWidth = body.bounds.max.x - body.bounds.min.x; + + if (bodyHeight > maxHeight) + maxHeight = bodyHeight; + + Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 }); + + x = body.bounds.max.x + columnGap; + + Composite.addBody(stack, body); + + lastBody = body; + i += 1; + } else { + x += columnGap; + } + } + + y += maxHeight + rowGap; + x = xx; + } + + return stack; + }; + + /** + * Chains all bodies in the given composite together using constraints. + * @method chain + * @param {composite} composite + * @param {number} xOffsetA + * @param {number} yOffsetA + * @param {number} xOffsetB + * @param {number} yOffsetB + * @param {object} options + * @return {composite} A new composite containing objects chained together with constraints + */ + Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) { + var bodies = composite.bodies; + + for (var i = 1; i < bodies.length; i++) { + var bodyA = bodies[i - 1], + bodyB = bodies[i], + bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y, + bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, + bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y, + bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x; + + var defaults = { + bodyA: bodyA, + pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA }, + bodyB: bodyB, + pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB } + }; + + var constraint = Common.extend(defaults, options); + + Composite.addConstraint(composite, Constraint.create(constraint)); + } + + composite.label += ' Chain'; + + return composite; + }; + + /** + * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. + * @method mesh + * @param {composite} composite + * @param {number} columns + * @param {number} rows + * @param {boolean} crossBrace + * @param {object} options + * @return {composite} The composite containing objects meshed together with constraints + */ + Composites.mesh = function(composite, columns, rows, crossBrace, options) { + var bodies = composite.bodies, + row, + col, + bodyA, + bodyB, + bodyC; + + for (row = 0; row < rows; row++) { + for (col = 1; col < columns; col++) { + bodyA = bodies[(col - 1) + (row * columns)]; + bodyB = bodies[col + (row * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); + } + + if (row > 0) { + for (col = 0; col < columns; col++) { + bodyA = bodies[col + ((row - 1) * columns)]; + bodyB = bodies[col + (row * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); + + if (crossBrace && col > 0) { + bodyC = bodies[(col - 1) + ((row - 1) * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); + } + + if (crossBrace && col < columns - 1) { + bodyC = bodies[(col + 1) + ((row - 1) * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); + } + } + } + } + + composite.label += ' Mesh'; + + return composite; + }; + + /** + * Create a new composite containing bodies created in the callback in a pyramid arrangement. + * This function uses the body's bounds to prevent overlaps. + * @method pyramid + * @param {number} xx + * @param {number} yy + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {function} callback + * @return {composite} A new composite containing objects created in the callback + */ + Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) { + return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) { + var actualRows = Math.min(rows, Math.ceil(columns / 2)), + lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0; + + if (row > actualRows) + return; + + // reverse row order + row = actualRows - row; + + var start = row, + end = columns - 1 - row; + + if (column < start || column > end) + return; + + // retroactively fix the first body's position, since width was unknown + if (i === 1) { + Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 }); + } + + var xOffset = lastBody ? column * lastBodyWidth : 0; + + return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i); + }); + }; + + /** + * This has now moved to the [newtonsCradle example](https://github.com/liabru/matter-js/blob/master/examples/newtonsCradle.js), follow that instead as this function is deprecated here. + * @deprecated moved to newtonsCradle example + * @method newtonsCradle + * @param {number} xx + * @param {number} yy + * @param {number} number + * @param {number} size + * @param {number} length + * @return {composite} A new composite newtonsCradle body + */ + Composites.newtonsCradle = function(xx, yy, number, size, length) { + var newtonsCradle = Composite.create({ label: 'Newtons Cradle' }); + + for (var i = 0; i < number; i++) { + var separation = 1.9, + circle = Bodies.circle(xx + i * (size * separation), yy + length, size, + { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }), + constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle }); + + Composite.addBody(newtonsCradle, circle); + Composite.addConstraint(newtonsCradle, constraint); + } + + return newtonsCradle; + }; + + deprecated(Composites, 'newtonsCradle', 'Composites.newtonsCradle ➤ moved to newtonsCradle example'); + + /** + * This has now moved to the [car example](https://github.com/liabru/matter-js/blob/master/examples/car.js), follow that instead as this function is deprecated here. + * @deprecated moved to car example + * @method car + * @param {number} xx + * @param {number} yy + * @param {number} width + * @param {number} height + * @param {number} wheelSize + * @return {composite} A new composite car body + */ + Composites.car = function(xx, yy, width, height, wheelSize) { + var group = Body.nextGroup(true), + wheelBase = 20, + wheelAOffset = -width * 0.5 + wheelBase, + wheelBOffset = width * 0.5 - wheelBase, + wheelYOffset = 0; + + var car = Composite.create({ label: 'Car' }), + body = Bodies.rectangle(xx, yy, width, height, { + collisionFilter: { + group: group + }, + chamfer: { + radius: height * 0.5 + }, + density: 0.0002 + }); + + var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { + collisionFilter: { + group: group + }, + friction: 0.8 + }); + + var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { + collisionFilter: { + group: group + }, + friction: 0.8 + }); + + var axelA = Constraint.create({ + bodyB: body, + pointB: { x: wheelAOffset, y: wheelYOffset }, + bodyA: wheelA, + stiffness: 1, + length: 0 + }); + + var axelB = Constraint.create({ + bodyB: body, + pointB: { x: wheelBOffset, y: wheelYOffset }, + bodyA: wheelB, + stiffness: 1, + length: 0 + }); + + Composite.addBody(car, body); + Composite.addBody(car, wheelA); + Composite.addBody(car, wheelB); + Composite.addConstraint(car, axelA); + Composite.addConstraint(car, axelB); + + return car; + }; + + deprecated(Composites, 'car', 'Composites.car ➤ moved to car example'); + + /** + * This has now moved to the [softBody example](https://github.com/liabru/matter-js/blob/master/examples/softBody.js) + * and the [cloth example](https://github.com/liabru/matter-js/blob/master/examples/cloth.js), follow those instead as this function is deprecated here. + * @deprecated moved to softBody and cloth examples + * @method softBody + * @param {number} xx + * @param {number} yy + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {boolean} crossBrace + * @param {number} particleRadius + * @param {} particleOptions + * @param {} constraintOptions + * @return {composite} A new composite softBody + */ + Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) { + particleOptions = Common.extend({ inertia: Infinity }, particleOptions); + constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions); + + var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) { + return Bodies.circle(x, y, particleRadius, particleOptions); + }); + + Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions); + + softBody.label = 'Soft Body'; + + return softBody; + }; + + deprecated(Composites, 'softBody', 'Composites.softBody ➤ moved to softBody and cloth examples'); +})(); + + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* This module has now been replaced by `Matter.Detector`. +* +* All usage should be migrated to `Matter.Detector` or another alternative. +* For back-compatibility purposes this module will remain for a short term and then later removed in a future release. +* +* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. +* +* @class Grid +* @deprecated +*/ + +var Grid = {}; + +module.exports = Grid; + +var Pair = __webpack_require__(9); +var Common = __webpack_require__(0); +var deprecated = Common.deprecated; + +(function() { + + /** + * Creates a new grid. + * @deprecated replaced by Matter.Detector + * @method create + * @param {} options + * @return {grid} A new grid + */ + Grid.create = function(options) { + var defaults = { + buckets: {}, + pairs: {}, + pairsList: [], + bucketWidth: 48, + bucketHeight: 48 + }; + + return Common.extend(defaults, options); + }; + + /** + * The width of a single grid bucket. + * + * @property bucketWidth + * @type number + * @default 48 + */ + + /** + * The height of a single grid bucket. + * + * @property bucketHeight + * @type number + * @default 48 + */ + + /** + * Updates the grid. + * @deprecated replaced by Matter.Detector + * @method update + * @param {grid} grid + * @param {body[]} bodies + * @param {engine} engine + * @param {boolean} forceUpdate + */ + Grid.update = function(grid, bodies, engine, forceUpdate) { + var i, col, row, + world = engine.world, + buckets = grid.buckets, + bucket, + bucketId, + gridChanged = false; + + for (i = 0; i < bodies.length; i++) { + var body = bodies[i]; + + if (body.isSleeping && !forceUpdate) + continue; + + // temporary back compatibility bounds check + if (world.bounds && (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x + || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)) + continue; + + var newRegion = Grid._getRegion(grid, body); + + // if the body has changed grid region + if (!body.region || newRegion.id !== body.region.id || forceUpdate) { + + if (!body.region || forceUpdate) + body.region = newRegion; + + var union = Grid._regionUnion(newRegion, body.region); + + // update grid buckets affected by region change + // iterate over the union of both regions + for (col = union.startCol; col <= union.endCol; col++) { + for (row = union.startRow; row <= union.endRow; row++) { + bucketId = Grid._getBucketId(col, row); + bucket = buckets[bucketId]; + + var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol + && row >= newRegion.startRow && row <= newRegion.endRow); + + var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol + && row >= body.region.startRow && row <= body.region.endRow); + + // remove from old region buckets + if (!isInsideNewRegion && isInsideOldRegion) { + if (isInsideOldRegion) { + if (bucket) + Grid._bucketRemoveBody(grid, bucket, body); + } + } + + // add to new region buckets + if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) { + if (!bucket) + bucket = Grid._createBucket(buckets, bucketId); + Grid._bucketAddBody(grid, bucket, body); + } + } + } + + // set the new region + body.region = newRegion; + + // flag changes so we can update pairs + gridChanged = true; + } + } + + // update pairs list only if pairs changed (i.e. a body changed region) + if (gridChanged) + grid.pairsList = Grid._createActivePairsList(grid); + }; + + deprecated(Grid, 'update', 'Grid.update ➤ replaced by Matter.Detector'); + + /** + * Clears the grid. + * @deprecated replaced by Matter.Detector + * @method clear + * @param {grid} grid + */ + Grid.clear = function(grid) { + grid.buckets = {}; + grid.pairs = {}; + grid.pairsList = []; + }; + + deprecated(Grid, 'clear', 'Grid.clear ➤ replaced by Matter.Detector'); + + /** + * Finds the union of two regions. + * @method _regionUnion + * @deprecated replaced by Matter.Detector + * @private + * @param {} regionA + * @param {} regionB + * @return {} region + */ + Grid._regionUnion = function(regionA, regionB) { + var startCol = Math.min(regionA.startCol, regionB.startCol), + endCol = Math.max(regionA.endCol, regionB.endCol), + startRow = Math.min(regionA.startRow, regionB.startRow), + endRow = Math.max(regionA.endRow, regionB.endRow); + + return Grid._createRegion(startCol, endCol, startRow, endRow); + }; + + /** + * Gets the region a given body falls in for a given grid. + * @method _getRegion + * @deprecated replaced by Matter.Detector + * @private + * @param {} grid + * @param {} body + * @return {} region + */ + Grid._getRegion = function(grid, body) { + var bounds = body.bounds, + startCol = Math.floor(bounds.min.x / grid.bucketWidth), + endCol = Math.floor(bounds.max.x / grid.bucketWidth), + startRow = Math.floor(bounds.min.y / grid.bucketHeight), + endRow = Math.floor(bounds.max.y / grid.bucketHeight); + + return Grid._createRegion(startCol, endCol, startRow, endRow); + }; + + /** + * Creates a region. + * @method _createRegion + * @deprecated replaced by Matter.Detector + * @private + * @param {} startCol + * @param {} endCol + * @param {} startRow + * @param {} endRow + * @return {} region + */ + Grid._createRegion = function(startCol, endCol, startRow, endRow) { + return { + id: startCol + ',' + endCol + ',' + startRow + ',' + endRow, + startCol: startCol, + endCol: endCol, + startRow: startRow, + endRow: endRow + }; + }; + + /** + * Gets the bucket id at the given position. + * @method _getBucketId + * @deprecated replaced by Matter.Detector + * @private + * @param {} column + * @param {} row + * @return {string} bucket id + */ + Grid._getBucketId = function(column, row) { + return 'C' + column + 'R' + row; + }; + + /** + * Creates a bucket. + * @method _createBucket + * @deprecated replaced by Matter.Detector + * @private + * @param {} buckets + * @param {} bucketId + * @return {} bucket + */ + Grid._createBucket = function(buckets, bucketId) { + var bucket = buckets[bucketId] = []; + return bucket; + }; + + /** + * Adds a body to a bucket. + * @method _bucketAddBody + * @deprecated replaced by Matter.Detector + * @private + * @param {} grid + * @param {} bucket + * @param {} body + */ + Grid._bucketAddBody = function(grid, bucket, body) { + var gridPairs = grid.pairs, + pairId = Pair.id, + bucketLength = bucket.length, + i; + + // add new pairs + for (i = 0; i < bucketLength; i++) { + var bodyB = bucket[i]; + + if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic)) + continue; + + // keep track of the number of buckets the pair exists in + // important for Grid.update to work + var id = pairId(body, bodyB), + pair = gridPairs[id]; + + if (pair) { + pair[2] += 1; + } else { + gridPairs[id] = [body, bodyB, 1]; + } + } + + // add to bodies (after pairs, otherwise pairs with self) + bucket.push(body); + }; + + /** + * Removes a body from a bucket. + * @method _bucketRemoveBody + * @deprecated replaced by Matter.Detector + * @private + * @param {} grid + * @param {} bucket + * @param {} body + */ + Grid._bucketRemoveBody = function(grid, bucket, body) { + var gridPairs = grid.pairs, + pairId = Pair.id, + i; + + // remove from bucket + bucket.splice(Common.indexOf(bucket, body), 1); + + var bucketLength = bucket.length; + + // update pair counts + for (i = 0; i < bucketLength; i++) { + // keep track of the number of buckets the pair exists in + // important for _createActivePairsList to work + var pair = gridPairs[pairId(body, bucket[i])]; + + if (pair) + pair[2] -= 1; + } + }; + + /** + * Generates a list of the active pairs in the grid. + * @method _createActivePairsList + * @deprecated replaced by Matter.Detector + * @private + * @param {} grid + * @return [] pairs + */ + Grid._createActivePairsList = function(grid) { + var pair, + gridPairs = grid.pairs, + pairKeys = Common.keys(gridPairs), + pairKeysLength = pairKeys.length, + pairs = [], + k; + + // iterate over grid.pairs + for (k = 0; k < pairKeysLength; k++) { + pair = gridPairs[pairKeys[k]]; + + // if pair exists in at least one bucket + // it is a pair that needs further collision testing so push it + if (pair[2] > 0) { + pairs.push(pair); + } else { + delete gridPairs[pairKeys[k]]; + } + } + + return pairs; + }; + +})(); + + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter.MouseConstraint` module contains methods for creating mouse constraints. +* Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class MouseConstraint +*/ + +var MouseConstraint = {}; + +module.exports = MouseConstraint; + +var Vertices = __webpack_require__(3); +var Sleeping = __webpack_require__(7); +var Mouse = __webpack_require__(14); +var Events = __webpack_require__(5); +var Detector = __webpack_require__(13); +var Constraint = __webpack_require__(10); +var Composite = __webpack_require__(6); +var Common = __webpack_require__(0); +var Bounds = __webpack_require__(1); + +(function() { + + /** + * Creates a new mouse constraint. + * 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 {engine} engine + * @param {} options + * @return {MouseConstraint} A new MouseConstraint + */ + MouseConstraint.create = function(engine, options) { + var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null); + + if (!mouse) { + if (engine && engine.render && engine.render.canvas) { + mouse = Mouse.create(engine.render.canvas); + } else if (options && options.element) { + mouse = Mouse.create(options.element); + } else { + mouse = Mouse.create(); + Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected'); + } + } + + var constraint = Constraint.create({ + label: 'Mouse Constraint', + pointA: mouse.position, + pointB: { x: 0, y: 0 }, + length: 0.01, + stiffness: 0.1, + angularStiffness: 1, + render: { + strokeStyle: '#90EE90', + lineWidth: 3 + } + }); + + var defaults = { + type: 'mouseConstraint', + mouse: mouse, + element: null, + body: null, + constraint: constraint, + collisionFilter: { + category: 0x0001, + mask: 0xFFFFFFFF, + group: 0 + } + }; + + var mouseConstraint = Common.extend(defaults, options); + + Events.on(engine, 'beforeUpdate', function() { + var allBodies = Composite.allBodies(engine.world); + MouseConstraint.update(mouseConstraint, allBodies); + MouseConstraint._triggerEvents(mouseConstraint); + }); + + return mouseConstraint; + }; + + /** + * Updates the given mouse constraint. + * @private + * @method update + * @param {MouseConstraint} mouseConstraint + * @param {body[]} bodies + */ + MouseConstraint.update = function(mouseConstraint, bodies) { + var mouse = mouseConstraint.mouse, + constraint = mouseConstraint.constraint, + body = mouseConstraint.body; + + if (mouse.button === 0) { + if (!constraint.bodyB) { + for (var i = 0; i < bodies.length; i++) { + body = bodies[i]; + if (Bounds.contains(body.bounds, mouse.position) + && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) { + for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) { + var part = body.parts[j]; + if (Vertices.contains(part.vertices, mouse.position)) { + constraint.pointA = mouse.position; + constraint.bodyB = mouseConstraint.body = body; + constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y }; + constraint.angleB = body.angle; + + Sleeping.set(body, false); + Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body }); + + break; + } + } + } + } + } else { + Sleeping.set(constraint.bodyB, false); + constraint.pointA = mouse.position; + } + } else { + constraint.bodyB = mouseConstraint.body = null; + constraint.pointB = null; + + if (body) + Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body }); + } + }; + + /** + * Triggers mouse constraint events. + * @method _triggerEvents + * @private + * @param {mouse} mouseConstraint + */ + MouseConstraint._triggerEvents = function(mouseConstraint) { + var mouse = mouseConstraint.mouse, + mouseEvents = mouse.sourceEvents; + + if (mouseEvents.mousemove) + Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse }); + + if (mouseEvents.mousedown) + Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse }); + + if (mouseEvents.mouseup) + Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse }); + + // reset the mouse state ready for the next step + Mouse.clearSourceEvents(mouse); + }; + + /* + * + * Events Documentation + * + */ + + /** + * Fired when the mouse has moved (or a touch moves) during the last step + * + * @event mousemove + * @param {} event An event object + * @param {mouse} event.mouse The engine's mouse instance + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when the mouse is down (or a touch has started) during the last step + * + * @event mousedown + * @param {} event An event object + * @param {mouse} event.mouse The engine's mouse instance + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when the mouse is up (or a touch has ended) during the last step + * + * @event mouseup + * @param {} event An event object + * @param {mouse} event.mouse The engine's mouse instance + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when the user starts dragging a body + * + * @event startdrag + * @param {} event An event object + * @param {mouse} event.mouse The engine's mouse instance + * @param {body} event.body The body being dragged + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when the user ends dragging a body + * + * @event enddrag + * @param {} event An event object + * @param {mouse} event.mouse The engine's mouse instance + * @param {body} event.body The body that has stopped being dragged + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /* + * + * Properties Documentation + * + */ + + /** + * A `String` denoting the type of object. + * + * @property type + * @type string + * @default "constraint" + * @readOnly + */ + + /** + * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created. + * + * @property mouse + * @type mouse + * @default mouse + */ + + /** + * The `Body` that is currently being moved by the user, or `null` if no body. + * + * @property body + * @type body + * @default null + */ + + /** + * The `Constraint` object that is used to move the body during interaction. + * + * @property constraint + * @type constraint + */ + + /** + * An `Object` that specifies the collision filter properties. + * The collision filter allows the user to define which types of body this mouse constraint can interact with. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter + * @type object + */ + +})(); + + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* The `Matter.Query` module contains methods for performing collision queries. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Query +*/ + +var Query = {}; + +module.exports = Query; + +var Vector = __webpack_require__(2); +var Collision = __webpack_require__(8); +var Bounds = __webpack_require__(1); +var Bodies = __webpack_require__(12); +var Vertices = __webpack_require__(3); + +(function() { + + /** + * Returns a list of collisions between `body` and `bodies`. + * @method collides + * @param {body} body + * @param {body[]} bodies + * @return {collision[]} Collisions + */ + Query.collides = function(body, bodies) { + var collisions = [], + bodiesLength = bodies.length, + bounds = body.bounds, + collides = Collision.collides, + overlaps = Bounds.overlaps; + + for (var i = 0; i < bodiesLength; i++) { + var bodyA = bodies[i], + partsALength = bodyA.parts.length, + partsAStart = partsALength === 1 ? 0 : 1; + + if (overlaps(bodyA.bounds, bounds)) { + for (var j = partsAStart; j < partsALength; j++) { + var part = bodyA.parts[j]; + + if (overlaps(part.bounds, bounds)) { + var collision = collides(part, body); + + if (collision) { + collisions.push(collision); + break; + } + } + } + } + } + + return collisions; + }; + + /** + * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided. + * @method ray + * @param {body[]} bodies + * @param {vector} startPoint + * @param {vector} endPoint + * @param {number} [rayWidth] + * @return {collision[]} Collisions + */ + Query.ray = function(bodies, startPoint, endPoint, rayWidth) { + rayWidth = rayWidth || 1e-100; + + var rayAngle = Vector.angle(startPoint, endPoint), + rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)), + rayX = (endPoint.x + startPoint.x) * 0.5, + rayY = (endPoint.y + startPoint.y) * 0.5, + ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }), + collisions = Query.collides(ray, bodies); + + for (var i = 0; i < collisions.length; i += 1) { + var collision = collisions[i]; + collision.body = collision.bodyB = collision.bodyA; + } + + return collisions; + }; + + /** + * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies. + * @method region + * @param {body[]} bodies + * @param {bounds} bounds + * @param {bool} [outside=false] + * @return {body[]} The bodies matching the query + */ + Query.region = function(bodies, bounds, outside) { + var result = []; + + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + overlaps = Bounds.overlaps(body.bounds, bounds); + if ((overlaps && !outside) || (!overlaps && outside)) + result.push(body); + } + + return result; + }; + + /** + * Returns all bodies whose vertices contain the given point, from the given set of bodies. + * @method point + * @param {body[]} bodies + * @param {vector} point + * @return {body[]} The bodies matching the query + */ + Query.point = function(bodies, point) { + var result = []; + + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i]; + + if (Bounds.contains(body.bounds, point)) { + for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) { + var part = body.parts[j]; + + if (Bounds.contains(part.bounds, point) + && Vertices.contains(part.vertices, point)) { + result.push(body); + break; + } + } + } + } + + return result; + }; + +})(); + + +/***/ }), +/* 26 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -6036,12 +8583,13 @@ var Render = {}; module.exports = Render; +var Body = __webpack_require__(4); var Common = __webpack_require__(0); -var Composite = __webpack_require__(5); +var Composite = __webpack_require__(6); var Bounds = __webpack_require__(1); -var Events = __webpack_require__(4); +var Events = __webpack_require__(5); var Vector = __webpack_require__(2); -var Mouse = __webpack_require__(13); +var Mouse = __webpack_require__(14); (function() { @@ -6070,7 +8618,6 @@ var Mouse = __webpack_require__(13); */ Render.create = function(options) { var defaults = { - controller: Render, engine: null, element: null, canvas: null, @@ -6142,6 +8689,7 @@ var Mouse = __webpack_require__(13); }; // for temporary back compatibility only + render.controller = Render; render.options.showBroadphase = false; if (render.options.pixelRatio !== 1) { @@ -6150,8 +8698,6 @@ var Mouse = __webpack_require__(13); if (Common.isElement(render.element)) { render.element.appendChild(render.canvas); - } else if (!render.canvas.parentNode) { - Common.log('Render.create: options.element was undefined, render.canvas was created but not appended', 'warn'); } return render; @@ -7134,8 +9680,10 @@ var Mouse = __webpack_require__(13); if (!body.render.visible) continue; + var velocity = Body.getVelocity(body); + c.moveTo(body.position.x, body.position.y); - c.lineTo(body.position.x + (body.position.x - body.positionPrev.x) * 2, body.position.y + (body.position.y - body.positionPrev.y) * 2); + c.lineTo(body.position.x + velocity.x, body.position.y + velocity.y); } c.lineWidth = 3; @@ -7551,6 +10099,7 @@ var Mouse = __webpack_require__(13); /** * A back-reference to the `Matter.Render` module. * + * @deprecated * @property controller * @type render */ @@ -7856,2298 +10405,6 @@ var Mouse = __webpack_require__(13); })(); -/***/ }), -/* 17 */ -/***/ (function(module, exports) { - -/** -* The `Matter.Contact` module contains methods for creating and manipulating collision contacts. -* -* @class Contact -*/ - -var Contact = {}; - -module.exports = Contact; - -(function() { - - /** - * Creates a new contact. - * @method create - * @param {vertex} vertex - * @return {contact} A new contact - */ - Contact.create = function(vertex) { - return { - vertex: vertex, - normalImpulse: 0, - tangentImpulse: 0 - }; - }; - -})(); - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* 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 Sleeping = __webpack_require__(7); -var Resolver = __webpack_require__(19); -var Detector = __webpack_require__(14); -var Pairs = __webpack_require__(20); -var Events = __webpack_require__(4); -var Composite = __webpack_require__(5); -var Constraint = __webpack_require__(10); -var Common = __webpack_require__(0); -var Body = __webpack_require__(6); - -(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(options) { - options = options || {}; - - var defaults = { - positionIterations: 6, - velocityIterations: 4, - constraintIterations: 2, - enableSleeping: false, - events: [], - plugin: {}, - gravity: { - x: 0, - y: 1, - scale: 0.001 - }, - timing: { - timestamp: 0, - timeScale: 1, - lastDelta: 0, - lastElapsed: 0 - } - }; - - var engine = Common.extend(defaults, options); - - engine.world = options.world || Composite.create({ label: 'World' }); - engine.pairs = options.pairs || Pairs.create(); - engine.detector = options.detector || Detector.create(); - - // for temporary back compatibility only - engine.grid = { buckets: [] }; - engine.world.gravity = engine.gravity; - engine.broadphase = engine.grid; - engine.metrics = {}; - - 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 Time Corrected Verlet 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) { - var startTime = Common.now(); - - delta = delta || 1000 / 60; - correction = correction || 1; - - var world = engine.world, - detector = engine.detector, - pairs = engine.pairs, - timing = engine.timing, - timestamp = timing.timestamp, - i; - - // increment timestamp - timing.timestamp += delta * timing.timeScale; - timing.lastDelta = delta * timing.timeScale; - - // create an event object - var event = { - timestamp: timing.timestamp - }; - - Events.trigger(engine, 'beforeUpdate', event); - - // get all bodies and all constraints in the world - var allBodies = Composite.allBodies(world), - allConstraints = Composite.allConstraints(world); - - // update the detector bodies if they have changed - if (world.isModified) { - Detector.setBodies(detector, allBodies); - } - - // reset all composite modified flags - if (world.isModified) { - Composite.setModified(world, false, false, true); - } - - // update sleeping if enabled - if (engine.enableSleeping) - Sleeping.update(allBodies, timing.timeScale); - - // apply gravity to all bodies - Engine._bodiesApplyGravity(allBodies, engine.gravity); - - // update all body position and rotation by integration - Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds); - - // update all constraints (first pass) - Constraint.preSolveAll(allBodies); - for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); - } - Constraint.postSolveAll(allBodies); - - // find all collisions - detector.pairs = engine.pairs; - var collisions = Detector.collisions(detector); - - // update collision pairs - Pairs.update(pairs, collisions, 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); - - // update all constraints (second pass) - Constraint.preSolveAll(allBodies); - for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); - } - Constraint.postSolveAll(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 }); - - // clear force buffers - Engine._bodiesClearForces(allBodies); - - Events.trigger(engine, 'afterUpdate', event); - - // log the time elapsed computing this update - engine.timing.lastElapsed = Common.now() - startTime; - - 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 pairs and detector. - * @method clear - * @param {engine} engine - */ - Engine.clear = function(engine) { - Pairs.clear(engine.pairs); - Detector.clear(engine.detector); - }; - - /** - * Zeroes the `body.force` and `body.torque` force buffers. - * @method _bodiesClearForces - * @private - * @param {body[]} bodies - */ - Engine._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 - */ - Engine._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 _bodiesUpdate - * @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 - */ - Engine._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); - } - }; - - /** - * A deprecated alias for `Runner.run`, use `Matter.Runner.run(engine)` instead and see `Matter.Runner` for more information. - * @deprecated use Matter.Runner.run(engine) instead - * @method run - * @param {engine} engine - */ - - /** - * Fired just before an update - * - * @event beforeUpdate - * @param {object} event An event object - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {engine} event.source The source object of the event - * @param {string} event.name The name of the event - */ - - /** - * Fired after engine update and all collision events - * - * @event afterUpdate - * @param {object} event An event object - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {engine} event.source The source object of the event - * @param {string} 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 {object} event An event object - * @param {pair[]} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {engine} event.source The source object of the event - * @param {string} 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 {object} event An event object - * @param {pair[]} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {engine} event.source The source object of the event - * @param {string} 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 {object} event An event object - * @param {pair[]} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {engine} event.source The source object of the event - * @param {string} 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 - */ - - /** - * A `Number` that represents the total execution time elapsed during the last `Engine.update` in milliseconds. - * It is updated by timing from the start of the last `Engine.update` call until it ends. - * - * This value will also include the total execution time of all event handlers directly or indirectly triggered by the engine update. - * - * @property timing.lastElapsed - * @type number - * @default 0 - */ - - /** - * A `Number` that represents the `delta` value used in the last engine update. - * - * @property timing.lastDelta - * @type number - * @default 0 - */ - - /** - * A `Matter.Detector` instance. - * - * @property detector - * @type detector - * @default a Matter.Detector instance - */ - - /** - * A `Matter.Grid` instance. - * - * @deprecated replaced by `engine.detector` - * @property grid - * @type grid - * @default a Matter.Grid instance - */ - - /** - * Replaced by and now alias for `engine.grid`. - * - * @deprecated replaced by `engine.detector` - * @property broadphase - * @type grid - * @default a Matter.Grid instance - */ - - /** - * The root `Matter.Composite` instance that will contain all bodies, constraints and other composites to be simulated by this engine. - * - * @property world - * @type composite - * @default a Matter.Composite instance - */ - - /** - * An object reserved for storing plugin-specific properties. - * - * @property plugin - * @type {} - */ - - /** - * The gravity to apply on all bodies in `engine.world`. - * - * @property gravity - * @type object - */ - - /** - * The gravity x component. - * - * @property gravity.x - * @type object - * @default 0 - */ - - /** - * The gravity y component. - * - * @property gravity.y - * @type object - * @default 1 - */ - - /** - * The gravity scale factor. - * - * @property gravity.scale - * @type object - * @default 0.001 - */ - -})(); - - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Resolver` module contains methods for resolving collision pairs. -* -* @class Resolver -*/ - -var Resolver = {}; - -module.exports = Resolver; - -var Vertices = __webpack_require__(3); -var Bounds = __webpack_require__(1); - -(function() { - - Resolver._restingThresh = 4; - Resolver._restingThreshTangent = 6; - Resolver._positionDampen = 0.9; - Resolver._positionWarming = 0.8; - Resolver._frictionNormalMultiplier = 5; - - /** - * Prepare pairs for position solving. - * @method preSolvePosition - * @param {pair[]} pairs - */ - Resolver.preSolvePosition = function(pairs) { - var i, - pair, - activeCount, - pairsLength = pairs.length; - - // find total contacts on each body - for (i = 0; i < pairsLength; i++) { - pair = pairs[i]; - - if (!pair.isActive) - continue; - - activeCount = pair.activeContacts.length; - pair.collision.parentA.totalContacts += activeCount; - pair.collision.parentB.totalContacts += activeCount; - } - }; - - /** - * Find a solution for pair positions. - * @method solvePosition - * @param {pair[]} pairs - * @param {number} timeScale - */ - Resolver.solvePosition = function(pairs, timeScale) { - var i, - pair, - collision, - bodyA, - bodyB, - normal, - contactShare, - positionImpulse, - positionDampen = Resolver._positionDampen, - pairsLength = pairs.length; - - // find impulses required to resolve penetration - for (i = 0; i < pairsLength; i++) { - pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - collision = pair.collision; - bodyA = collision.parentA; - bodyB = collision.parentB; - normal = collision.normal; - - // get current separation between body edges involved in collision - pair.separation = - normal.x * (bodyB.positionImpulse.x + collision.penetration.x - bodyA.positionImpulse.x) - + normal.y * (bodyB.positionImpulse.y + collision.penetration.y - bodyA.positionImpulse.y); - } - - for (i = 0; i < pairsLength; i++) { - pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - collision = pair.collision; - bodyA = collision.parentA; - bodyB = collision.parentB; - normal = collision.normal; - positionImpulse = (pair.separation - pair.slop) * timeScale; - - if (bodyA.isStatic || bodyB.isStatic) - positionImpulse *= 2; - - if (!(bodyA.isStatic || bodyA.isSleeping)) { - contactShare = positionDampen / bodyA.totalContacts; - bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare; - bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare; - } - - if (!(bodyB.isStatic || bodyB.isSleeping)) { - contactShare = positionDampen / bodyB.totalContacts; - bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare; - bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare; - } - } - }; - - /** - * Apply position resolution. - * @method postSolvePosition - * @param {body[]} bodies - */ - Resolver.postSolvePosition = function(bodies) { - var positionWarming = Resolver._positionWarming, - bodiesLength = bodies.length, - verticesTranslate = Vertices.translate, - boundsUpdate = Bounds.update; - - for (var i = 0; i < bodiesLength; i++) { - var body = bodies[i], - positionImpulse = body.positionImpulse, - positionImpulseX = positionImpulse.x, - positionImpulseY = positionImpulse.y, - velocity = body.velocity; - - // reset contact count - body.totalContacts = 0; - - if (positionImpulseX !== 0 || positionImpulseY !== 0) { - // update body geometry - for (var j = 0; j < body.parts.length; j++) { - var part = body.parts[j]; - verticesTranslate(part.vertices, positionImpulse); - boundsUpdate(part.bounds, part.vertices, velocity); - part.position.x += positionImpulseX; - part.position.y += positionImpulseY; - } - - // move the body without changing velocity - body.positionPrev.x += positionImpulseX; - body.positionPrev.y += positionImpulseY; - - if (positionImpulseX * velocity.x + positionImpulseY * velocity.y < 0) { - // reset cached impulse if the body has velocity along it - positionImpulse.x = 0; - positionImpulse.y = 0; - } else { - // warm the next iteration - positionImpulse.x *= positionWarming; - positionImpulse.y *= positionWarming; - } - } - } - }; - - /** - * Prepare pairs for velocity solving. - * @method preSolveVelocity - * @param {pair[]} pairs - */ - Resolver.preSolveVelocity = function(pairs) { - var pairsLength = pairs.length, - i, - j; - - for (i = 0; i < pairsLength; i++) { - var pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - var contacts = pair.activeContacts, - contactsLength = contacts.length, - collision = pair.collision, - bodyA = collision.parentA, - bodyB = collision.parentB, - normal = collision.normal, - tangent = collision.tangent; - - // resolve each contact - for (j = 0; j < contactsLength; j++) { - var contact = contacts[j], - contactVertex = contact.vertex, - normalImpulse = contact.normalImpulse, - tangentImpulse = contact.tangentImpulse; - - if (normalImpulse !== 0 || tangentImpulse !== 0) { - // total impulse from contact - var impulseX = normal.x * normalImpulse + tangent.x * tangentImpulse, - impulseY = normal.y * normalImpulse + tangent.y * tangentImpulse; - - // apply impulse from contact - if (!(bodyA.isStatic || bodyA.isSleeping)) { - bodyA.positionPrev.x += impulseX * bodyA.inverseMass; - bodyA.positionPrev.y += impulseY * bodyA.inverseMass; - bodyA.anglePrev += bodyA.inverseInertia * ( - (contactVertex.x - bodyA.position.x) * impulseY - - (contactVertex.y - bodyA.position.y) * impulseX - ); - } - - if (!(bodyB.isStatic || bodyB.isSleeping)) { - bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; - bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; - bodyB.anglePrev -= bodyB.inverseInertia * ( - (contactVertex.x - bodyB.position.x) * impulseY - - (contactVertex.y - bodyB.position.y) * impulseX - ); - } - } - } - } - }; - - /** - * Find a solution for pair velocities. - * @method solveVelocity - * @param {pair[]} pairs - * @param {number} timeScale - */ - Resolver.solveVelocity = function(pairs, timeScale) { - var timeScaleSquared = timeScale * timeScale, - restingThresh = Resolver._restingThresh * timeScaleSquared, - frictionNormalMultiplier = Resolver._frictionNormalMultiplier, - restingThreshTangent = Resolver._restingThreshTangent * timeScaleSquared, - NumberMaxValue = Number.MAX_VALUE, - pairsLength = pairs.length, - tangentImpulse, - maxFriction, - i, - j; - - for (i = 0; i < pairsLength; i++) { - var pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - var collision = pair.collision, - bodyA = collision.parentA, - bodyB = collision.parentB, - bodyAVelocity = bodyA.velocity, - bodyBVelocity = bodyB.velocity, - normalX = collision.normal.x, - normalY = collision.normal.y, - tangentX = collision.tangent.x, - tangentY = collision.tangent.y, - contacts = pair.activeContacts, - contactsLength = contacts.length, - contactShare = 1 / contactsLength, - inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, - friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScaleSquared; - - // update body velocities - bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x; - bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y; - bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x; - bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y; - bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; - bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; - - // resolve each contact - for (j = 0; j < contactsLength; j++) { - var contact = contacts[j], - contactVertex = contact.vertex; - - var offsetAX = contactVertex.x - bodyA.position.x, - offsetAY = contactVertex.y - bodyA.position.y, - offsetBX = contactVertex.x - bodyB.position.x, - offsetBY = contactVertex.y - bodyB.position.y; - - var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity, - velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity, - velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity, - velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity; - - var relativeVelocityX = velocityPointAX - velocityPointBX, - relativeVelocityY = velocityPointAY - velocityPointBY; - - var normalVelocity = normalX * relativeVelocityX + normalY * relativeVelocityY, - tangentVelocity = tangentX * relativeVelocityX + tangentY * relativeVelocityY; - - // coulomb friction - var normalOverlap = pair.separation + normalVelocity; - var normalForce = Math.min(normalOverlap, 1); - normalForce = normalOverlap < 0 ? 0 : normalForce; - - var frictionLimit = normalForce * friction; - - if (tangentVelocity > frictionLimit || -tangentVelocity > frictionLimit) { - maxFriction = tangentVelocity > 0 ? tangentVelocity : -tangentVelocity; - tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleSquared; - - if (tangentImpulse < -maxFriction) { - tangentImpulse = -maxFriction; - } else if (tangentImpulse > maxFriction) { - tangentImpulse = maxFriction; - } - } else { - tangentImpulse = tangentVelocity; - maxFriction = NumberMaxValue; - } - - // account for mass, inertia and contact offset - var oAcN = offsetAX * normalY - offsetAY * normalX, - oBcN = offsetBX * normalY - offsetBY * normalX, - share = contactShare / (inverseMassTotal + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN); - - // raw impulses - var normalImpulse = (1 + pair.restitution) * normalVelocity * share; - tangentImpulse *= share; - - // handle high velocity and resting collisions separately - if (normalVelocity * normalVelocity > restingThresh && normalVelocity < 0) { - // high normal velocity so clear cached contact normal impulse - contact.normalImpulse = 0; - } else { - // solve resting collision constraints using Erin Catto's method (GDC08) - // impulse constraint tends to 0 - var contactNormalImpulse = contact.normalImpulse; - contact.normalImpulse += normalImpulse; - contact.normalImpulse = Math.min(contact.normalImpulse, 0); - normalImpulse = contact.normalImpulse - contactNormalImpulse; - } - - // handle high velocity and resting collisions separately - if (tangentVelocity * tangentVelocity > restingThreshTangent) { - // high tangent velocity so clear cached contact tangent impulse - contact.tangentImpulse = 0; - } else { - // solve resting collision constraints using Erin Catto's method (GDC08) - // tangent impulse tends to -tangentSpeed or +tangentSpeed - var contactTangentImpulse = contact.tangentImpulse; - contact.tangentImpulse += tangentImpulse; - if (contact.tangentImpulse < -maxFriction) contact.tangentImpulse = -maxFriction; - if (contact.tangentImpulse > maxFriction) contact.tangentImpulse = maxFriction; - tangentImpulse = contact.tangentImpulse - contactTangentImpulse; - } - - // total impulse from contact - var impulseX = normalX * normalImpulse + tangentX * tangentImpulse, - impulseY = normalY * normalImpulse + tangentY * tangentImpulse; - - // apply impulse from contact - if (!(bodyA.isStatic || bodyA.isSleeping)) { - bodyA.positionPrev.x += impulseX * bodyA.inverseMass; - bodyA.positionPrev.y += impulseY * bodyA.inverseMass; - bodyA.anglePrev += (offsetAX * impulseY - offsetAY * impulseX) * bodyA.inverseInertia; - } - - if (!(bodyB.isStatic || bodyB.isSleeping)) { - bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; - bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; - bodyB.anglePrev -= (offsetBX * impulseY - offsetBY * impulseX) * bodyB.inverseInertia; - } - } - } - }; - -})(); - - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. -* -* @class Pairs -*/ - -var Pairs = {}; - -module.exports = Pairs; - -var Pair = __webpack_require__(9); -var Common = __webpack_require__(0); - -(function() { - - /** - * Creates a new pairs structure. - * @method create - * @param {object} options - * @return {pairs} A new pairs structure - */ - Pairs.create = function(options) { - return Common.extend({ - table: {}, - list: [], - collisionStart: [], - collisionActive: [], - collisionEnd: [] - }, options); - }; - - /** - * Updates pairs given a list of collisions. - * @method update - * @param {object} pairs - * @param {collision[]} collisions - * @param {number} timestamp - */ - Pairs.update = function(pairs, collisions, timestamp) { - var pairsList = pairs.list, - pairsListLength = pairsList.length, - pairsTable = pairs.table, - collisionsLength = collisions.length, - collisionStart = pairs.collisionStart, - collisionEnd = pairs.collisionEnd, - collisionActive = pairs.collisionActive, - collision, - pairIndex, - pair, - i; - - // clear collision state arrays, but maintain old reference - collisionStart.length = 0; - collisionEnd.length = 0; - collisionActive.length = 0; - - for (i = 0; i < pairsListLength; i++) { - pairsList[i].confirmedActive = false; - } - - for (i = 0; i < collisionsLength; i++) { - collision = collisions[i]; - pair = collision.pair; - - if (pair) { - // pair already exists (but may or may not be active) - if (pair.isActive) { - // pair exists and is active - collisionActive.push(pair); - } else { - // pair exists but was inactive, so a collision has just started again - collisionStart.push(pair); - } - - // update the pair - Pair.update(pair, collision, timestamp); - pair.confirmedActive = true; - } else { - // pair did not exist, create a new pair - pair = Pair.create(collision, timestamp); - pairsTable[pair.id] = pair; - - // push the new pair - collisionStart.push(pair); - pairsList.push(pair); - } - } - - // find pairs that are no longer active - var removePairIndex = []; - pairsListLength = pairsList.length; - - for (i = 0; i < pairsListLength; i++) { - pair = pairsList[i]; - - if (!pair.confirmedActive) { - Pair.setActive(pair, false, timestamp); - collisionEnd.push(pair); - - if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) { - removePairIndex.push(i); - } - } - } - - // remove inactive pairs - for (i = 0; i < removePairIndex.length; i++) { - pairIndex = removePairIndex[i] - i; - pair = pairsList[pairIndex]; - pairsList.splice(pairIndex, 1); - delete pairsTable[pair.id]; - } - }; - - /** - * Clears the given pairs structure. - * @method clear - * @param {pairs} pairs - * @return {pairs} pairs - */ - Pairs.clear = function(pairs) { - pairs.table = {}; - pairs.list.length = 0; - pairs.collisionStart.length = 0; - pairs.collisionActive.length = 0; - pairs.collisionEnd.length = 0; - return pairs; - }; - -})(); - - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -var Matter = module.exports = __webpack_require__(22); - -Matter.Axes = __webpack_require__(11); -Matter.Bodies = __webpack_require__(12); -Matter.Body = __webpack_require__(6); -Matter.Bounds = __webpack_require__(1); -Matter.Collision = __webpack_require__(8); -Matter.Common = __webpack_require__(0); -Matter.Composite = __webpack_require__(5); -Matter.Composites = __webpack_require__(23); -Matter.Constraint = __webpack_require__(10); -Matter.Contact = __webpack_require__(17); -Matter.Detector = __webpack_require__(14); -Matter.Engine = __webpack_require__(18); -Matter.Events = __webpack_require__(4); -Matter.Grid = __webpack_require__(24); -Matter.Mouse = __webpack_require__(13); -Matter.MouseConstraint = __webpack_require__(25); -Matter.Pair = __webpack_require__(9); -Matter.Pairs = __webpack_require__(20); -Matter.Plugin = __webpack_require__(15); -Matter.Query = __webpack_require__(26); -Matter.Render = __webpack_require__(16); -Matter.Resolver = __webpack_require__(19); -Matter.Runner = __webpack_require__(27); -Matter.SAT = __webpack_require__(28); -Matter.Sleeping = __webpack_require__(7); -Matter.Svg = __webpack_require__(29); -Matter.Vector = __webpack_require__(2); -Matter.Vertices = __webpack_require__(3); -Matter.World = __webpack_require__(30); - -// temporary back compatibility -Matter.Engine.run = Matter.Runner.run; -Matter.Common.deprecated(Matter.Engine, 'run', 'Engine.run ➤ use Matter.Runner.run(engine) instead'); - - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library. -* -* @class Matter -*/ - -var Matter = {}; - -module.exports = Matter; - -var Plugin = __webpack_require__(15); -var Common = __webpack_require__(0); - -(function() { - - /** - * The library name. - * @property name - * @readOnly - * @type {String} - */ - Matter.name = 'matter-js'; - - /** - * The library version. - * @property version - * @readOnly - * @type {String} - */ - Matter.version = true ? "0.18.0" : undefined; - - /** - * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`. - * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`. - * @property uses - * @type {Array} - */ - Matter.uses = []; - - /** - * The plugins that have been installed through `Matter.Plugin.install`. Read only. - * @property used - * @readOnly - * @type {Array} - */ - Matter.used = []; - - /** - * Installs the given plugins on the `Matter` namespace. - * This is a short-hand for `Plugin.use`, see it for more information. - * Call this function once at the start of your code, with all of the plugins you wish to install as arguments. - * Avoid calling this function multiple times unless you intend to manually control installation order. - * @method use - * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument). - */ - Matter.use = function() { - Plugin.use(Matter, Array.prototype.slice.call(arguments)); - }; - - /** - * Chains a function to excute before the original function on the given `path` relative to `Matter`. - * See also docs for `Common.chain`. - * @method before - * @param {string} path The path relative to `Matter` - * @param {function} func The function to chain before the original - * @return {function} The chained function that replaced the original - */ - Matter.before = function(path, func) { - path = path.replace(/^Matter./, ''); - return Common.chainPathBefore(Matter, path, func); - }; - - /** - * Chains a function to excute after the original function on the given `path` relative to `Matter`. - * See also docs for `Common.chain`. - * @method after - * @param {string} path The path relative to `Matter` - * @param {function} func The function to chain after the original - * @return {function} The chained function that replaced the original - */ - Matter.after = function(path, func) { - path = path.replace(/^Matter./, ''); - return Common.chainPathAfter(Matter, path, func); - }; - -})(); - - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Composites` module contains factory methods for creating composite bodies -* with commonly used configurations (such as stacks and chains). -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Composites -*/ - -var Composites = {}; - -module.exports = Composites; - -var Composite = __webpack_require__(5); -var Constraint = __webpack_require__(10); -var Common = __webpack_require__(0); -var Body = __webpack_require__(6); -var Bodies = __webpack_require__(12); -var deprecated = Common.deprecated; - -(function() { - - /** - * Create a new composite containing bodies created in the callback in a grid arrangement. - * This function uses the body's bounds to prevent overlaps. - * @method stack - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {function} callback - * @return {composite} A new composite containing objects created in the callback - */ - Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) { - var stack = Composite.create({ label: 'Stack' }), - x = xx, - y = yy, - lastBody, - i = 0; - - for (var row = 0; row < rows; row++) { - var maxHeight = 0; - - for (var column = 0; column < columns; column++) { - var body = callback(x, y, column, row, lastBody, i); - - if (body) { - var bodyHeight = body.bounds.max.y - body.bounds.min.y, - bodyWidth = body.bounds.max.x - body.bounds.min.x; - - if (bodyHeight > maxHeight) - maxHeight = bodyHeight; - - Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 }); - - x = body.bounds.max.x + columnGap; - - Composite.addBody(stack, body); - - lastBody = body; - i += 1; - } else { - x += columnGap; - } - } - - y += maxHeight + rowGap; - x = xx; - } - - return stack; - }; - - /** - * Chains all bodies in the given composite together using constraints. - * @method chain - * @param {composite} composite - * @param {number} xOffsetA - * @param {number} yOffsetA - * @param {number} xOffsetB - * @param {number} yOffsetB - * @param {object} options - * @return {composite} A new composite containing objects chained together with constraints - */ - Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) { - var bodies = composite.bodies; - - for (var i = 1; i < bodies.length; i++) { - var bodyA = bodies[i - 1], - bodyB = bodies[i], - bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y, - bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, - bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y, - bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x; - - var defaults = { - bodyA: bodyA, - pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA }, - bodyB: bodyB, - pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB } - }; - - var constraint = Common.extend(defaults, options); - - Composite.addConstraint(composite, Constraint.create(constraint)); - } - - composite.label += ' Chain'; - - return composite; - }; - - /** - * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. - * @method mesh - * @param {composite} composite - * @param {number} columns - * @param {number} rows - * @param {boolean} crossBrace - * @param {object} options - * @return {composite} The composite containing objects meshed together with constraints - */ - Composites.mesh = function(composite, columns, rows, crossBrace, options) { - var bodies = composite.bodies, - row, - col, - bodyA, - bodyB, - bodyC; - - for (row = 0; row < rows; row++) { - for (col = 1; col < columns; col++) { - bodyA = bodies[(col - 1) + (row * columns)]; - bodyB = bodies[col + (row * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); - } - - if (row > 0) { - for (col = 0; col < columns; col++) { - bodyA = bodies[col + ((row - 1) * columns)]; - bodyB = bodies[col + (row * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); - - if (crossBrace && col > 0) { - bodyC = bodies[(col - 1) + ((row - 1) * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); - } - - if (crossBrace && col < columns - 1) { - bodyC = bodies[(col + 1) + ((row - 1) * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); - } - } - } - } - - composite.label += ' Mesh'; - - return composite; - }; - - /** - * Create a new composite containing bodies created in the callback in a pyramid arrangement. - * This function uses the body's bounds to prevent overlaps. - * @method pyramid - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {function} callback - * @return {composite} A new composite containing objects created in the callback - */ - Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) { - return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) { - var actualRows = Math.min(rows, Math.ceil(columns / 2)), - lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0; - - if (row > actualRows) - return; - - // reverse row order - row = actualRows - row; - - var start = row, - end = columns - 1 - row; - - if (column < start || column > end) - return; - - // retroactively fix the first body's position, since width was unknown - if (i === 1) { - Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 }); - } - - var xOffset = lastBody ? column * lastBodyWidth : 0; - - return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i); - }); - }; - - /** - * This has now moved to the [newtonsCradle example](https://github.com/liabru/matter-js/blob/master/examples/newtonsCradle.js), follow that instead as this function is deprecated here. - * @deprecated moved to newtonsCradle example - * @method newtonsCradle - * @param {number} xx - * @param {number} yy - * @param {number} number - * @param {number} size - * @param {number} length - * @return {composite} A new composite newtonsCradle body - */ - Composites.newtonsCradle = function(xx, yy, number, size, length) { - var newtonsCradle = Composite.create({ label: 'Newtons Cradle' }); - - for (var i = 0; i < number; i++) { - var separation = 1.9, - circle = Bodies.circle(xx + i * (size * separation), yy + length, size, - { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }), - constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle }); - - Composite.addBody(newtonsCradle, circle); - Composite.addConstraint(newtonsCradle, constraint); - } - - return newtonsCradle; - }; - - deprecated(Composites, 'newtonsCradle', 'Composites.newtonsCradle ➤ moved to newtonsCradle example'); - - /** - * This has now moved to the [car example](https://github.com/liabru/matter-js/blob/master/examples/car.js), follow that instead as this function is deprecated here. - * @deprecated moved to car example - * @method car - * @param {number} xx - * @param {number} yy - * @param {number} width - * @param {number} height - * @param {number} wheelSize - * @return {composite} A new composite car body - */ - Composites.car = function(xx, yy, width, height, wheelSize) { - var group = Body.nextGroup(true), - wheelBase = 20, - wheelAOffset = -width * 0.5 + wheelBase, - wheelBOffset = width * 0.5 - wheelBase, - wheelYOffset = 0; - - var car = Composite.create({ label: 'Car' }), - body = Bodies.rectangle(xx, yy, width, height, { - collisionFilter: { - group: group - }, - chamfer: { - radius: height * 0.5 - }, - density: 0.0002 - }); - - var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { - collisionFilter: { - group: group - }, - friction: 0.8 - }); - - var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { - collisionFilter: { - group: group - }, - friction: 0.8 - }); - - var axelA = Constraint.create({ - bodyB: body, - pointB: { x: wheelAOffset, y: wheelYOffset }, - bodyA: wheelA, - stiffness: 1, - length: 0 - }); - - var axelB = Constraint.create({ - bodyB: body, - pointB: { x: wheelBOffset, y: wheelYOffset }, - bodyA: wheelB, - stiffness: 1, - length: 0 - }); - - Composite.addBody(car, body); - Composite.addBody(car, wheelA); - Composite.addBody(car, wheelB); - Composite.addConstraint(car, axelA); - Composite.addConstraint(car, axelB); - - return car; - }; - - deprecated(Composites, 'car', 'Composites.car ➤ moved to car example'); - - /** - * This has now moved to the [softBody example](https://github.com/liabru/matter-js/blob/master/examples/softBody.js) - * and the [cloth example](https://github.com/liabru/matter-js/blob/master/examples/cloth.js), follow those instead as this function is deprecated here. - * @deprecated moved to softBody and cloth examples - * @method softBody - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {boolean} crossBrace - * @param {number} particleRadius - * @param {} particleOptions - * @param {} constraintOptions - * @return {composite} A new composite softBody - */ - Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) { - particleOptions = Common.extend({ inertia: Infinity }, particleOptions); - constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions); - - var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) { - return Bodies.circle(x, y, particleRadius, particleOptions); - }); - - Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions); - - softBody.label = 'Soft Body'; - - return softBody; - }; - - deprecated(Composites, 'softBody', 'Composites.softBody ➤ moved to softBody and cloth examples'); -})(); - - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* This module has now been replaced by `Matter.Detector`. -* -* All usage should be migrated to `Matter.Detector` or another alternative. -* For back-compatibility purposes this module will remain for a short term and then later removed in a future release. -* -* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. -* -* @class Grid -* @deprecated -*/ - -var Grid = {}; - -module.exports = Grid; - -var Pair = __webpack_require__(9); -var Common = __webpack_require__(0); -var deprecated = Common.deprecated; - -(function() { - - /** - * Creates a new grid. - * @deprecated replaced by Matter.Detector - * @method create - * @param {} options - * @return {grid} A new grid - */ - Grid.create = function(options) { - var defaults = { - buckets: {}, - pairs: {}, - pairsList: [], - bucketWidth: 48, - bucketHeight: 48 - }; - - return Common.extend(defaults, options); - }; - - /** - * The width of a single grid bucket. - * - * @property bucketWidth - * @type number - * @default 48 - */ - - /** - * The height of a single grid bucket. - * - * @property bucketHeight - * @type number - * @default 48 - */ - - /** - * Updates the grid. - * @deprecated replaced by Matter.Detector - * @method update - * @param {grid} grid - * @param {body[]} bodies - * @param {engine} engine - * @param {boolean} forceUpdate - */ - Grid.update = function(grid, bodies, engine, forceUpdate) { - var i, col, row, - world = engine.world, - buckets = grid.buckets, - bucket, - bucketId, - gridChanged = false; - - for (i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - if (body.isSleeping && !forceUpdate) - continue; - - // temporary back compatibility bounds check - if (world.bounds && (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x - || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)) - continue; - - var newRegion = Grid._getRegion(grid, body); - - // if the body has changed grid region - if (!body.region || newRegion.id !== body.region.id || forceUpdate) { - - if (!body.region || forceUpdate) - body.region = newRegion; - - var union = Grid._regionUnion(newRegion, body.region); - - // update grid buckets affected by region change - // iterate over the union of both regions - for (col = union.startCol; col <= union.endCol; col++) { - for (row = union.startRow; row <= union.endRow; row++) { - bucketId = Grid._getBucketId(col, row); - bucket = buckets[bucketId]; - - var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol - && row >= newRegion.startRow && row <= newRegion.endRow); - - var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol - && row >= body.region.startRow && row <= body.region.endRow); - - // remove from old region buckets - if (!isInsideNewRegion && isInsideOldRegion) { - if (isInsideOldRegion) { - if (bucket) - Grid._bucketRemoveBody(grid, bucket, body); - } - } - - // add to new region buckets - if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) { - if (!bucket) - bucket = Grid._createBucket(buckets, bucketId); - Grid._bucketAddBody(grid, bucket, body); - } - } - } - - // set the new region - body.region = newRegion; - - // flag changes so we can update pairs - gridChanged = true; - } - } - - // update pairs list only if pairs changed (i.e. a body changed region) - if (gridChanged) - grid.pairsList = Grid._createActivePairsList(grid); - }; - - deprecated(Grid, 'update', 'Grid.update ➤ replaced by Matter.Detector'); - - /** - * Clears the grid. - * @deprecated replaced by Matter.Detector - * @method clear - * @param {grid} grid - */ - Grid.clear = function(grid) { - grid.buckets = {}; - grid.pairs = {}; - grid.pairsList = []; - }; - - deprecated(Grid, 'clear', 'Grid.clear ➤ replaced by Matter.Detector'); - - /** - * Finds the union of two regions. - * @method _regionUnion - * @deprecated replaced by Matter.Detector - * @private - * @param {} regionA - * @param {} regionB - * @return {} region - */ - Grid._regionUnion = function(regionA, regionB) { - var startCol = Math.min(regionA.startCol, regionB.startCol), - endCol = Math.max(regionA.endCol, regionB.endCol), - startRow = Math.min(regionA.startRow, regionB.startRow), - endRow = Math.max(regionA.endRow, regionB.endRow); - - return Grid._createRegion(startCol, endCol, startRow, endRow); - }; - - /** - * Gets the region a given body falls in for a given grid. - * @method _getRegion - * @deprecated replaced by Matter.Detector - * @private - * @param {} grid - * @param {} body - * @return {} region - */ - Grid._getRegion = function(grid, body) { - var bounds = body.bounds, - startCol = Math.floor(bounds.min.x / grid.bucketWidth), - endCol = Math.floor(bounds.max.x / grid.bucketWidth), - startRow = Math.floor(bounds.min.y / grid.bucketHeight), - endRow = Math.floor(bounds.max.y / grid.bucketHeight); - - return Grid._createRegion(startCol, endCol, startRow, endRow); - }; - - /** - * Creates a region. - * @method _createRegion - * @deprecated replaced by Matter.Detector - * @private - * @param {} startCol - * @param {} endCol - * @param {} startRow - * @param {} endRow - * @return {} region - */ - Grid._createRegion = function(startCol, endCol, startRow, endRow) { - return { - id: startCol + ',' + endCol + ',' + startRow + ',' + endRow, - startCol: startCol, - endCol: endCol, - startRow: startRow, - endRow: endRow - }; - }; - - /** - * Gets the bucket id at the given position. - * @method _getBucketId - * @deprecated replaced by Matter.Detector - * @private - * @param {} column - * @param {} row - * @return {string} bucket id - */ - Grid._getBucketId = function(column, row) { - return 'C' + column + 'R' + row; - }; - - /** - * Creates a bucket. - * @method _createBucket - * @deprecated replaced by Matter.Detector - * @private - * @param {} buckets - * @param {} bucketId - * @return {} bucket - */ - Grid._createBucket = function(buckets, bucketId) { - var bucket = buckets[bucketId] = []; - return bucket; - }; - - /** - * Adds a body to a bucket. - * @method _bucketAddBody - * @deprecated replaced by Matter.Detector - * @private - * @param {} grid - * @param {} bucket - * @param {} body - */ - Grid._bucketAddBody = function(grid, bucket, body) { - var gridPairs = grid.pairs, - pairId = Pair.id, - bucketLength = bucket.length, - i; - - // add new pairs - for (i = 0; i < bucketLength; i++) { - var bodyB = bucket[i]; - - if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic)) - continue; - - // keep track of the number of buckets the pair exists in - // important for Grid.update to work - var id = pairId(body, bodyB), - pair = gridPairs[id]; - - if (pair) { - pair[2] += 1; - } else { - gridPairs[id] = [body, bodyB, 1]; - } - } - - // add to bodies (after pairs, otherwise pairs with self) - bucket.push(body); - }; - - /** - * Removes a body from a bucket. - * @method _bucketRemoveBody - * @deprecated replaced by Matter.Detector - * @private - * @param {} grid - * @param {} bucket - * @param {} body - */ - Grid._bucketRemoveBody = function(grid, bucket, body) { - var gridPairs = grid.pairs, - pairId = Pair.id, - i; - - // remove from bucket - bucket.splice(Common.indexOf(bucket, body), 1); - - var bucketLength = bucket.length; - - // update pair counts - for (i = 0; i < bucketLength; i++) { - // keep track of the number of buckets the pair exists in - // important for _createActivePairsList to work - var pair = gridPairs[pairId(body, bucket[i])]; - - if (pair) - pair[2] -= 1; - } - }; - - /** - * Generates a list of the active pairs in the grid. - * @method _createActivePairsList - * @deprecated replaced by Matter.Detector - * @private - * @param {} grid - * @return [] pairs - */ - Grid._createActivePairsList = function(grid) { - var pair, - gridPairs = grid.pairs, - pairKeys = Common.keys(gridPairs), - pairKeysLength = pairKeys.length, - pairs = [], - k; - - // iterate over grid.pairs - for (k = 0; k < pairKeysLength; k++) { - pair = gridPairs[pairKeys[k]]; - - // if pair exists in at least one bucket - // it is a pair that needs further collision testing so push it - if (pair[2] > 0) { - pairs.push(pair); - } else { - delete gridPairs[pairKeys[k]]; - } - } - - return pairs; - }; - -})(); - - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.MouseConstraint` module contains methods for creating mouse constraints. -* Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class MouseConstraint -*/ - -var MouseConstraint = {}; - -module.exports = MouseConstraint; - -var Vertices = __webpack_require__(3); -var Sleeping = __webpack_require__(7); -var Mouse = __webpack_require__(13); -var Events = __webpack_require__(4); -var Detector = __webpack_require__(14); -var Constraint = __webpack_require__(10); -var Composite = __webpack_require__(5); -var Common = __webpack_require__(0); -var Bounds = __webpack_require__(1); - -(function() { - - /** - * Creates a new mouse constraint. - * 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 {engine} engine - * @param {} options - * @return {MouseConstraint} A new MouseConstraint - */ - MouseConstraint.create = function(engine, options) { - var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null); - - if (!mouse) { - if (engine && engine.render && engine.render.canvas) { - mouse = Mouse.create(engine.render.canvas); - } else if (options && options.element) { - mouse = Mouse.create(options.element); - } else { - mouse = Mouse.create(); - Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected'); - } - } - - var constraint = Constraint.create({ - label: 'Mouse Constraint', - pointA: mouse.position, - pointB: { x: 0, y: 0 }, - length: 0.01, - stiffness: 0.1, - angularStiffness: 1, - render: { - strokeStyle: '#90EE90', - lineWidth: 3 - } - }); - - var defaults = { - type: 'mouseConstraint', - mouse: mouse, - element: null, - body: null, - constraint: constraint, - collisionFilter: { - category: 0x0001, - mask: 0xFFFFFFFF, - group: 0 - } - }; - - var mouseConstraint = Common.extend(defaults, options); - - Events.on(engine, 'beforeUpdate', function() { - var allBodies = Composite.allBodies(engine.world); - MouseConstraint.update(mouseConstraint, allBodies); - MouseConstraint._triggerEvents(mouseConstraint); - }); - - return mouseConstraint; - }; - - /** - * Updates the given mouse constraint. - * @private - * @method update - * @param {MouseConstraint} mouseConstraint - * @param {body[]} bodies - */ - MouseConstraint.update = function(mouseConstraint, bodies) { - var mouse = mouseConstraint.mouse, - constraint = mouseConstraint.constraint, - body = mouseConstraint.body; - - if (mouse.button === 0) { - if (!constraint.bodyB) { - for (var i = 0; i < bodies.length; i++) { - body = bodies[i]; - if (Bounds.contains(body.bounds, mouse.position) - && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) { - for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) { - var part = body.parts[j]; - if (Vertices.contains(part.vertices, mouse.position)) { - constraint.pointA = mouse.position; - constraint.bodyB = mouseConstraint.body = body; - constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y }; - constraint.angleB = body.angle; - - Sleeping.set(body, false); - Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body }); - - break; - } - } - } - } - } else { - Sleeping.set(constraint.bodyB, false); - constraint.pointA = mouse.position; - } - } else { - constraint.bodyB = mouseConstraint.body = null; - constraint.pointB = null; - - if (body) - Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body }); - } - }; - - /** - * Triggers mouse constraint events. - * @method _triggerEvents - * @private - * @param {mouse} mouseConstraint - */ - MouseConstraint._triggerEvents = function(mouseConstraint) { - var mouse = mouseConstraint.mouse, - mouseEvents = mouse.sourceEvents; - - if (mouseEvents.mousemove) - Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse }); - - if (mouseEvents.mousedown) - Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse }); - - if (mouseEvents.mouseup) - Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse }); - - // reset the mouse state ready for the next step - Mouse.clearSourceEvents(mouse); - }; - - /* - * - * Events Documentation - * - */ - - /** - * Fired when the mouse has moved (or a touch moves) during the last step - * - * @event mousemove - * @param {} event An event object - * @param {mouse} event.mouse The engine's mouse instance - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when the mouse is down (or a touch has started) during the last step - * - * @event mousedown - * @param {} event An event object - * @param {mouse} event.mouse The engine's mouse instance - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when the mouse is up (or a touch has ended) during the last step - * - * @event mouseup - * @param {} event An event object - * @param {mouse} event.mouse The engine's mouse instance - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when the user starts dragging a body - * - * @event startdrag - * @param {} event An event object - * @param {mouse} event.mouse The engine's mouse instance - * @param {body} event.body The body being dragged - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when the user ends dragging a body - * - * @event enddrag - * @param {} event An event object - * @param {mouse} event.mouse The engine's mouse instance - * @param {body} event.body The body that has stopped being dragged - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /* - * - * Properties Documentation - * - */ - - /** - * A `String` denoting the type of object. - * - * @property type - * @type string - * @default "constraint" - * @readOnly - */ - - /** - * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created. - * - * @property mouse - * @type mouse - * @default mouse - */ - - /** - * The `Body` that is currently being moved by the user, or `null` if no body. - * - * @property body - * @type body - * @default null - */ - - /** - * The `Constraint` object that is used to move the body during interaction. - * - * @property constraint - * @type constraint - */ - - /** - * An `Object` that specifies the collision filter properties. - * The collision filter allows the user to define which types of body this mouse constraint can interact with. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter - * @type object - */ - -})(); - - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Query` module contains methods for performing collision queries. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Query -*/ - -var Query = {}; - -module.exports = Query; - -var Vector = __webpack_require__(2); -var Collision = __webpack_require__(8); -var Bounds = __webpack_require__(1); -var Bodies = __webpack_require__(12); -var Vertices = __webpack_require__(3); - -(function() { - - /** - * Returns a list of collisions between `body` and `bodies`. - * @method collides - * @param {body} body - * @param {body[]} bodies - * @return {collision[]} Collisions - */ - Query.collides = function(body, bodies) { - var collisions = [], - bodiesLength = bodies.length, - bounds = body.bounds, - collides = Collision.collides, - overlaps = Bounds.overlaps; - - for (var i = 0; i < bodiesLength; i++) { - var bodyA = bodies[i], - partsALength = bodyA.parts.length, - partsAStart = partsALength === 1 ? 0 : 1; - - if (overlaps(bodyA.bounds, bounds)) { - for (var j = partsAStart; j < partsALength; j++) { - var part = bodyA.parts[j]; - - if (overlaps(part.bounds, bounds)) { - var collision = collides(part, body); - - if (collision) { - collisions.push(collision); - break; - } - } - } - } - } - - return collisions; - }; - - /** - * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided. - * @method ray - * @param {body[]} bodies - * @param {vector} startPoint - * @param {vector} endPoint - * @param {number} [rayWidth] - * @return {collision[]} Collisions - */ - Query.ray = function(bodies, startPoint, endPoint, rayWidth) { - rayWidth = rayWidth || 1e-100; - - var rayAngle = Vector.angle(startPoint, endPoint), - rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)), - rayX = (endPoint.x + startPoint.x) * 0.5, - rayY = (endPoint.y + startPoint.y) * 0.5, - ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }), - collisions = Query.collides(ray, bodies); - - for (var i = 0; i < collisions.length; i += 1) { - var collision = collisions[i]; - collision.body = collision.bodyB = collision.bodyA; - } - - return collisions; - }; - - /** - * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies. - * @method region - * @param {body[]} bodies - * @param {bounds} bounds - * @param {bool} [outside=false] - * @return {body[]} The bodies matching the query - */ - Query.region = function(bodies, bounds, outside) { - var result = []; - - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - overlaps = Bounds.overlaps(body.bounds, bounds); - if ((overlaps && !outside) || (!overlaps && outside)) - result.push(body); - } - - return result; - }; - - /** - * Returns all bodies whose vertices contain the given point, from the given set of bodies. - * @method point - * @param {body[]} bodies - * @param {vector} point - * @return {body[]} The bodies matching the query - */ - Query.point = function(bodies, point) { - var result = []; - - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - if (Bounds.contains(body.bounds, point)) { - for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) { - var part = body.parts[j]; - - if (Bounds.contains(part.bounds, point) - && Vertices.contains(part.vertices, point)) { - result.push(body); - break; - } - } - } - } - - return result; - }; - -})(); - - /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { @@ -10168,8 +10425,8 @@ var Runner = {}; module.exports = Runner; -var Events = __webpack_require__(4); -var Engine = __webpack_require__(18); +var Events = __webpack_require__(5); +var Engine = __webpack_require__(17); var Common = __webpack_require__(0); (function() { @@ -10207,13 +10464,11 @@ var Common = __webpack_require__(0); Runner.create = function(options) { var defaults = { fps: 60, - correction: 1, deltaSampleSize: 60, counterTimestamp: 0, frameCounter: 0, deltaHistory: [], timePrev: null, - timeScalePrev: 1, frameRequestId: null, isFixed: false, enabled: true @@ -10241,8 +10496,8 @@ var Common = __webpack_require__(0); runner = Runner.create(); } - (function render(time){ - runner.frameRequestId = _requestAnimationFrame(render); + (function run(time){ + runner.frameRequestId = _requestAnimationFrame(run); if (time && runner.enabled) { Runner.tick(runner, engine, time); @@ -10263,16 +10518,8 @@ var Common = __webpack_require__(0); */ Runner.tick = function(runner, engine, time) { var timing = engine.timing, - correction = 1, delta; - // create an event object - var event = { - timestamp: timing.timestamp - }; - - Events.trigger(runner, 'beforeTick', event); - if (runner.isFixed) { // fixed timestep delta = runner.delta; @@ -10285,27 +10532,21 @@ var Common = __webpack_require__(0); runner.deltaHistory.push(delta); runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize); delta = Math.min.apply(null, runner.deltaHistory); - + // limit delta delta = delta < runner.deltaMin ? runner.deltaMin : delta; delta = delta > runner.deltaMax ? runner.deltaMax : delta; - // correction for delta - correction = delta / runner.delta; - // update engine timing object runner.delta = delta; } - // time correction for time scaling - if (runner.timeScalePrev !== 0) - correction *= timing.timeScale / runner.timeScalePrev; + // create an event object + var event = { + timestamp: timing.timestamp + }; - if (timing.timeScale === 0) - correction = 0; - - runner.timeScalePrev = timing.timeScale; - runner.correction = correction; + Events.trigger(runner, 'beforeTick', event); // fps counter runner.frameCounter += 1; @@ -10319,7 +10560,9 @@ var Common = __webpack_require__(0); // update Events.trigger(runner, 'beforeUpdate', event); - Engine.update(engine, delta, correction); + + Engine.update(engine, delta); + Events.trigger(runner, 'afterUpdate', event); Events.trigger(runner, 'afterTick', event); @@ -10734,7 +10977,7 @@ var World = {}; module.exports = World; -var Composite = __webpack_require__(5); +var Composite = __webpack_require__(6); var Common = __webpack_require__(0); (function() { diff --git a/build/matter.min.js b/build/matter.min.js index 29d25db..1b31215 100644 --- a/build/matter.min.js +++ b/build/matter.min.js @@ -1,6 +1,6 @@ /*! - * matter-js 0.18.0 by @liabru + * matter-js 0.19.0 by @liabru * http://brm.io/matter-js/ * License MIT */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Matter",[],t):"object"==typeof exports?exports.Matter=t():e.Matter=t()}(this,(function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=21)}([function(e,t){var n={};e.exports=n,function(){n._nextId=0,n._seed=0,n._nowStartTime=+new Date,n._warnedOnce={},n._decomp=null,n.extend=function(e,t){var i,o;"boolean"==typeof t?(i=2,o=t):(i=1,o=!0);for(var r=i;r0;t--){var i=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[i],e[i]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,i){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",i)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;ne.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,i=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+i}},function(e,t){var n={};e.exports=n,n.create=function(e,t){return{x:e||0,y:t||0}},n.clone=function(e){return{x:e.x,y:e.y}},n.magnitude=function(e){return Math.sqrt(e.x*e.x+e.y*e.y)},n.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},n.rotate=function(e,t,n){var i=Math.cos(t),o=Math.sin(t);n||(n={});var r=e.x*i-e.y*o;return n.y=e.x*o+e.y*i,n.x=r,n},n.rotateAbout=function(e,t,n,i){var o=Math.cos(t),r=Math.sin(t);i||(i={});var a=n.x+((e.x-n.x)*o-(e.y-n.y)*r);return i.y=n.y+((e.x-n.x)*r+(e.y-n.y)*o),i.x=a,i},n.normalise=function(e){var t=n.magnitude(e);return 0===t?{x:0,y:0}:{x:e.x/t,y:e.y/t}},n.dot=function(e,t){return e.x*t.x+e.y*t.y},n.cross=function(e,t){return e.x*t.y-e.y*t.x},n.cross3=function(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)},n.add=function(e,t,n){return n||(n={}),n.x=e.x+t.x,n.y=e.y+t.y,n},n.sub=function(e,t,n){return n||(n={}),n.x=e.x-t.x,n.y=e.y-t.y,n},n.mult=function(e,t){return{x:e.x*t,y:e.y*t}},n.div=function(e,t){return{x:e.x/t,y:e.y/t}},n.perp=function(e,t){return{x:(t=!0===t?-1:1)*-e.y,y:t*e.x}},n.neg=function(e){return{x:-e.x,y:-e.y}},n.angle=function(e,t){return Math.atan2(t.y-e.y,t.x-e.x)},n._temp=[n.create(),n.create(),n.create(),n.create(),n.create(),n.create()]},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.create=function(e,t){for(var n=[],i=0;i0)return!1;a=n}return!0},i.scale=function(e,t,n,r){if(1===t&&1===n)return e;var a,s;r=r||i.centre(e);for(var l=0;l=0?l-1:e.length-1],u=e[l],d=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},i.hull=function(e){var t,n,i=[],r=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];i.length>=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}return i.pop(),r.pop(),i.concat(r)}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.on=function(e,t,n){for(var i,o=t.split(" "),r=0;r0){n||(n={}),i=t.split(" ");for(var c=0;c0&&r.rotateAbout(a.position,n,e.position,a.position)}},i.setVelocity=function(e,t){e.positionPrev.x=e.position.x-t.x,e.positionPrev.y=e.position.y-t.y,e.velocity.x=t.x,e.velocity.y=t.y,e.speed=r.magnitude(e.velocity)},i.setAngularVelocity=function(e,t){e.anglePrev=e.angle-t,e.angularVelocity=t,e.angularSpeed=Math.abs(e.angularVelocity)},i.translate=function(e,t){i.setPosition(e,r.add(e.position,t))},i.rotate=function(e,t,n){if(n){var o=Math.cos(t),r=Math.sin(t),a=e.position.x-n.x,s=e.position.y-n.y;i.setPosition(e,{x:n.x+(a*o-s*r),y:n.y+(a*r+s*o)}),i.setAngle(e,e.angle+t)}else i.setAngle(e,e.angle+t)},i.scale=function(e,t,n,r){var a=0,s=0;r=r||e.position;for(var u=0;u0&&(a+=d.area,s+=d.inertia),d.position.x=r.x+(d.position.x-r.x)*t,d.position.y=r.y+(d.position.y-r.y)*n,l.update(d.bounds,d.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(i.setMass(e,e.density*a),i.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},i.update=function(e,t,n,i){var a=Math.pow(t*n*e.timeScale,2),s=1-e.frictionAir*n*e.timeScale,u=e.position.x-e.positionPrev.x,d=e.position.y-e.positionPrev.y;e.velocity.x=u*s*i+e.force.x/e.mass*a,e.velocity.y=d*s*i+e.force.y/e.mass*a,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.angularVelocity=(e.angle-e.anglePrev)*s*i+e.torque/e.inertia*a,e.anglePrev=e.angle,e.angle+=e.angularVelocity,e.speed=r.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var p=0;p0&&(f.position.x+=e.velocity.x,f.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(f.vertices,e.angularVelocity,e.position),c.rotate(f.axes,e.angularVelocity),p>0&&r.rotateAbout(f.position,e.angularVelocity,e.position,f.position)),l.update(f.bounds,f.vertices,e.velocity)}},i.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var i=t.x-e.position.x,o=t.y-e.position.y;e.torque+=i*n.y-o*n.x},i._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n0&&r.motion=r.sleepThreshold&&i.set(r,!0)):r.sleepCounter>0&&(r.sleepCounter-=1)}else i.set(r,!1)}},i.afterCollisions=function(e,t){for(var n=t*t*t,o=0;oi._motionWakeThreshold*n&&i.set(c,!1)}}}},i.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||o.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&o.trigger(e,"sleepEnd"))}},function(e,t,n){var i={};e.exports=i;var o,r,a,s=n(3),l=n(9);o=[],r={overlap:0,axis:null},a={overlap:0,axis:null},i.create=function(e,t){return{pair:null,collided:!1,bodyA:e,bodyB:t,parentA:e.parent,parentB:t.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},i.collides=function(e,t,n){if(i._overlapAxes(r,e.vertices,t.vertices,e.axes),r.overlap<=0)return null;if(i._overlapAxes(a,t.vertices,e.vertices,t.axes),a.overlap<=0)return null;var o,c,u=n&&n.table[l.id(e,t)];u?o=u.collision:((o=i.create(e,t)).collided=!0,o.bodyA=e.idP?P=s:sC?C=s:so?o=a:al.frictionStatic?s.frictionStatic:l.frictionStatic,e.restitution=s.restitution>l.restitution?s.restitution:l.restitution,e.slop=s.slop>l.slop?s.slop:l.slop,t.pair=e,a.length=0;for(var u=0;u0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=c.extend(a,t.render),t},i.preSolveAll=function(e){for(var t=0;t0&&(d.position.x+=c.x,d.position.y+=c.y),0!==c.angle&&(o.rotate(d.vertices,c.angle,n.position),l.rotate(d.axes,c.angle),u>0&&r.rotateAbout(d.position,c.angle,n.position,d.position)),s.update(d.bounds,d.vertices,n.velocity)}c.angle*=i._warming,c.x*=i._warming,c.y*=i._warming}}},i.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+e.pointA.x,y:(e.bodyA?e.bodyA.position.y:0)+e.pointA.y}},i.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+e.pointB.x,y:(e.bodyB?e.bodyB.position.y:0)+e.pointB.y}}},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.fromVertices=function(e){for(var t={},n=0;n0&&o.area(M)1?(v=a.create(r.extend({parts:y.slice(0)},i)),a.setPosition(v,{x:e,y:t}),v):y[0]}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},i.setElement(t,t.element),t},i.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},i.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},i.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i._getRelativeMousePosition=function(e,t,n){var i,o,r=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,l=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,c=e.changedTouches;return c?(i=c[0].pageX-r.left-s,o=c[0].pageY-r.top-l):(i=e.pageX-r.left-s,o=e.pageY-r.top-l),{x:i/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(8);i.create=function(e){return o.extend({bodies:[],pairs:null},e)},i.setBodies=function(e,t){e.bodies=t.slice(0)},i.clear=function(e){e.bodies=[]},i.collisions=function(e){var t,n,o=[],a=e.pairs,s=e.bodies,l=s.length,c=i.canCollide,u=r.collides;for(s.sort(i._compareBoundsX),t=0;tf)break;if(!(vB.max.y)&&(!m||!h.isStatic&&!h.isSleeping)&&c(d.collisionFilter,h.collisionFilter)){var b=h.parts.length;if(x&&1===b)(C=u(d,h,a))&&o.push(C);else for(var S=b>1?1:0,w=g>1?1:0;wB.max.x||p.max.xB.max.y||(C=u(A,M,a))&&o.push(C)}}}}return o},i.canCollide=function(e,t){return e.group===t.group&&0!==e.group?e.group>0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)},i._compareBoundsX=function(e,t){return e.bounds.min.x-t.bounds.min.x}},function(e,t,n){var i={};e.exports=i;var o=n(0);i._registry={},i.register=function(e){if(i.isPlugin(e)||o.warn("Plugin.register:",i.toString(e),"does not implement all required fields."),e.name in i._registry){var t=i._registry[e.name],n=i.versionParse(e.version).number,r=i.versionParse(t.version).number;n>r?(o.warn("Plugin.register:",i.toString(t),"was upgraded to",i.toString(e)),i._registry[e.name]=e):n-1},i.isFor=function(e,t){var n=e.for&&i.dependencyParse(e.for);return!e.for||t.name===n.name&&i.versionSatisfies(t.version,n.range)},i.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=i.dependencies(e),r=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",i.toString(e),"does not specify any dependencies to install.")},i.dependencies=function(e,t){var n=i.dependencyParse(e),r=n.name;if(!(r in(t=t||{}))){e=i.resolve(e)||e,t[r]=o.map(e.uses||[],(function(t){i.isPlugin(t)&&i.register(t);var r=i.dependencyParse(t),a=i.resolve(t);return a&&!i.versionSatisfies(a.version,r.range)?(o.warn("Plugin.dependencies:",i.toString(a),"does not satisfy",i.toString(r),"used by",i.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",i.toString(t),"used by",i.toString(n),"could not be resolved."),e._warned=!0),r.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),i=Number(n[4]),r=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:i,minor:r,patch:a,parts:[i,r,a],prerelease:n[7],number:1e8*i+1e4*r+a}},i.versionSatisfies=function(e,t){t=t||"*";var n=i.versionParse(t),o=i.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(5),a=n(1),s=n(4),l=n(2),c=n(13);!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout((function(){e(o.now())}),1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),i._goodFps=30,i._goodDelta=1e3/60,i.create=function(e){var t={controller:i,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,timing:{historySize:60,delta:0,deltaHistory:[],lastTime:0,lastTimestamp:0,lastElapsed:0,timestampElapsed:0,timestampElapsedHistory:[],engineDeltaHistory:[],engineElapsedHistory:[],elapsedHistory:[]},options:{width:800,height:600,pixelRatio:1,background:"#14151f",wireframeBackground:"#14151f",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showStats:!1,showPerformance:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},n=o.extend(t,e);return n.canvas&&(n.canvas.width=n.options.width||n.canvas.width,n.canvas.height=n.options.height||n.canvas.height),n.mouse=e.mouse,n.engine=e.engine,n.canvas=n.canvas||d(n.options.width,n.options.height),n.context=n.canvas.getContext("2d"),n.textures={},n.bounds=n.bounds||{min:{x:0,y:0},max:{x:n.canvas.width,y:n.canvas.height}},n.options.showBroadphase=!1,1!==n.options.pixelRatio&&i.setPixelRatio(n,n.options.pixelRatio),o.isElement(n.element)?n.element.appendChild(n.canvas):n.canvas.parentNode||o.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),n},i.run=function(t){!function o(r){t.frameRequestId=e(o),n(t,r),i.world(t,r),(t.options.showStats||t.options.showDebug)&&i.stats(t,t.context,r),(t.options.showPerformance||t.options.showDebug)&&i.performance(t,t.context,r)}()},i.stop=function(e){t(e.frameRequestId)},i.setPixelRatio=function(e,t){var n=e.options,i=e.canvas;"auto"===t&&(t=p(i)),n.pixelRatio=t,i.setAttribute("data-pixel-ratio",t),i.width=n.width*t,i.height=n.height*t,i.style.width=n.width+"px",i.style.height=n.height+"px"},i.lookAt=function(e,t,n,i){i=void 0===i||i,t=o.isArray(t)?t:[t],n=n||{x:0,y:0};for(var r={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},a=0;ar.max.x&&(r.max.x=u.x),l.yr.max.y&&(r.max.y=u.y))}var d=r.max.x-r.min.x+2*n.x,p=r.max.y-r.min.y+2*n.y,f=e.canvas.height,v=e.canvas.width/f,y=d/p,m=1,g=1;y>v?g=y/v:m=v/y,e.options.hasBounds=!0,e.bounds.min.x=r.min.x,e.bounds.max.x=r.min.x+d*m,e.bounds.min.y=r.min.y,e.bounds.max.y=r.min.y+p*g,i&&(e.bounds.min.x+=.5*d-d*m*.5,e.bounds.max.x+=.5*d-d*m*.5,e.bounds.min.y+=.5*p-p*g*.5,e.bounds.max.y+=.5*p-p*g*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(c.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),c.setOffset(e.mouse,e.bounds.min))},i.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,i=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/i,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},i.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},i.world=function(e,t){var n,u=o.now(),d=e.engine,p=d.world,f=e.canvas,y=e.context,m=e.options,g=e.timing,x=r.allBodies(p),h=r.allConstraints(p),b=m.wireframes?m.wireframeBackground:m.background,S=[],w=[],A={timestamp:d.timing.timestamp};if(s.trigger(e,"beforeRender",A),e.currentBackground!==b&&v(e,b),y.globalCompositeOperation="source-in",y.fillStyle="transparent",y.fillRect(0,0,f.width,f.height),y.globalCompositeOperation="source-over",m.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;r1?1:0;s1?1:0;r1?1:0;r1?1:0;o0)){var u=i.activeContacts[0].vertex.x,d=i.activeContacts[0].vertex.y;2===i.activeContacts.length&&(u=(i.activeContacts[0].vertex.x+i.activeContacts[1].vertex.x)/2,d=(i.activeContacts[0].vertex.y+i.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(u-8*o.normal.x,d-8*o.normal.y):s.moveTo(u+8*o.normal.x,d+8*o.normal.y),s.lineTo(u,d)}l.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},i.separations=function(e,t,n){var i,o,r,a,s,l=n,c=e.options;for(l.beginPath(),s=0;s0&&l.trigger(e,"collisionStart",{pairs:m.collisionStart}),r.preSolvePosition(m.list),f=0;f0&&l.trigger(e,"collisionActive",{pairs:m.collisionActive}),m.collisionEnd.length>0&&l.trigger(e,"collisionEnd",{pairs:m.collisionEnd}),i._bodiesClearForces(b),l.trigger(e,"afterUpdate",h),e.timing.lastElapsed=d.now()-p,e},i.merge=function(e,t){if(d.extend(e,t),t.world){e.world=t.world,i.clear(e);for(var n=c.allBodies(e.world),r=0;rW||-H>W?(o=H>0?H:-H,(n=f.friction*(H>0?1:-1)*s)<-o?n=-o:n>o&&(n=o)):(n=H,o=d);var G=I*b-T*h,N=R*b-E*h,U=C/(M+y.inverseInertia*G*G+m.inverseInertia*N*N),z=(1+f.restitution)*F*U;if(n*=U,F*F>l&&F<0)k.normalImpulse=0;else{var X=k.normalImpulse;k.normalImpulse+=z,k.normalImpulse=Math.min(k.normalImpulse,0),z=k.normalImpulse-X}if(H*H>u)k.tangentImpulse=0;else{var Q=k.tangentImpulse;k.tangentImpulse+=n,k.tangentImpulse<-o&&(k.tangentImpulse=-o),k.tangentImpulse>o&&(k.tangentImpulse=o),n=k.tangentImpulse-Q}var Y=h*z+S*n,Z=b*z+w*n;y.isStatic||y.isSleeping||(y.positionPrev.x+=Y*y.inverseMass,y.positionPrev.y+=Z*y.inverseMass,y.anglePrev+=(I*Z-T*Y)*y.inverseInertia),m.isStatic||m.isSleeping||(m.positionPrev.x-=Y*m.inverseMass,m.positionPrev.y-=Z*m.inverseMass,m.anglePrev-=(R*Z-E*Y)*m.inverseInertia)}}}}},function(e,t,n){var i={};e.exports=i;var o=n(9),r=n(0);i.create=function(e){return r.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},i.update=function(e,t,n){var i,r,a,s,l=e.list,c=l.length,u=e.table,d=t.length,p=e.collisionStart,f=e.collisionEnd,v=e.collisionActive;for(p.length=0,f.length=0,v.length=0,s=0;sy&&(y=x),s.translate(g,{x:.5*h,y:.5*x}),d=g.bounds.max.x+r,o.addBody(u,g),c=g,f+=1}else d+=r}p+=y+a,d=e}return u},i.chain=function(e,t,n,i,s,l){for(var c=e.bodies,u=1;u0)for(c=0;c0&&(p=f[c-1+(l-1)*t],o.addConstraint(e,r.create(a.extend({bodyA:p,bodyB:d},s)))),i&&cp||a<(c=p-c)||a>n-1-c))return 1===d&&s.translate(u,{x:(a+(n%2==1?1:-1))*f,y:0}),l(e+(u?a*f:0)+a*r,i,a,c,u,d)}))},i.newtonsCradle=function(e,t,n,i,a){for(var s=o.create({label:"Newtons Cradle"}),c=0;cu.bounds.max.x||f.bounds.max.yu.bounds.max.y))){var v=i._getRegion(e,f);if(!f.region||v.id!==f.region.id||o){f.region&&!o||(f.region=v);var y=i._regionUnion(v,f.region);for(a=y.startCol;a<=y.endCol;a++)for(s=y.startRow;s<=y.endRow;s++){l=d[c=i._getBucketId(a,s)];var m=a>=v.startCol&&a<=v.endCol&&s>=v.startRow&&s<=v.endRow,g=a>=f.region.startCol&&a<=f.region.endCol&&s>=f.region.startRow&&s<=f.region.endRow;!m&&g&&g&&l&&i._bucketRemoveBody(e,l,f),(f.region===v||m&&!g||o)&&(l||(l=i._createBucket(d,c)),i._bucketAddBody(e,l,f))}f.region=v,p=!0}}}p&&(e.pairsList=i._createActivePairsList(e))},a(i,"update","Grid.update ➤ replaced by Matter.Detector"),i.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},a(i,"clear","Grid.clear ➤ replaced by Matter.Detector"),i._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return i._createRegion(n,o,r,a)},i._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return i._createRegion(o,r,a,s)},i._createRegion=function(e,t,n,i){return{id:e+","+t+","+n+","+i,startCol:e,endCol:t,startRow:n,endRow:i}},i._getBucketId=function(e,t){return"C"+e+"R"+t},i._createBucket=function(e,t){return e[t]=[]},i._bucketAddBody=function(e,t,n){var i,r=e.pairs,a=o.id,s=t.length;for(i=0;i0?s.push(t):delete i[o[n]];return s}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(7),a=n(13),s=n(4),l=n(14),c=n(10),u=n(5),d=n(0),p=n(1);i.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=a.create(e.render.canvas):t&&t.element?n=a.create(t.element):(n=a.create(),d.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var o={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:c.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),collisionFilter:{category:1,mask:4294967295,group:0}},r=d.extend(o,t);return s.on(e,"beforeUpdate",(function(){var t=u.allBodies(e.world);i.update(r,t),i._triggerEvents(r)})),r},i.update=function(e,t){var n=e.mouse,i=e.constraint,a=e.body;if(0===n.button){if(i.bodyB)r.set(i.bodyB,!1),i.pointA=n.position;else for(var c=0;c1?1:0;ue.deltaMax?e.deltaMax:i)/e.delta,e.delta=i),0!==e.timeScalePrev&&(s*=a.timeScale/e.timeScalePrev),0===a.timeScale&&(s=0),e.timeScalePrev=a.timeScale,e.correction=s,e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",l),o.trigger(e,"beforeUpdate",l),r.update(t,i,s),o.trigger(e,"afterUpdate",l),o.trigger(e,"afterTick",l)},i.stop=function(e){t(e.frameRequestId)},i.start=function(e,t){i.run(e,t)}}()},function(e,t,n){var i={};e.exports=i;var o=n(8),r=n(0).deprecated;i.collides=function(e,t){return o.collides(e,t)},r(i,"collides","SAT.collides ➤ replaced by Collision.collides")},function(e,t,n){var i={};e.exports=i;n(1);var o=n(0);i.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||o.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,a,s,l,c,u,d,p,f,v,y=[],m=0,g=0,x=0;t=t||15;var h=function(e,t,n){var i=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&i?(f=p.x,v=p.y):(f=0,v=0);var o={x:f+e,y:v+t};!i&&p||(p=o),y.push(o),g=f+e,x=v+t}},b=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":g=e.x,x=e.y;break;case"H":g=e.x;break;case"V":x=e.y}h(g,x,e.pathSegType)}};for(i._svgPathToAbsolute(e),a=e.getTotalLength(),c=[],n=0;n0;t--){var i=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[i],e[i]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,i){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",i)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;ne.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,i=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+i}},function(e,t){var n={};e.exports=n,n.create=function(e,t){return{x:e||0,y:t||0}},n.clone=function(e){return{x:e.x,y:e.y}},n.magnitude=function(e){return Math.sqrt(e.x*e.x+e.y*e.y)},n.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},n.rotate=function(e,t,n){var i=Math.cos(t),o=Math.sin(t);n||(n={});var r=e.x*i-e.y*o;return n.y=e.x*o+e.y*i,n.x=r,n},n.rotateAbout=function(e,t,n,i){var o=Math.cos(t),r=Math.sin(t);i||(i={});var a=n.x+((e.x-n.x)*o-(e.y-n.y)*r);return i.y=n.y+((e.x-n.x)*r+(e.y-n.y)*o),i.x=a,i},n.normalise=function(e){var t=n.magnitude(e);return 0===t?{x:0,y:0}:{x:e.x/t,y:e.y/t}},n.dot=function(e,t){return e.x*t.x+e.y*t.y},n.cross=function(e,t){return e.x*t.y-e.y*t.x},n.cross3=function(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)},n.add=function(e,t,n){return n||(n={}),n.x=e.x+t.x,n.y=e.y+t.y,n},n.sub=function(e,t,n){return n||(n={}),n.x=e.x-t.x,n.y=e.y-t.y,n},n.mult=function(e,t){return{x:e.x*t,y:e.y*t}},n.div=function(e,t){return{x:e.x/t,y:e.y/t}},n.perp=function(e,t){return{x:(t=!0===t?-1:1)*-e.y,y:t*e.x}},n.neg=function(e){return{x:-e.x,y:-e.y}},n.angle=function(e,t){return Math.atan2(t.y-e.y,t.x-e.x)},n._temp=[n.create(),n.create(),n.create(),n.create(),n.create(),n.create()]},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.create=function(e,t){for(var n=[],i=0;i0)return!1;a=n}return!0},i.scale=function(e,t,n,r){if(1===t&&1===n)return e;var a,s;r=r||i.centre(e);for(var l=0;l=0?l-1:e.length-1],u=e[l],d=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},i.hull=function(e){var t,n,i=[],r=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];i.length>=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}return i.pop(),r.pop(),i.concat(r)}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(2),a=n(7),s=n(0),l=n(1),c=n(11);!function(){i._timeCorrection=!0,i._inertiaScale=4,i._nextCollidingGroupId=1,i._nextNonCollidingGroupId=-1,i._nextCategory=1,i._baseDelta=1e3/60,i.create=function(t){var n={id:s.nextId(),type:"body",label:"Body",parts:[],plugin:{},angle:0,vertices:o.fromPath("L 0 0 L 40 0 L 40 40 L 0 40"),position:{x:0,y:0},force:{x:0,y:0},torque:0,positionImpulse:{x:0,y:0},constraintImpulse:{x:0,y:0,angle:0},totalContacts:0,speed:0,angularSpeed:0,velocity:{x:0,y:0},angularVelocity:0,isSensor:!1,isStatic:!1,isSleeping:!1,motion:0,sleepThreshold:60,density:.001,restitution:0,friction:.1,frictionStatic:.5,frictionAir:.01,collisionFilter:{category:1,mask:4294967295,group:0},slop:.05,timeScale:1,render:{visible:!0,opacity:1,strokeStyle:null,fillStyle:null,lineWidth:null,sprite:{xScale:1,yScale:1,xOffset:0,yOffset:0}},events:null,bounds:null,chamfer:null,circleRadius:0,positionPrev:null,anglePrev:0,parent:null,axes:null,area:0,mass:0,inertia:0,deltaTime:1e3/60,_original:null},i=s.extend(n,t);return e(i,t),i},i.nextGroup=function(e){return e?i._nextNonCollidingGroupId--:i._nextCollidingGroupId++},i.nextCategory=function(){return i._nextCategory=i._nextCategory<<1,i._nextCategory};var e=function(e,t){t=t||{},i.set(e,{bounds:e.bounds||l.create(e.vertices),positionPrev:e.positionPrev||r.clone(e.position),anglePrev:e.anglePrev||e.angle,vertices:e.vertices,parts:e.parts||[e],isStatic:e.isStatic,isSleeping:e.isSleeping,parent:e.parent||e}),o.rotate(e.vertices,e.angle,e.position),c.rotate(e.axes,e.angle),l.update(e.bounds,e.vertices,e.velocity),i.set(e,{axes:t.axes||e.axes,area:t.area||e.area,mass:t.mass||e.mass,inertia:t.inertia||e.inertia});var n=e.isStatic?"#14151f":s.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),a=e.isStatic?"#555":"#ccc",u=e.isStatic&&null===e.render.fillStyle?1:0;e.render.fillStyle=e.render.fillStyle||n,e.render.strokeStyle=e.render.strokeStyle||a,e.render.lineWidth=e.render.lineWidth||u,e.render.sprite.xOffset+=-(e.bounds.min.x-e.position.x)/(e.bounds.max.x-e.bounds.min.x),e.render.sprite.yOffset+=-(e.bounds.min.y-e.position.y)/(e.bounds.max.y-e.bounds.min.y)};i.set=function(e,t,n){var o;for(o in"string"==typeof t&&(o=t,(t={})[o]=n),t)if(Object.prototype.hasOwnProperty.call(t,o))switch(n=t[o],o){case"isStatic":i.setStatic(e,n);break;case"isSleeping":a.set(e,n);break;case"mass":i.setMass(e,n);break;case"density":i.setDensity(e,n);break;case"inertia":i.setInertia(e,n);break;case"vertices":i.setVertices(e,n);break;case"position":i.setPosition(e,n);break;case"angle":i.setAngle(e,n);break;case"velocity":i.setVelocity(e,n);break;case"angularVelocity":i.setAngularVelocity(e,n);break;case"speed":i.setSpeed(e,n);break;case"angularSpeed":i.setAngularSpeed(e,n);break;case"parts":i.setParts(e,n);break;case"centre":i.setCentre(e,n);break;default:e[o]=n}},i.setStatic=function(e,t){for(var n=0;n0&&r.rotateAbout(s.position,i,e.position,s.position)}},i.setVelocity=function(e,t){var n=e.deltaTime/i._baseDelta;e.positionPrev.x=e.position.x-t.x*n,e.positionPrev.y=e.position.y-t.y*n,e.velocity.x=(e.position.x-e.positionPrev.x)/n,e.velocity.y=(e.position.y-e.positionPrev.y)/n,e.speed=r.magnitude(e.velocity)},i.getVelocity=function(e){var t=i._baseDelta/e.deltaTime;return{x:(e.position.x-e.positionPrev.x)*t,y:(e.position.y-e.positionPrev.y)*t}},i.getSpeed=function(e){return r.magnitude(i.getVelocity(e))},i.setSpeed=function(e,t){i.setVelocity(e,r.mult(r.normalise(i.getVelocity(e)),t))},i.setAngularVelocity=function(e,t){var n=e.deltaTime/i._baseDelta;e.anglePrev=e.angle-t*n,e.angularVelocity=(e.angle-e.anglePrev)/n,e.angularSpeed=Math.abs(e.angularVelocity)},i.getAngularVelocity=function(e){return(e.angle-e.anglePrev)*i._baseDelta/e.deltaTime},i.getAngularSpeed=function(e){return Math.abs(i.getAngularVelocity(e))},i.setAngularSpeed=function(e,t){i.setAngularVelocity(e,s.sign(i.getAngularVelocity(e))*t)},i.translate=function(e,t,n){i.setPosition(e,r.add(e.position,t),n)},i.rotate=function(e,t,n,o){if(n){var r=Math.cos(t),a=Math.sin(t),s=e.position.x-n.x,l=e.position.y-n.y;i.setPosition(e,{x:n.x+(s*r-l*a),y:n.y+(s*a+l*r)},o),i.setAngle(e,e.angle+t,o)}else i.setAngle(e,e.angle+t,o)},i.scale=function(e,t,n,r){var a=0,s=0;r=r||e.position;for(var u=0;u0&&(a+=d.area,s+=d.inertia),d.position.x=r.x+(d.position.x-r.x)*t,d.position.y=r.y+(d.position.y-r.y)*n,l.update(d.bounds,d.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(i.setMass(e,e.density*a),i.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},i.update=function(e,t){var n=(t=(void 0!==t?t:1e3/60)*e.timeScale)*t,a=i._timeCorrection?t/(e.deltaTime||t):1,u=1-e.frictionAir*(t/s._baseDelta),d=(e.position.x-e.positionPrev.x)*a,p=(e.position.y-e.positionPrev.y)*a;e.velocity.x=d*u+e.force.x/e.mass*n,e.velocity.y=p*u+e.force.y/e.mass*n,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.deltaTime=t,e.angularVelocity=(e.angle-e.anglePrev)*u*a+e.torque/e.inertia*n,e.anglePrev=e.angle,e.angle+=e.angularVelocity;for(var f=0;f0&&(v.position.x+=e.velocity.x,v.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(v.vertices,e.angularVelocity,e.position),c.rotate(v.axes,e.angularVelocity),f>0&&r.rotateAbout(v.position,e.angularVelocity,e.position,v.position)),l.update(v.bounds,v.vertices,e.velocity)}},i.updateVelocities=function(e){var t=i._baseDelta/e.deltaTime,n=e.velocity;n.x=(e.position.x-e.positionPrev.x)*t,n.y=(e.position.y-e.positionPrev.y)*t,e.speed=Math.sqrt(n.x*n.x+n.y*n.y),e.angularVelocity=(e.angle-e.anglePrev)*t,e.angularSpeed=Math.abs(e.angularVelocity)},i.applyForce=function(e,t,n){var i=t.x-e.position.x,o=t.y-e.position.y;e.force.x+=n.x,e.force.y+=n.y,e.torque+=i*n.y-o*n.x},i._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n0){n||(n={}),i=t.split(" ");for(var c=0;c0&&l.motion=l.sleepThreshold/n&&i.set(l,!0)):l.sleepCounter>0&&(l.sleepCounter-=1)}else i.set(l,!1)}},i.afterCollisions=function(e){for(var t=i._motionSleepThreshold,n=0;nt&&i.set(l,!1)}}}},i.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||r.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&r.trigger(e,"sleepEnd"))}},function(e,t,n){var i={};e.exports=i;var o,r,a,s=n(3),l=n(9);o=[],r={overlap:0,axis:null},a={overlap:0,axis:null},i.create=function(e,t){return{pair:null,collided:!1,bodyA:e,bodyB:t,parentA:e.parent,parentB:t.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},i.collides=function(e,t,n){if(i._overlapAxes(r,e.vertices,t.vertices,e.axes),r.overlap<=0)return null;if(i._overlapAxes(a,t.vertices,e.vertices,t.axes),a.overlap<=0)return null;var o,c,u=n&&n.table[l.id(e,t)];u?o=u.collision:((o=i.create(e,t)).collided=!0,o.bodyA=e.idP?P=s:sC?C=s:so?o=a:al.frictionStatic?s.frictionStatic:l.frictionStatic,e.restitution=s.restitution>l.restitution?s.restitution:l.restitution,e.slop=s.slop>l.slop?s.slop:l.slop,t.pair=e,a.length=0;for(var u=0;u0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=c.extend(a,t.render),t},i.preSolveAll=function(e){for(var t=0;t=1||0===e.length?e.stiffness*t:e.stiffness*t*t,h=e.damping*t,b=r.mult(u,g*x),S=(n?n.inverseMass:0)+(o?o.inverseMass:0),w=S+((n?n.inverseInertia:0)+(o?o.inverseInertia:0));if(h>0){var A=r.create();v=r.div(u,d),m=r.sub(o&&r.sub(o.position,o.positionPrev)||A,n&&r.sub(n.position,n.positionPrev)||A),y=r.dot(v,m)}n&&!n.isStatic&&(f=n.inverseMass/S,n.constraintImpulse.x-=b.x*f,n.constraintImpulse.y-=b.y*f,n.position.x-=b.x*f,n.position.y-=b.y*f,h>0&&(n.positionPrev.x-=h*v.x*y*f,n.positionPrev.y-=h*v.y*y*f),p=r.cross(a,b)/w*i._torqueDampen*n.inverseInertia*(1-e.angularStiffness),n.constraintImpulse.angle-=p,n.angle-=p),o&&!o.isStatic&&(f=o.inverseMass/S,o.constraintImpulse.x+=b.x*f,o.constraintImpulse.y+=b.y*f,o.position.x+=b.x*f,o.position.y+=b.y*f,h>0&&(o.positionPrev.x+=h*v.x*y*f,o.positionPrev.y+=h*v.y*y*f),p=r.cross(s,b)/w*i._torqueDampen*o.inverseInertia*(1-e.angularStiffness),o.constraintImpulse.angle+=p,o.angle+=p)}}},i.postSolveAll=function(e){for(var t=0;t0&&(d.position.x+=c.x,d.position.y+=c.y),0!==c.angle&&(o.rotate(d.vertices,c.angle,n.position),l.rotate(d.axes,c.angle),u>0&&r.rotateAbout(d.position,c.angle,n.position,d.position)),s.update(d.bounds,d.vertices,n.velocity)}c.angle*=i._warming,c.x*=i._warming,c.y*=i._warming}}},i.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+(e.pointA?e.pointA.x:0),y:(e.bodyA?e.bodyA.position.y:0)+(e.pointA?e.pointA.y:0)}},i.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+(e.pointB?e.pointB.x:0),y:(e.bodyB?e.bodyB.position.y:0)+(e.pointB?e.pointB.y:0)}}},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.fromVertices=function(e){for(var t={},n=0;n0&&o.area(M)1?(v=a.create(r.extend({parts:y.slice(0)},i)),a.setPosition(v,{x:e,y:t}),v):y[0]}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(8);i.create=function(e){return o.extend({bodies:[],pairs:null},e)},i.setBodies=function(e,t){e.bodies=t.slice(0)},i.clear=function(e){e.bodies=[]},i.collisions=function(e){var t,n,o=[],a=e.pairs,s=e.bodies,l=s.length,c=i.canCollide,u=r.collides;for(s.sort(i._compareBoundsX),t=0;tf)break;if(!(vB.max.y)&&(!m||!h.isStatic&&!h.isSleeping)&&c(d.collisionFilter,h.collisionFilter)){var b=h.parts.length;if(x&&1===b)(C=u(d,h,a))&&o.push(C);else for(var S=b>1?1:0,w=g>1?1:0;wB.max.x||p.max.xB.max.y||(C=u(A,M,a))&&o.push(C)}}}}return o},i.canCollide=function(e,t){return e.group===t.group&&0!==e.group?e.group>0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)},i._compareBoundsX=function(e,t){return e.bounds.min.x-t.bounds.min.x}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},i.setElement(t,t.element),t},i.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},i.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},i.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i._getRelativeMousePosition=function(e,t,n){var i,o,r=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,l=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,c=e.changedTouches;return c?(i=c[0].pageX-r.left-s,o=c[0].pageY-r.top-l):(i=e.pageX-r.left-s,o=e.pageY-r.top-l),{x:i/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},function(e,t,n){var i={};e.exports=i;var o=n(0);i._registry={},i.register=function(e){if(i.isPlugin(e)||o.warn("Plugin.register:",i.toString(e),"does not implement all required fields."),e.name in i._registry){var t=i._registry[e.name],n=i.versionParse(e.version).number,r=i.versionParse(t.version).number;n>r?(o.warn("Plugin.register:",i.toString(t),"was upgraded to",i.toString(e)),i._registry[e.name]=e):n-1},i.isFor=function(e,t){var n=e.for&&i.dependencyParse(e.for);return!e.for||t.name===n.name&&i.versionSatisfies(t.version,n.range)},i.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=i.dependencies(e),r=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",i.toString(e),"does not specify any dependencies to install.")},i.dependencies=function(e,t){var n=i.dependencyParse(e),r=n.name;if(!(r in(t=t||{}))){e=i.resolve(e)||e,t[r]=o.map(e.uses||[],(function(t){i.isPlugin(t)&&i.register(t);var r=i.dependencyParse(t),a=i.resolve(t);return a&&!i.versionSatisfies(a.version,r.range)?(o.warn("Plugin.dependencies:",i.toString(a),"does not satisfy",i.toString(r),"used by",i.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",i.toString(t),"used by",i.toString(n),"could not be resolved."),e._warned=!0),r.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),i=Number(n[4]),r=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:i,minor:r,patch:a,parts:[i,r,a],prerelease:n[7],number:1e8*i+1e4*r+a}},i.versionSatisfies=function(e,t){t=t||"*";var n=i.versionParse(t),o=i.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},function(e,t){var n={};e.exports=n,n.create=function(e){return{vertex:e,normalImpulse:0,tangentImpulse:0}}},function(e,t,n){var i={};e.exports=i;var o=n(7),r=n(18),a=n(13),s=n(19),l=n(5),c=n(6),u=n(10),d=n(0),p=n(4);i.create=function(e){e=e||{};var t=d.extend({positionIterations:6,velocityIterations:4,constraintIterations:2,enableSleeping:!1,events:[],plugin:{},gravity:{x:0,y:1,scale:.001},timing:{timestamp:0,timeScale:1,lastDelta:0,lastElapsed:0}},e);return t.world=e.world||c.create({label:"World"}),t.pairs=e.pairs||s.create(),t.detector=e.detector||a.create(),t.grid={buckets:[]},t.world.gravity=t.gravity,t.broadphase=t.grid,t.metrics={},t},i.update=function(e,t){var n,p=d.now(),f=e.world,v=e.detector,y=e.pairs,m=e.timing,g=m.timestamp;t=void 0!==t?t:d._baseDelta,t*=m.timeScale,m.timestamp+=t,m.lastDelta=t;var x={timestamp:m.timestamp,delta:t};l.trigger(e,"beforeUpdate",x);var h=c.allBodies(f),b=c.allConstraints(f);for(f.isModified&&(a.setBodies(v,h),c.setModified(f,!1,!1,!0)),e.enableSleeping&&o.update(h,t),i._bodiesApplyGravity(h,e.gravity),t>0&&i._bodiesUpdate(h,t),u.preSolveAll(h),n=0;n0&&l.trigger(e,"collisionStart",{pairs:y.collisionStart});var w=d.clamp(20/e.positionIterations,0,1);for(r.preSolvePosition(y.list),n=0;n0&&l.trigger(e,"collisionActive",{pairs:y.collisionActive}),y.collisionEnd.length>0&&l.trigger(e,"collisionEnd",{pairs:y.collisionEnd}),i._bodiesClearForces(h),l.trigger(e,"afterUpdate",x),e.timing.lastElapsed=d.now()-p,e},i.merge=function(e,t){if(d.extend(e,t),t.world){e.world=t.world,i.clear(e);for(var n=c.allBodies(e.world),r=0;rU?(o=q>0?q:-q,(n=y.friction*(q>0?1:-1)*c)<-o?n=-o:n>o&&(n=o)):(n=q,o=f);var N=R*w-V*S,z=E*w-L*S,X=B/(_+g.inverseInertia*N*N+x.inverseInertia*z*z),Q=(1+y.restitution)*j*X;if(n*=X,j0&&(I.normalImpulse=0),Q=I.normalImpulse-Y}if(q<-d||q>d)I.tangentImpulse=0;else{var Z=I.tangentImpulse;I.tangentImpulse+=n,I.tangentImpulse<-o&&(I.tangentImpulse=-o),I.tangentImpulse>o&&(I.tangentImpulse=o),n=I.tangentImpulse-Z}var $=S*Q+A*n,J=w*Q+P*n;g.isStatic||g.isSleeping||(g.positionPrev.x+=$*g.inverseMass,g.positionPrev.y+=J*g.inverseMass,g.anglePrev+=(R*J-V*$)*g.inverseInertia),x.isStatic||x.isSleeping||(x.positionPrev.x-=$*x.inverseMass,x.positionPrev.y-=J*x.inverseMass,x.anglePrev-=(E*J-L*$)*x.inverseInertia)}}}}},function(e,t,n){var i={};e.exports=i;var o=n(9),r=n(0);i.create=function(e){return r.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},i.update=function(e,t,n){var i,r,a,s,l=e.list,c=l.length,u=e.table,d=t.length,p=e.collisionStart,f=e.collisionEnd,v=e.collisionActive;for(p.length=0,f.length=0,v.length=0,s=0;sy&&(y=x),s.translate(g,{x:.5*h,y:.5*x}),d=g.bounds.max.x+r,o.addBody(u,g),c=g,f+=1}else d+=r}p+=y+a,d=e}return u},i.chain=function(e,t,n,i,s,l){for(var c=e.bodies,u=1;u0)for(c=0;c0&&(p=f[c-1+(l-1)*t],o.addConstraint(e,r.create(a.extend({bodyA:p,bodyB:d},s)))),i&&cp||a<(c=p-c)||a>n-1-c))return 1===d&&s.translate(u,{x:(a+(n%2==1?1:-1))*f,y:0}),l(e+(u?a*f:0)+a*r,i,a,c,u,d)}))},i.newtonsCradle=function(e,t,n,i,a){for(var s=o.create({label:"Newtons Cradle"}),c=0;cu.bounds.max.x||f.bounds.max.yu.bounds.max.y))){var v=i._getRegion(e,f);if(!f.region||v.id!==f.region.id||o){f.region&&!o||(f.region=v);var y=i._regionUnion(v,f.region);for(a=y.startCol;a<=y.endCol;a++)for(s=y.startRow;s<=y.endRow;s++){l=d[c=i._getBucketId(a,s)];var m=a>=v.startCol&&a<=v.endCol&&s>=v.startRow&&s<=v.endRow,g=a>=f.region.startCol&&a<=f.region.endCol&&s>=f.region.startRow&&s<=f.region.endRow;!m&&g&&g&&l&&i._bucketRemoveBody(e,l,f),(f.region===v||m&&!g||o)&&(l||(l=i._createBucket(d,c)),i._bucketAddBody(e,l,f))}f.region=v,p=!0}}}p&&(e.pairsList=i._createActivePairsList(e))},a(i,"update","Grid.update ➤ replaced by Matter.Detector"),i.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},a(i,"clear","Grid.clear ➤ replaced by Matter.Detector"),i._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return i._createRegion(n,o,r,a)},i._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return i._createRegion(o,r,a,s)},i._createRegion=function(e,t,n,i){return{id:e+","+t+","+n+","+i,startCol:e,endCol:t,startRow:n,endRow:i}},i._getBucketId=function(e,t){return"C"+e+"R"+t},i._createBucket=function(e,t){return e[t]=[]},i._bucketAddBody=function(e,t,n){var i,r=e.pairs,a=o.id,s=t.length;for(i=0;i0?s.push(t):delete i[o[n]];return s}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(7),a=n(14),s=n(5),l=n(13),c=n(10),u=n(6),d=n(0),p=n(1);i.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=a.create(e.render.canvas):t&&t.element?n=a.create(t.element):(n=a.create(),d.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var o={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:c.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),collisionFilter:{category:1,mask:4294967295,group:0}},r=d.extend(o,t);return s.on(e,"beforeUpdate",(function(){var t=u.allBodies(e.world);i.update(r,t),i._triggerEvents(r)})),r},i.update=function(e,t){var n=e.mouse,i=e.constraint,a=e.body;if(0===n.button){if(i.bodyB)r.set(i.bodyB,!1),i.pointA=n.position;else for(var c=0;c1?1:0;uo.max.x&&(o.max.x=c.x),l.yo.max.y&&(o.max.y=c.y))}var d=o.max.x-o.min.x+2*n.x,p=o.max.y-o.min.y+2*n.y,f=e.canvas.height,v=e.canvas.width/f,y=d/p,m=1,g=1;y>v?g=y/v:m=v/y,e.options.hasBounds=!0,e.bounds.min.x=o.min.x,e.bounds.max.x=o.min.x+d*m,e.bounds.min.y=o.min.y,e.bounds.max.y=o.min.y+p*g,i&&(e.bounds.min.x+=.5*d-d*m*.5,e.bounds.max.x+=.5*d-d*m*.5,e.bounds.min.y+=.5*p-p*g*.5,e.bounds.max.y+=.5*p-p*g*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(u.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),u.setOffset(e.mouse,e.bounds.min))},i.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,i=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/i,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},i.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},i.world=function(e,t){var n,o=r.now(),d=e.engine,p=d.world,f=e.canvas,v=e.context,m=e.options,g=e.timing,x=a.allBodies(p),h=a.allConstraints(p),b=m.wireframes?m.wireframeBackground:m.background,S=[],w=[],A={timestamp:d.timing.timestamp};if(l.trigger(e,"beforeRender",A),e.currentBackground!==b&&y(e,b),v.globalCompositeOperation="source-in",v.fillStyle="transparent",v.fillRect(0,0,f.width,f.height),v.globalCompositeOperation="source-over",m.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;r1?1:0;s1?1:0;r1?1:0;r1?1:0;o0)){var u=i.activeContacts[0].vertex.x,d=i.activeContacts[0].vertex.y;2===i.activeContacts.length&&(u=(i.activeContacts[0].vertex.x+i.activeContacts[1].vertex.x)/2,d=(i.activeContacts[0].vertex.y+i.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(u-8*o.normal.x,d-8*o.normal.y):s.moveTo(u+8*o.normal.x,d+8*o.normal.y),s.lineTo(u,d)}l.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},i.separations=function(e,t,n){var i,o,r,a,s,l=n,c=e.options;for(l.beginPath(),s=0;se.deltaMax?e.deltaMax:i,e.delta=i);var s={timestamp:a.timestamp};o.trigger(e,"beforeTick",s),e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",s),o.trigger(e,"beforeUpdate",s),r.update(t,i),o.trigger(e,"afterUpdate",s),o.trigger(e,"afterTick",s)},i.stop=function(e){t(e.frameRequestId)},i.start=function(e,t){i.run(e,t)}}()},function(e,t,n){var i={};e.exports=i;var o=n(8),r=n(0).deprecated;i.collides=function(e,t){return o.collides(e,t)},r(i,"collides","SAT.collides ➤ replaced by Collision.collides")},function(e,t,n){var i={};e.exports=i;n(1);var o=n(0);i.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||o.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,a,s,l,c,u,d,p,f,v,y=[],m=0,g=0,x=0;t=t||15;var h=function(e,t,n){var i=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&i?(f=p.x,v=p.y):(f=0,v=0);var o={x:f+e,y:v+t};!i&&p||(p=o),y.push(o),g=f+e,x=v+t}},b=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":g=e.x,x=e.y;break;case"H":g=e.x;break;case"V":x=e.y}h(g,x,e.pathSegType)}};for(i._svgPathToAbsolute(e),a=e.getTotalLength(),c=[],n=0;n - + \ No newline at end of file diff --git a/demo/js/matter-demo.6283b1.min.js b/demo/js/matter-demo.6283b1.min.js new file mode 100644 index 0000000..9bb62fb --- /dev/null +++ b/demo/js/matter-demo.6283b1.min.js @@ -0,0 +1,6 @@ +/*! + * matter-demo bundle 0.19.0 by @liabru + * http://brm.io/matter-js/ + * License MIT + */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("MatterDemo",[],t):"object"==typeof exports?exports.MatterDemo=t():e.MatterDemo=t()}(this,(function(){return(this.webpackJsonpMatterDemo=this.webpackJsonpMatterDemo||[]).push([[0],{"+QOk":function(e,t,n){var r=r||{};r.timescale=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.Composite,a=Matter.Composites,s=Matter.Common,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,showAngleIndicator:!0}});t.run(m);var f=n.create();n.run(f,u),i.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var v=1,g=s.now();o.on(u,"afterUpdate",(function(e){var t=(e.delta||1e3/60)/1e3;u.timing.timeScale+=12*(v-u.timing.timeScale)*t,s.now()-g>=2e3&&(v=v<1?1:0,function(e,t){for(var n=1e3/60/t,o=i.allBodies(e.world),a=0;a=500){var l=.05*c.mass*n;r.applyForce(c,c.position,{x:(l+s.random()*l)*s.choose([1,-1]),y:-l+s.random()*-l})}}}(u,e.delta),g=s.now())}));var y={frictionAir:0,friction:1e-4,restitution:.8};i.add(p,a.stack(20,100,15,3,20,40,(function(e,t){return d.circle(e,t,s.random(10,20),y)}))),i.add(p,a.stack(50,50,8,3,0,0,(function(e,t){switch(Math.round(s.random(0,1))){case 0:return s.random()<.8?d.rectangle(e,t,s.random(20,50),s.random(20,50),y):d.rectangle(e,t,s.random(80,120),s.random(20,30),y);case 1:return d.polygon(e,t,Math.round(s.random(4,8)),s.random(20,50),y)}})));var x=l.create(m.canvas),h=c.create(u,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(p,h),m.mouse=x,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.timescale.title="Time Scaling",r.timescale.for=">=0.14.2",e.exports=r.timescale},"+jwT":function(e,t,n){var r=r||{};r.constraints=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=(Matter.Composites,Matter.Common,Matter.Constraint),o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=s.polygon(150,200,5,30),m=r.create({pointA:{x:150,y:100},bodyB:p,pointB:{x:-10,y:-10}});a.add(l,[p,m]);p=s.polygon(280,100,3,30),m=r.create({pointA:{x:280,y:120},bodyB:p,pointB:{x:-10,y:-7},stiffness:.001});a.add(l,[p,m]);p=s.polygon(400,100,4,30),m=r.create({pointA:{x:400,y:120},bodyB:p,pointB:{x:-10,y:-10},stiffness:.001,damping:.05});a.add(l,[p,m]);p=s.rectangle(600,200,200,20);var f=s.circle(550,150,20);m=r.create({pointA:{x:600,y:200},bodyB:p,length:0});a.add(l,[p,f,m]);p=s.rectangle(500,400,100,20,{collisionFilter:{group:-1}}),f=s.circle(600,400,20,{collisionFilter:{group:-1}}),m=r.create({bodyA:p,bodyB:f});a.add(l,[p,f,m]);var v=s.polygon(100,400,6,20),g=s.polygon(200,400,1,50);m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-10}});a.add(l,[v,g,m]);v=s.polygon(300,400,4,20),g=s.polygon(400,400,3,30),m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-7},stiffness:.001});a.add(l,[v,g,m]);v=s.polygon(500,400,6,30),g=s.polygon(600,400,7,60),m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-10},stiffness:.001,damping:.1});a.add(l,[v,g,m]),a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var y=i.create(d.canvas),x=o.create(c,{mouse:y,constraint:{angularStiffness:0,render:{visible:!1}}});return a.add(l,x),d.mouse=y,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.constraints.title="Constraints",r.constraints.for=">=0.14.2",e.exports=r.constraints},"/iAh":function(e,t,n){var r=r||{};r.svg=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Vertices,l=Matter.Svg,d=Matter.Bodies;o.setDecomp(n("Dded"));var u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600}});t.run(m);var f=r.create();if(r.run(f,u),"undefined"!=typeof fetch){var v=function(e,t){return Array.prototype.slice.call(e.querySelectorAll(t))},g=function(e){return fetch(e).then((function(e){return e.text()})).then((function(e){return(new window.DOMParser).parseFromString(e,"image/svg+xml")}))};["./svg/iconmonstr-check-mark-8-icon.svg","./svg/iconmonstr-paperclip-2-icon.svg","./svg/iconmonstr-puzzle-icon.svg","./svg/iconmonstr-user-icon.svg"].forEach((function(e,t){g(e).then((function(e){var n=o.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),r=v(e,"path").map((function(e){return c.scale(l.pathToVertices(e,30),.4,.4)}));s.add(p,d.fromVertices(100+150*t,200+50*t,r,{render:{fillStyle:n,strokeStyle:n,lineWidth:1}},!0))}))})),g("./svg/svg.svg").then((function(e){var t=o.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),n=v(e,"path").map((function(e){return l.pathToVertices(e,30)}));s.add(p,d.fromVertices(400,80,n,{render:{fillStyle:t,strokeStyle:t,lineWidth:1}},!0))}))}else o.warn("Fetch is not available. Could not load SVG.");s.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var y=a.create(m.canvas),x=i.create(u,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(p,x),m.mouse=y,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.svg.title="Concave SVG Paths",r.svg.for=">0.16.1",e.exports=r.svg},"02te":function(e,t,n){var r=r||{};r.ballPool=function(){try{"undefined"!=typeof MatterWrap?Matter.use("matter-wrap"):Matter.use(n("OPlj"))}catch(e){}var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composite,i=Matter.Composites,a=Matter.Common,s=Matter.MouseConstraint,c=Matter.Mouse,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0}});t.run(p);var m=r.create();r.run(m,d),o.add(u,[l.rectangle(400,600,1200,50.5,{isStatic:!0,render:{fillStyle:"#060a19"}})]);var f=i.stack(100,0,10,8,10,10,(function(e,t){return l.circle(e,t,a.random(15,30),{restitution:.6,friction:.1})}));o.add(u,[f,l.polygon(200,460,3,60),l.polygon(400,460,5,60),l.rectangle(600,460,80,80)]);var v=c.create(p.canvas),g=s.create(d,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});o.add(u,g),p.mouse=v,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}});for(var y=o.allBodies(u),x=0;x1;if(!p||e!=p.x||t!=p.y){p&&r?(m=p.x,f=p.y):(m=0,f=0);var o={x:m+e,y:f+t};!r&&p||(p=o),v.push(o),y=m+e,x=f+t}},b=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":y=e.x,x=e.y;break;case"H":y=e.x;break;case"V":x=e.y}h(y,x,e.pathSegType)}};for(r._svgPathToAbsolute(e),a=e.getTotalLength(),l=[],n=0;n0)return!1;a=n}return!0},r.scale=function(e,t,n,i){if(1===t&&1===n)return e;var a,s;i=i||r.centre(e);for(var c=0;c=0?c-1:e.length-1],d=e[c],u=e[(c+1)%e.length],p=t[c0&&(i|=2),3===i)return!1;return 0!==i||null},r.hull=function(e){var t,n,r=[],i=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];r.length>=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}return r.pop(),i.pop(),r.concat(i)}},"0mtl":function(e,t,n){var r=r||{};r.catapult=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Constraint,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=Matter.Body,d=Matter.Vector,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0,showVelocity:!0}});t.run(m);var f=n.create();n.run(f,u);var v=l.nextGroup(!0),g=r.stack(250,255,1,6,0,0,(function(e,t){return c.rectangle(e,t,30,30)})),y=c.rectangle(400,520,320,20,{collisionFilter:{group:v}});s.add(p,[g,y,c.rectangle(400,600,800,50.5,{isStatic:!0,render:{fillStyle:"#060a19"}}),c.rectangle(250,555,20,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),c.rectangle(400,535,20,80,{isStatic:!0,collisionFilter:{group:v},render:{fillStyle:"#060a19"}}),c.circle(560,100,50,{density:.005}),o.create({bodyA:y,pointB:d.clone(y.position),stiffness:1,length:0})]);var x=a.create(m.canvas),h=i.create(u,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(p,h),m.mouse=x,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.catapult.title="Catapult",r.catapult.for=">=0.14.2",e.exports=r.catapult},"136C":function(e,t,n){var r=r||{};r.slingshot=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Events,i=Matter.Constraint,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Body,l=Matter.Composite,d=Matter.Bodies,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,showAngleIndicator:!0}});t.run(m);var f=n.create();n.run(f,u);var v=d.rectangle(395,600,815,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),g={density:.004},y=d.polygon(170,450,8,20,g),x=i.create({pointA:{x:170,y:450},bodyB:y,length:.01,damping:.01,stiffness:.05}),h=r.pyramid(500,300,9,10,0,0,(function(e,t){return d.rectangle(e,t,25,40)})),b=d.rectangle(610,250,200,20,{isStatic:!0,render:{fillStyle:"#060a19"}}),M=r.pyramid(550,0,5,10,0,0,(function(e,t){return d.rectangle(e,t,25,40)}));l.add(u.world,[v,h,b,M,y,x]),o.on(u,"afterUpdate",(function(){-1===w.mouse.button&&(y.position.x>190||y.position.y<430)&&(c.getSpeed(y)>45&&c.setSpeed(y,45),y=d.polygon(170,450,7,20,g),l.add(u.world,y),x.bodyB=y)}));var S=s.create(m.canvas),w=a.create(u,{mouse:S,constraint:{stiffness:.2,render:{visible:!1}}});return l.add(p,w),m.mouse=S,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.slingshot.title="Slingshot",r.slingshot.for=">=0.14.2",e.exports=r.slingshot},"2Og8":function(e,t,n){var r={};e.exports=r;var o=n("571F");r._registry={},r.register=function(e){if(r.isPlugin(e)||o.warn("Plugin.register:",r.toString(e),"does not implement all required fields."),e.name in r._registry){var t=r._registry[e.name],n=r.versionParse(e.version).number,i=r.versionParse(t.version).number;n>i?(o.warn("Plugin.register:",r.toString(t),"was upgraded to",r.toString(e)),r._registry[e.name]=e):n-1},r.isFor=function(e,t){var n=e.for&&r.dependencyParse(e.for);return!e.for||t.name===n.name&&r.versionSatisfies(t.version,n.range)},r.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=r.dependencies(e),i=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",r.toString(e),"does not specify any dependencies to install.")},r.dependencies=function(e,t){var n=r.dependencyParse(e),i=n.name;if(!(i in(t=t||{}))){e=r.resolve(e)||e,t[i]=o.map(e.uses||[],(function(t){r.isPlugin(t)&&r.register(t);var i=r.dependencyParse(t),a=r.resolve(t);return a&&!r.versionSatisfies(a.version,i.range)?(o.warn("Plugin.dependencies:",r.toString(a),"does not satisfy",r.toString(i),"used by",r.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",r.toString(t),"used by",r.toString(n),"could not be resolved."),e._warned=!0),i.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),r=Number(n[4]),i=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:r,minor:i,patch:a,parts:[r,i,a],prerelease:n[7],number:1e8*r+1e4*i+a}},r.versionSatisfies=function(e,t){t=t||"*";var n=r.versionParse(t),o=r.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},"2oV2":function(e,t,n){var r=r||{};r.raycasting=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composite,i=Matter.Composites,a=Matter.Common,s=Matter.Query,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Events,u=Matter.Vertices,p=Matter.Bodies,m=e.create(),f=m.world,v=t.create({element:document.body,engine:m,options:{width:800,height:600,showAngleIndicator:!0}});t.run(v);var g=r.create();r.run(g,m);var y=i.stack(20,20,12,4,0,0,(function(e,t){switch(Math.round(a.random(0,1))){case 0:return a.random()<.8?p.rectangle(e,t,a.random(20,50),a.random(20,50)):p.rectangle(e,t,a.random(80,120),a.random(20,30));case 1:var n=Math.round(a.random(1,8));return n=3===n?4:n,p.polygon(e,t,n,a.random(20,50))}}));a.setDecomp(n("Dded"));var x=u.fromPath("50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38"),h=p.fromVertices(200,200,x);o.add(f,[y,h,p.rectangle(400,0,800,50,{isStatic:!0}),p.rectangle(400,600,800,50,{isStatic:!0}),p.rectangle(800,300,50,600,{isStatic:!0}),p.rectangle(0,300,50,600,{isStatic:!0})]);var b=[],M={x:400,y:100};d.on(m,"afterUpdate",(function(){var e=w.mouse,t=o.allBodies(m.world),n=e.position||{x:100,y:600};b=s.ray(t,M,n)})),d.on(v,"afterRender",(function(){var e=w.mouse,n=v.context,r=e.position||{x:100,y:600};t.startViewTransform(v),n.beginPath(),n.moveTo(M.x,M.y),n.lineTo(r.x,r.y),b.length>0?n.strokeStyle="#fff":n.strokeStyle="#555",n.lineWidth=.5,n.stroke();for(var o=0;o0.16.1",e.exports=r.raycasting},"3Slt":function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("571F"),a=n("Tgw/");r._restingThresh=2,r._restingThreshTangent=Math.sqrt(6),r._positionDampen=.9,r._positionWarming=.8,r._frictionNormalMultiplier=5,r._frictionMaxStatic=Number.MAX_VALUE,r.preSolvePosition=function(e){var t,n,r,o=e.length;for(t=0;tG?(o=q>0?q:-q,(n=v.friction*(q>0?1:-1)*l)<-o?n=-o:n>o&&(n=o)):(n=q,o=m);var N=E*S-T*M,z=F*S-V*M,Z=k/(R+y.inverseInertia*N*N+x.inverseInertia*z*z),Q=(1+v.restitution)*j*Z;if(n*=Z,j0&&(I.normalImpulse=0),Q=I.normalImpulse-X}if(q<-u||q>u)I.tangentImpulse=0;else{var Y=I.tangentImpulse;I.tangentImpulse+=n,I.tangentImpulse<-o&&(I.tangentImpulse=-o),I.tangentImpulse>o&&(I.tangentImpulse=o),n=I.tangentImpulse-Y}var J=M*Q+w*n,K=S*Q+C*n;y.isStatic||y.isSleeping||(y.positionPrev.x+=J*y.inverseMass,y.positionPrev.y+=K*y.inverseMass,y.anglePrev+=(E*K-T*J)*y.inverseInertia),x.isStatic||x.isSleeping||(x.positionPrev.x-=J*x.inverseMass,x.positionPrev.y-=K*x.inverseMass,x.anglePrev-=(F*K-V*J)*x.inverseInertia)}}}}},"4XQC":function(e,t,n){var r=r||{};r.staticFriction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Composites,i=Matter.Events,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showVelocity:!0}});t.run(p);var m=n.create();n.run(m,d);var f=l.rectangle(400,500,200,60,{isStatic:!0,chamfer:10,render:{fillStyle:"#060a19"}}),v=o.stack(350,170,1,6,0,0,(function(e,t){return l.rectangle(e,t,100,50,{slop:.5,friction:1,frictionStatic:1/0})}));c.add(u,[f,v,l.rectangle(400,0,800,50,{isStatic:!0}),l.rectangle(400,600,800,50,{isStatic:!0}),l.rectangle(800,300,50,600,{isStatic:!0}),l.rectangle(0,300,50,600,{isStatic:!0})]),i.on(d,"beforeUpdate",(function(){if(!(d.timing.timestamp<1500)){var e=400+100*Math.sin(.001*(d.timing.timestamp-1500));"0.18.0"===Matter.version&&r.setVelocity(f,{x:e-f.position.x,y:0}),r.setPosition(f,{x:e,y:f.position.y},!0)}}));var g=s.create(p.canvas),y=a.create(d,{mouse:g,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(u,y),p.mouse=g,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.staticFriction.title="Static Friction",r.staticFriction.for=">=0.14.2",e.exports=r.staticFriction},"4d8i":function(e,t,n){var r={};e.exports=r;var o=n("yTB+"),i=n("nIFq"),a=n("571F");!function(){var e,t,n;("undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),e)||(e=function(e){n=setTimeout((function(){e(a.now())}),1e3/60)},t=function(){clearTimeout(n)});r.create=function(e){var t=a.extend({fps:60,deltaSampleSize:60,counterTimestamp:0,frameCounter:0,deltaHistory:[],timePrev:null,frameRequestId:null,isFixed:!1,enabled:!0},e);return t.delta=t.delta||1e3/t.fps,t.deltaMin=t.deltaMin||1e3/t.fps,t.deltaMax=t.deltaMax||1e3/(.5*t.fps),t.fps=1e3/t.delta,t},r.run=function(t,n){return void 0!==t.positionIterations&&(n=t,t=r.create()),function o(i){t.frameRequestId=e(o),i&&t.enabled&&r.tick(t,n,i)}(),t},r.tick=function(e,t,n){var r,a=t.timing;e.isFixed?r=e.delta:(r=n-e.timePrev||e.delta,e.timePrev=n,e.deltaHistory.push(r),e.deltaHistory=e.deltaHistory.slice(-e.deltaSampleSize),r=(r=(r=Math.min.apply(null,e.deltaHistory))e.deltaMax?e.deltaMax:r,e.delta=r);var s={timestamp:a.timestamp};o.trigger(e,"beforeTick",s),e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",s),o.trigger(e,"beforeUpdate",s),i.update(t,r),o.trigger(e,"afterUpdate",s),o.trigger(e,"afterTick",s)},r.stop=function(e){t(e.frameRequestId)},r.start=function(e,t){r.run(e,t)}}()},"52dP":function(e,t,n){var r=r||{};r.terrain=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Query,d=Matter.Svg,u=Matter.Bodies;i.setDecomp(n("Dded"));var p=e.create(),m=p.world,f=t.create({element:document.body,engine:p,options:{width:800,height:600}});t.run(f);var v,g=r.create();if(r.run(g,p),"undefined"!=typeof fetch){(v="./svg/terrain.svg",fetch(v).then((function(e){return e.text()})).then((function(e){return(new window.DOMParser).parseFromString(e,"image/svg+xml")}))).then((function(e){var t=function(e,t){return Array.prototype.slice.call(e.querySelectorAll(t))}(e,"path").map((function(e){return d.pathToVertices(e,30)})),n=u.fromVertices(400,350,t,{isStatic:!0,render:{fillStyle:"#060a19",strokeStyle:"#060a19",lineWidth:1}},!0);c.add(m,n);var r={frictionAir:0,friction:1e-4,restitution:.6};c.add(m,o.stack(80,100,20,20,10,10,(function(e,t){if(0===l.point([n],{x:e,y:t}).length)return u.polygon(e,t,5,12,r)})))}))}else i.warn("Fetch is not available. Could not load SVG.");var y=s.create(f.canvas),x=a.create(p,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(m,x),f.mouse=y,t.lookAt(f,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:p,runner:g,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(g)}}},r.terrain.title="Terrain",r.terrain.for=">0.16.1",e.exports=r.terrain},"571F":function(e,t){var n={};e.exports=n,function(){n._baseDelta=1e3/60,n._nextId=0,n._seed=0,n._nowStartTime=+new Date,n._warnedOnce={},n._decomp=null,n.extend=function(e,t){var r,o;"boolean"==typeof t?(r=2,o=t):(r=1,o=!0);for(var i=r;i0;t--){var r=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[r],e[r]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,r){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",r)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;n=0.14.2",e.exports=r.pyramid},"6IAi":function(e,t,n){var r=r||{};r.airFriction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showVelocity:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(200,100,60,60,{frictionAir:.001}),a.rectangle(400,100,60,60,{frictionAir:.05}),a.rectangle(600,100,60,60,{frictionAir:.1}),a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.airFriction.title="Air Friction",r.airFriction.for=">=0.14.2",e.exports=r.airFriction},"71Xj":function(e,t,n){var r=n("akk5");e.exports={demo:function(e,t){var n=r.Demo.create({toolbar:{title:"matter-js"+(t?" ・ dev":""),url:"https://github.com/liabru/matter-js",reset:!0,source:!0,inspector:!0,tools:!0,fullscreen:!0,exampleSelect:!0},tools:{inspector:!0,gui:!0},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!0,startExample:"mixed",examples:e});if(window.MatterDemoInstance=n,document.body.appendChild(n.dom.root),document.title="Matter.js Demo"+(t?" ・ Dev":""),t){var o=n.dom.buttonSource,i=o.cloneNode(!0);i.textContent="⎄",i.title="Compare",i.href="?compare",i.target="",i.className="matter-btn matter-btn-compare",i.addEventListener("click",(function(e){window.location="?compare#"+n.example.id,e.preventDefault()})),o.parentNode.insertBefore(i,o.nextSibling),Matter.before("Render.create",(function(e){e.options.showDebug=!0}))}r.Demo.start(n)}}},"74MQ":function(e,t,n){var r=r||{};r.doublePendulum=function(){var e=Matter.Engine,t=Matter.Events,n=Matter.Render,r=Matter.Runner,o=Matter.Body,i=Matter.Composite,a=Matter.Composites,s=Matter.Constraint,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=Matter.Vector,p=e.create(),m=p.world,f=n.create({element:document.body,engine:p,options:{width:800,height:600,wireframes:!1}});n.run(f);var v=r.create();r.run(v,p);var g=o.nextGroup(!0),y=a.stack(350,160,2,1,-20,0,(function(e,t){return d.rectangle(e,t,200,25,{collisionFilter:{group:g},frictionAir:0,chamfer:5,render:{fillStyle:"transparent",lineWidth:1}})}));p.gravity.scale=.002,a.chain(y,.45,0,-.45,0,{stiffness:.9,length:0,angularStiffness:.7,render:{strokeStyle:"#4a485b"}}),i.add(y,s.create({bodyB:y.bodies[0],pointB:{x:-84,y:0},pointA:{x:y.bodies[0].position.x-84,y:y.bodies[0].position.y},stiffness:.9,length:0,render:{strokeStyle:"#4a485b"}}));var x=y.bodies[1];o.rotate(x,.3*-Math.PI,{x:x.position.x-100,y:x.position.y}),i.add(m,y);var h=[];t.on(f,"afterRender",(function(){h.unshift({position:u.clone(x.position),speed:x.speed}),n.startViewTransform(f),f.context.globalAlpha=.7;for(var e=0;e2e3&&h.pop()}));var b=l.create(f.canvas),M=c.create(p,{mouse:b,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(m,M),f.mouse=b,n.lookAt(f,{min:{x:0,y:0},max:{x:700,y:600}}),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.doublePendulum.title="Double Pendulum",r.doublePendulum.for=">0.16.1",e.exports=r.doublePendulum},"7MJU":function(e,t,n){var r=r||{};r.gravity=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showVelocity:!0,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50.5,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]),l.gravity.y=-1;var m=r.stack(50,120,11,5,0,0,(function(e,t){switch(Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(20,50),o.random(20,50)):c.rectangle(e,t,o.random(80,120),o.random(20,30));case 1:return c.polygon(e,t,Math.round(o.random(1,8)),o.random(20,50))}}));s.add(d,m);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.gravity.title="Reverse Gravity",r.gravity.for=">0.16.1",e.exports=r.gravity},"9K63":function(e,t){var n={};e.exports=n,n.create=function(e){return{vertex:e,normalImpulse:0,tangentImpulse:0}}},"9Nbg":function(e,t,n){var r={};e.exports=r;var o=n("wAS/"),i=n("ga9t"),a=n("571F"),s=n("IbIC"),c=n("oT59"),l=a.deprecated;r.stack=function(e,t,n,r,i,a,c){for(var l,d=o.create({label:"Stack"}),u=e,p=t,m=0,f=0;fv&&(v=x),s.translate(y,{x:.5*h,y:.5*x}),u=y.bounds.max.x+i,o.addBody(d,y),l=y,m+=1}else u+=i}p+=v+a,u=e}return d},r.chain=function(e,t,n,r,s,c){for(var l=e.bodies,d=1;d0)for(l=0;l0&&(p=m[l-1+(c-1)*t],o.addConstraint(e,i.create(a.extend({bodyA:p,bodyB:u},s)))),r&&lp||a<(l=p-l)||a>n-1-l))return 1===u&&s.translate(d,{x:(a+(n%2==1?1:-1))*m,y:0}),c(e+(d?a*m:0)+a*i,r,a,l,d,u)}))},r.newtonsCradle=function(e,t,n,r,a){for(var s=o.create({label:"Newtons Cradle"}),l=0;l=0.14.2",e.exports=r.avalanche},"C6Q+":function(e,t,n){var r=r||{};r.events=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.Composite,a=Matter.Composites,s=Matter.Common,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,wireframes:!1}});t.run(m);var f=n.create();n.run(f,u),o.on(p,"afterAdd",(function(e){}));var v=s.now();o.on(u,"beforeUpdate",(function(e){var t=e.source;s.now()-v>=5e3&&(x(t),v=s.now())})),o.on(u,"collisionStart",(function(e){for(var t=e.pairs,n=0;n=500){var c=.03*a.mass*t;r.applyForce(a,a.position,{x:(c+s.random()*c)*s.choose([1,-1]),y:-c+s.random()*-c})}}},h=l.create(m.canvas),b=c.create(u,{mouse:h,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(p,b),m.mouse=h,o.on(b,"mousedown",(function(e){var t=e.mouse.position;console.log("mousedown at "+t.x+" "+t.y),x(u)})),o.on(b,"mouseup",(function(e){var t=e.mouse.position;console.log("mouseup at "+t.x+" "+t.y)})),o.on(b,"startdrag",(function(e){console.log("startdrag",e)})),o.on(b,"enddrag",(function(e){console.log("enddrag",e)})),t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.events.title="Events",r.events.for=">=0.14.2",e.exports=r.events},Czbd:function(e,t,n){var r=r||{};r.softBody=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=(Matter.Composites,Matter.MouseConstraint),i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!1}});t.run(d);var u=n.create();n.run(u,c);var p={friction:.05,frictionStatic:.1,render:{visible:!0}};a.add(l,[r.softBody.softBody(250,100,5,5,0,0,!0,18,p),r.softBody.softBody(400,300,8,3,0,0,!0,15,p),r.softBody.softBody(250,400,4,4,0,0,!0,15,p),s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.9,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.softBody.title="Soft Body",r.softBody.for=">=0.14.2",r.softBody.softBody=function(e,t,n,r,o,i,a,s,c,l){var d=Matter.Common,u=Matter.Composites,p=Matter.Bodies;c=d.extend({inertia:1/0},c),l=d.extend({stiffness:.2,render:{type:"line",anchors:!1}},l);var m=u.stack(e,t,n,r,o,i,(function(e,t){return p.circle(e,t,s,c)}));return u.mesh(m,n,r,a,l),m.label="Soft Body",m},e.exports=r.softBody},DeYi:function(e,t,n){var r=r||{};r.friction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showVelocity:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]),i.add(c,[a.rectangle(300,180,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,70,40,40,{friction:.001})]),i.add(c,[a.rectangle(300,350,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,250,40,40,{friction:5e-4})]),i.add(c,[a.rectangle(300,520,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,430,40,40,{friction:0})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.friction.title="Friction",r.friction.for=">=0.14.2",e.exports=r.friction},DqtB:function(e,t,n){var r={};e.exports=r;var o=n("Z/YF"),i=n("571F").deprecated;r.collides=function(e,t){return o.collides(e,t)},i(r,"collides","SAT.collides ➤ replaced by Collision.collides")},EUdY:function(e,t,n){var r=r||{};r.stress=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(90,50,18,15,0,0,(function(e,t){return s.rectangle(e,t,35,35)}));a.add(l,[p,s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.stress.title="Stress",r.stress.for=">=0.14.2",e.exports=r.stress},H5X8:function(e,t,n){var r=r||{};r.stress3=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create({positionIterations:10,velocityIterations:10}),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(u);var p=n.create({isFixed:!0});n.run(p,l);var m=.3,f=r.stack(40,40,38,18,0,0,(function(e,t){var n=Math.round(o.random(1,8));switch(Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50)*m,o.random(25,50)*m):c.rectangle(e,t,o.random(80,120)*m,o.random(25,30)*m);case 1:return c.polygon(e,t,n,o.random(25,50)*m)}}));s.add(d,f),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.stress3.title="Stress 3",r.stress3.for=">=0.14.2",e.exports=r.stress3},I5nt:function(e,t,n){var r={};e.exports=r;var o=n("571F");r.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},r.setElement(t,t.element),t},r.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},r.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},r.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},r.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},r._getRelativeMousePosition=function(e,t,n){var r,o,i=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,c=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,l=e.changedTouches;return l?(r=l[0].pageX-i.left-s,o=l[0].pageY-i.top-c):(r=e.pageX-i.left-s,o=e.pageY-i.top-c),{x:r/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},IOLg:function(e,t,n){var r=r||{};r.concave=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Vertices,d=Matter.Bodies;i.setDecomp(n("Dded"));var u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600}});t.run(m);var f=r.create();r.run(f,u),c.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var v=l.fromPath("40 0 40 20 100 20 100 80 40 80 40 100 0 50"),g=l.fromPath("100 0 75 50 100 100 25 100 0 50 25 0"),y=l.fromPath("50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38"),x=l.fromPath("35 7 19 17 14 38 14 58 25 79 45 85 65 84 65 66 46 67 34 59 30 44 33 29 45 23 66 23 66 7 53 7"),h=o.stack(50,50,6,4,10,10,(function(e,t){var n=i.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]);return d.fromVertices(e,t,i.choose([v,g,y,x]),{render:{fillStyle:n,strokeStyle:n,lineWidth:1}},!0)}));c.add(p,h);var b=s.create(m.canvas),M=a.create(u,{mouse:b,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(p,M),m.mouse=b,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.concave.title="Concave",r.concave.for=">0.16.1",e.exports=r.concave},IbIC:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("m6Dm"),a=n("yw0d"),s=n("571F"),c=n("Tgw/"),l=n("JKEF");!function(){r._timeCorrection=!0,r._inertiaScale=4,r._nextCollidingGroupId=1,r._nextNonCollidingGroupId=-1,r._nextCategory=1,r._baseDelta=1e3/60,r.create=function(t){var n={id:s.nextId(),type:"body",label:"Body",parts:[],plugin:{},angle:0,vertices:o.fromPath("L 0 0 L 40 0 L 40 40 L 0 40"),position:{x:0,y:0},force:{x:0,y:0},torque:0,positionImpulse:{x:0,y:0},constraintImpulse:{x:0,y:0,angle:0},totalContacts:0,speed:0,angularSpeed:0,velocity:{x:0,y:0},angularVelocity:0,isSensor:!1,isStatic:!1,isSleeping:!1,motion:0,sleepThreshold:60,density:.001,restitution:0,friction:.1,frictionStatic:.5,frictionAir:.01,collisionFilter:{category:1,mask:4294967295,group:0},slop:.05,timeScale:1,render:{visible:!0,opacity:1,strokeStyle:null,fillStyle:null,lineWidth:null,sprite:{xScale:1,yScale:1,xOffset:0,yOffset:0}},events:null,bounds:null,chamfer:null,circleRadius:0,positionPrev:null,anglePrev:0,parent:null,axes:null,area:0,mass:0,inertia:0,deltaTime:1e3/60,_original:null},r=s.extend(n,t);return e(r,t),r},r.nextGroup=function(e){return e?r._nextNonCollidingGroupId--:r._nextCollidingGroupId++},r.nextCategory=function(){return r._nextCategory=r._nextCategory<<1,r._nextCategory};var e=function(e,t){t=t||{},r.set(e,{bounds:e.bounds||c.create(e.vertices),positionPrev:e.positionPrev||i.clone(e.position),anglePrev:e.anglePrev||e.angle,vertices:e.vertices,parts:e.parts||[e],isStatic:e.isStatic,isSleeping:e.isSleeping,parent:e.parent||e}),o.rotate(e.vertices,e.angle,e.position),l.rotate(e.axes,e.angle),c.update(e.bounds,e.vertices,e.velocity),r.set(e,{axes:t.axes||e.axes,area:t.area||e.area,mass:t.mass||e.mass,inertia:t.inertia||e.inertia});var n=e.isStatic?"#14151f":s.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),a=e.isStatic?"#555":"#ccc",d=e.isStatic&&null===e.render.fillStyle?1:0;e.render.fillStyle=e.render.fillStyle||n,e.render.strokeStyle=e.render.strokeStyle||a,e.render.lineWidth=e.render.lineWidth||d,e.render.sprite.xOffset+=-(e.bounds.min.x-e.position.x)/(e.bounds.max.x-e.bounds.min.x),e.render.sprite.yOffset+=-(e.bounds.min.y-e.position.y)/(e.bounds.max.y-e.bounds.min.y)};r.set=function(e,t,n){var o;for(o in"string"==typeof t&&(o=t,(t={})[o]=n),t)if(Object.prototype.hasOwnProperty.call(t,o))switch(n=t[o],o){case"isStatic":r.setStatic(e,n);break;case"isSleeping":a.set(e,n);break;case"mass":r.setMass(e,n);break;case"density":r.setDensity(e,n);break;case"inertia":r.setInertia(e,n);break;case"vertices":r.setVertices(e,n);break;case"position":r.setPosition(e,n);break;case"angle":r.setAngle(e,n);break;case"velocity":r.setVelocity(e,n);break;case"angularVelocity":r.setAngularVelocity(e,n);break;case"speed":r.setSpeed(e,n);break;case"angularSpeed":r.setAngularSpeed(e,n);break;case"parts":r.setParts(e,n);break;case"centre":r.setCentre(e,n);break;default:e[o]=n}},r.setStatic=function(e,t){for(var n=0;n0&&i.rotateAbout(s.position,r,e.position,s.position)}},r.setVelocity=function(e,t){var n=e.deltaTime/r._baseDelta;e.positionPrev.x=e.position.x-t.x*n,e.positionPrev.y=e.position.y-t.y*n,e.velocity.x=(e.position.x-e.positionPrev.x)/n,e.velocity.y=(e.position.y-e.positionPrev.y)/n,e.speed=i.magnitude(e.velocity)},r.getVelocity=function(e){var t=r._baseDelta/e.deltaTime;return{x:(e.position.x-e.positionPrev.x)*t,y:(e.position.y-e.positionPrev.y)*t}},r.getSpeed=function(e){return i.magnitude(r.getVelocity(e))},r.setSpeed=function(e,t){r.setVelocity(e,i.mult(i.normalise(r.getVelocity(e)),t))},r.setAngularVelocity=function(e,t){var n=e.deltaTime/r._baseDelta;e.anglePrev=e.angle-t*n,e.angularVelocity=(e.angle-e.anglePrev)/n,e.angularSpeed=Math.abs(e.angularVelocity)},r.getAngularVelocity=function(e){return(e.angle-e.anglePrev)*r._baseDelta/e.deltaTime},r.getAngularSpeed=function(e){return Math.abs(r.getAngularVelocity(e))},r.setAngularSpeed=function(e,t){r.setAngularVelocity(e,s.sign(r.getAngularVelocity(e))*t)},r.translate=function(e,t,n){r.setPosition(e,i.add(e.position,t),n)},r.rotate=function(e,t,n,o){if(n){var i=Math.cos(t),a=Math.sin(t),s=e.position.x-n.x,c=e.position.y-n.y;r.setPosition(e,{x:n.x+(s*i-c*a),y:n.y+(s*a+c*i)},o),r.setAngle(e,e.angle+t,o)}else r.setAngle(e,e.angle+t,o)},r.scale=function(e,t,n,i){var a=0,s=0;i=i||e.position;for(var d=0;d0&&(a+=u.area,s+=u.inertia),u.position.x=i.x+(u.position.x-i.x)*t,u.position.y=i.y+(u.position.y-i.y)*n,c.update(u.bounds,u.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(r.setMass(e,e.density*a),r.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},r.update=function(e,t){var n=(t=(void 0!==t?t:1e3/60)*e.timeScale)*t,a=r._timeCorrection?t/(e.deltaTime||t):1,d=1-e.frictionAir*(t/s._baseDelta),u=(e.position.x-e.positionPrev.x)*a,p=(e.position.y-e.positionPrev.y)*a;e.velocity.x=u*d+e.force.x/e.mass*n,e.velocity.y=p*d+e.force.y/e.mass*n,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.deltaTime=t,e.angularVelocity=(e.angle-e.anglePrev)*d*a+e.torque/e.inertia*n,e.anglePrev=e.angle,e.angle+=e.angularVelocity;for(var m=0;m0&&(f.position.x+=e.velocity.x,f.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(f.vertices,e.angularVelocity,e.position),l.rotate(f.axes,e.angularVelocity),m>0&&i.rotateAbout(f.position,e.angularVelocity,e.position,f.position)),c.update(f.bounds,f.vertices,e.velocity)}},r.updateVelocities=function(e){var t=r._baseDelta/e.deltaTime,n=e.velocity;n.x=(e.position.x-e.positionPrev.x)*t,n.y=(e.position.y-e.positionPrev.y)*t,e.speed=Math.sqrt(n.x*n.x+n.y*n.y),e.angularVelocity=(e.angle-e.anglePrev)*t,e.angularSpeed=Math.abs(e.angularVelocity)},r.applyForce=function(e,t,n){var r=t.x-e.position.x,o=t.y-e.position.y;e.force.x+=n.x,e.force.y+=n.y,e.torque+=r*n.y-o*n.x},r._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n=0.14.2",e.exports=r.sleeping},LS1c:function(e,t,n){var r=r||{};r.wreckingBall=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Constraint,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(400,175,5,10,0,0,(function(e,t){return c.rectangle(e,t,40,40)}));a.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=c.circle(100,400,50,{density:.04,frictionAir:.005});a.add(d,f),a.add(d,s.create({pointA:{x:300,y:100},bodyB:f}));var v=i.create(u.canvas),g=o.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.wreckingBall.title="Wrecking Ball",r.wreckingBall.for=">=0.14.2",e.exports=r.wreckingBall},Me0I:function(e,t,n){var r=r||{};r.car=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=(Matter.Composites,Matter.MouseConstraint),i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0}});t.run(d);var u=n.create();n.run(u,c),a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var p=.9;a.add(l,r.car.car(150,100,150*p,30*p,30*p)),p=.8,a.add(l,r.car.car(350,300,150*p,30*p,30*p)),a.add(l,[s.rectangle(200,150,400,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),s.rectangle(500,350,650,20,{isStatic:!0,angle:.06*-Math.PI,render:{fillStyle:"#060a19"}}),s.rectangle(300,560,600,20,{isStatic:!0,angle:.04*Math.PI,render:{fillStyle:"#060a19"}})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.car.title="Car",r.car.for=">=0.14.2",r.car.car=function(e,t,n,r,o){var i=Matter.Body,a=Matter.Bodies,s=Matter.Composite,c=Matter.Constraint,l=i.nextGroup(!0),d=.5*-n+20,u=.5*n-20,p=s.create({label:"Car"}),m=a.rectangle(e,t,n,r,{collisionFilter:{group:l},chamfer:{radius:.5*r},density:2e-4}),f=a.circle(e+d,t+0,o,{collisionFilter:{group:l},friction:.8}),v=a.circle(e+u,t+0,o,{collisionFilter:{group:l},friction:.8}),g=c.create({bodyB:m,pointB:{x:d,y:0},bodyA:f,stiffness:1,length:0}),y=c.create({bodyB:m,pointB:{x:u,y:0},bodyA:v,stiffness:1,length:0});return s.addBody(p,m),s.addBody(p,f),s.addBody(p,v),s.addConstraint(p,g),s.addConstraint(p,y),p},e.exports=r.car},MhOg:function(e,t,n){var r=r||{};r.views=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Events,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Vector,d=Matter.Bounds,u=Matter.Bodies,p=e.create(),m=p.world,f=t.create({element:document.body,engine:p,options:{width:800,height:600,hasBounds:!0,showAngleIndicator:!0}});t.run(f);var v=n.create();n.run(v,p);var g=s.create(f.canvas),y=a.create(p,{mouse:g,constraint:{stiffness:.2,render:{visible:!1}}});c.add(m,y),f.mouse=g;var x=o.stack(20,20,10,4,0,0,(function(e,t){switch(Math.round(i.random(0,1))){case 0:return i.random()<.8?u.rectangle(e,t,i.random(20,50),i.random(20,50)):u.rectangle(e,t,i.random(80,120),i.random(20,30));case 1:var n=Math.round(i.random(1,8));return n=3===n?4:n,u.polygon(e,t,n,i.random(20,50))}}));c.add(m,[x,u.rectangle(400,0,800,50,{isStatic:!0}),u.rectangle(400,600,800,50,{isStatic:!0}),u.rectangle(800,300,50,600,{isStatic:!0}),u.rectangle(0,300,50,600,{isStatic:!0})]);var h={x:.5*f.options.width,y:.5*f.options.height},b={x:-300,y:-300},M={x:1100,y:900},S=1,w={x:1,y:1};return r.on(f,"beforeRender",(function(){p.world;var e,t=y.mouse,n=-.1*t.wheelDelta;0!==n&&(n<0&&w.x>=.6||n>0&&w.x<=1.4)&&(S+=n),Math.abs(w.x-S)>.01&&(n=.2*(S-w.x),w.x+=n,w.y+=n,f.bounds.max.x=f.bounds.min.x+f.options.width*w.x,f.bounds.max.y=f.bounds.min.y+f.options.height*w.y,e={x:f.options.width*n*-.5,y:f.options.height*n*-.5},d.translate(f.bounds,e),s.setScale(t,w),s.setOffset(t,f.bounds.min));var r=l.sub(t.absolute,h),o=l.magnitude(r);if(o>50){var i=l.normalise(r),a=Math.min(10,2e-4*Math.pow(o-50,2));e=l.mult(i,a),f.bounds.min.x+e.xM.x&&(e.x=M.x-f.bounds.max.x),f.bounds.min.y+e.yM.y&&(e.y=M.y-f.bounds.max.y),d.translate(f.bounds,e),s.setOffset(t,f.bounds.min)}})),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.views.title="Views",r.views.for=">=0.14.2",e.exports=r.views},NDQ1:function(e,t,n){var r={};e.exports=r;var o=n("m6Dm"),i=n("Z/YF"),a=n("Tgw/"),s=n("oT59"),c=n("0kzT");r.collides=function(e,t){for(var n=[],r=t.length,o=e.bounds,s=i.collides,c=a.overlaps,l=0;ld.bounds.max.x||m.bounds.max.yd.bounds.max.y))){var f=r._getRegion(e,m);if(!m.region||f.id!==m.region.id||o){m.region&&!o||(m.region=f);var v=r._regionUnion(f,m.region);for(a=v.startCol;a<=v.endCol;a++)for(s=v.startRow;s<=v.endRow;s++){c=u[l=r._getBucketId(a,s)];var g=a>=f.startCol&&a<=f.endCol&&s>=f.startRow&&s<=f.endRow,y=a>=m.region.startCol&&a<=m.region.endCol&&s>=m.region.startRow&&s<=m.region.endRow;!g&&y&&y&&c&&r._bucketRemoveBody(e,c,m),(m.region===f||g&&!y||o)&&(c||(c=r._createBucket(u,l)),r._bucketAddBody(e,c,m))}m.region=f,p=!0}}}p&&(e.pairsList=r._createActivePairsList(e))},a(r,"update","Grid.update ➤ replaced by Matter.Detector"),r.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},a(r,"clear","Grid.clear ➤ replaced by Matter.Detector"),r._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),i=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return r._createRegion(n,o,i,a)},r._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),i=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return r._createRegion(o,i,a,s)},r._createRegion=function(e,t,n,r){return{id:e+","+t+","+n+","+r,startCol:e,endCol:t,startRow:n,endRow:r}},r._getBucketId=function(e,t){return"C"+e+"R"+t},r._createBucket=function(e,t){return e[t]=[]},r._bucketAddBody=function(e,t,n){var r,i=e.pairs,a=o.id,s=t.length;for(r=0;r0?s.push(t):delete r[o[n]];return s}},"Tgw/":function(e,t){var n={};e.exports=n,n.create=function(e){var t={min:{x:0,y:0},max:{x:0,y:0}};return e&&n.update(t,e),t},n.update=function(e,t,n){e.min.x=1/0,e.max.x=-1/0,e.min.y=1/0,e.max.y=-1/0;for(var r=0;re.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,r=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+r}},VZUp:function(e,t,n){var r=r||{};r.manipulation=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAxes:!0,showCollisions:!0,showConvexHulls:!0}});t.run(u);var p=n.create();n.run(p,l);var m=c.rectangle(100,300,50,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),f=c.rectangle(200,200,50,50),v=c.rectangle(300,200,50,50),g=c.rectangle(400,200,50,50),y=c.rectangle(550,200,50,50),x=c.rectangle(700,200,50,50),h=c.circle(400,100,25,{render:{fillStyle:"#060a19"}}),b=c.rectangle(600,200,96,40,{render:{fillStyle:"#060a19"}}),M=c.rectangle(660,200,40,152,{render:{fillStyle:"#060a19"}}),S=r.create({parts:[b,M],isStatic:!0});r.setPosition(S,{x:600,y:300}),s.add(d,[m,f,v,g,y,x,h,S]),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var w=0,C=.6;o.on(l,"beforeUpdate",(function(e){var t=(e.delta||1e3/60)/1e3;C>0&&(r.scale(x,1+C*t,1+C*t),y.vertices[0].x-=.2*t,y.vertices[0].y-=.2*t,y.vertices[1].x+=.2*t,y.vertices[1].y-=.2*t,r.setVertices(y,y.vertices));var n=300+100*Math.sin(.002*l.timing.timestamp);"0.18.0"===Matter.version&&(r.setVelocity(m,{x:0,y:n-m.position.y}),r.setVelocity(S,{x:0,y:n-S.position.y}),r.setAngularVelocity(S,1*Math.PI*t)),r.setPosition(m,{x:100,y:n},!0),r.setPosition(S,{x:600,y:n},!0),r.rotate(S,1*Math.PI*t,null,!0),l.timing.timestamp>=800&&r.setStatic(h,!0),l.timing.timestamp-w>=1500&&(r.setVelocity(f,{x:0,y:-10}),r.setAngle(v,.26*-Math.PI),r.setAngularVelocity(g,.2),C=0,w=l.timing.timestamp)}));var A=a.create(u.canvas),B=i.create(l,{mouse:A,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,B),u.mouse=A,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.manipulation.title="Manipulation",r.manipulation.for=">=0.14.2",e.exports=r.manipulation},Vyp4:function(e,t,n){var r=r||{};r.remove=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=Matter.Events,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0}});t.run(p);var m=n.create();n.run(m,d);var f=null,v=0,g=function(){return r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}))};l.on(d,"afterUpdate",(function(e){f&&e.timestamp-v<800||(v=e.timestamp,f&&s.remove(u,f),f=g(),s.add(u,f))})),s.add(u,g()),s.add(u,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var y=a.create(p.canvas),x=i.create(d,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(u,x),p.mouse=y,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.remove.title="Composite Remove",r.remove.for=">=0.14.2",e.exports=r.remove},"Z/YF":function(e,t,n){var r={};e.exports=r;var o,i,a,s=n("0kzT"),c=n("t8gT");o=[],i={overlap:0,axis:null},a={overlap:0,axis:null},r.create=function(e,t){return{pair:null,collided:!1,bodyA:e,bodyB:t,parentA:e.parent,parentB:t.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},r.collides=function(e,t,n){if(r._overlapAxes(i,e.vertices,t.vertices,e.axes),i.overlap<=0)return null;if(r._overlapAxes(a,t.vertices,e.vertices,t.axes),a.overlap<=0)return null;var o,l,d=n&&n.table[c.id(e,t)];d?o=d.collision:((o=r.create(e,t)).collided=!0,o.bodyA=e.idC?C=s:sA?A=s:so?o=a:a=0.14.2",e.exports=r.restitution},ZUN1:function(e,t,n){var r=r||{};r.chains=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Composite,i=Matter.Composites,a=Matter.Constraint,s=Matter.MouseConstraint,c=Matter.Mouse,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0,showVelocity:!0}});t.run(p);var m=n.create();n.run(m,d);var f=r.nextGroup(!0),v=i.stack(100,50,8,1,10,10,(function(e,t){return l.rectangle(e,t,50,20,{collisionFilter:{group:f}})}));i.chain(v,.5,0,-.5,0,{stiffness:.8,length:2,render:{type:"line"}}),o.add(v,a.create({bodyB:v.bodies[0],pointB:{x:-25,y:0},pointA:{x:v.bodies[0].position.x,y:v.bodies[0].position.y},stiffness:.5})),f=r.nextGroup(!0);var g=i.stack(350,50,10,1,10,10,(function(e,t){return l.circle(e,t,20,{collisionFilter:{group:f}})}));i.chain(g,.5,0,-.5,0,{stiffness:.8,length:2,render:{type:"line"}}),o.add(g,a.create({bodyB:g.bodies[0],pointB:{x:-20,y:0},pointA:{x:g.bodies[0].position.x,y:g.bodies[0].position.y},stiffness:.5})),f=r.nextGroup(!0);var y=i.stack(600,50,13,1,10,10,(function(e,t){return l.rectangle(e-20,t,50,20,{collisionFilter:{group:f},chamfer:5})}));i.chain(y,.3,0,-.3,0,{stiffness:1,length:0}),o.add(y,a.create({bodyB:y.bodies[0],pointB:{x:-20,y:0},pointA:{x:y.bodies[0].position.x,y:y.bodies[0].position.y},stiffness:.5})),o.add(u,[v,g,y,l.rectangle(400,600,1200,50.5,{isStatic:!0})]);var x=c.create(p.canvas),h=s.create(d,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return o.add(u,h),p.mouse=x,t.lookAt(p,{min:{x:0,y:0},max:{x:700,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.chains.title="Chains",r.chains.for=">=0.14.2",e.exports=r.chains},Zo9v:function(e,t,n){var r=r||{};r.collisionFiltering=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composite,o=Matter.Composites,i=(Matter.Common,Matter.MouseConstraint),a=Matter.Mouse,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,wireframes:!1}});t.run(d);var u=n.create();n.run(u,c);var p="#f55a3c",m="#063e7b",f="#f5d259";r.add(l,s.rectangle(400,600,900,50,{isStatic:!0,render:{fillStyle:"transparent",lineWidth:1}})),r.add(l,o.stack(275,100,5,9,10,10,(function(e,t,n,r){var o=2,i=p;return r>5?(o=8,i=m):r>2&&(o=4,i=f),s.circle(e,t,20,{collisionFilter:{category:o},render:{strokeStyle:i,fillStyle:"transparent",lineWidth:1}})}))),r.add(l,s.circle(310,40,30,{collisionFilter:{mask:5},render:{fillStyle:f}})),r.add(l,s.circle(400,40,30,{collisionFilter:{mask:3},render:{fillStyle:p}})),r.add(l,s.circle(480,40,30,{collisionFilter:{mask:9},render:{fillStyle:m}}));var v=a.create(d.canvas),g=i.create(c,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return r.add(l,g),d.mouse=v,g.collisionFilter.mask=13,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.collisionFiltering.title="Collision Filtering",r.collisionFiltering.for=">=0.14.2",e.exports=r.collisionFiltering},ZpbE:function(e,t,n){var r=r||{};r.stack=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(200,380.75,10,5,0,0,(function(e,t){return s.rectangle(e,t,40,40)}));a.add(l,[p,s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0}),s.rectangle(400,606,800,50.5,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.stack.title="Stack",r.stack.for=">=0.14.2",e.exports=r.stack},"a+ms":function(e,t,n){var r=n("akk5"),o=n("lniP"),i=n("lniP");e.exports={compare:function(e,t){var n=r.Demo.create({toolbar:{title:"matter-js ・ "+(t?"dev":"")+" ・ comparing to "+i.version,url:"https://github.com/liabru/matter-js",reset:!0,source:!0,inspector:!1,tools:!1,fullscreen:!0,exampleSelect:!0},tools:{inspector:!1,gui:!1},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!0,startExample:!1,examples:e}),a=r.Demo.create({toolbar:{title:"matter-js-compare-build",reset:!1,source:!1,inspector:!1,tools:!1,fullscreen:!1,exampleSelect:!1},tools:{inspector:!1,gui:!1},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!1,startExample:!1,examples:e.map((function(e){return Matter.Common.extend({},e)}))});i.Runner.run=function(){},i.Render.run=function(){},o.Runner._tick=o.Runner.tick,o.Render._world=o.Render.world,i.Mouse._setElement=i.Mouse.setElement,r.Demo._setExample=r.Demo.setExample,r.Demo.setExample=function(e,t){i.Common._nextId=i.Common._seed=0,o.Common._nextId=o.Common._seed=0,i.Plugin._registry=o.Plugin._registry,i.use.apply(null,o.used),window.Matter=o,r.Demo._setExample(n,n.examples.find((function(e){return e.name===t.name})));var s=parseFloat(window.location.search.split("=")[1]),c=0;o.Runner.tick=function(e,t,n){if(-1!==c){if(c>=s)return console.info("Demo.Compare: ran "+c+" ticks, timestamp is now "+t.timing.timestamp.toFixed(2)),void(c=-1);c+=1;var r=a.example.instance;return e.isFixed=r.runner.isFixed=!0,e.delta=r.runner.delta=1e3/60,window.Matter=i,i.Runner.tick(r.runner,r.engine,n),window.Matter=o,o.Runner._tick(e,t,n)}},o.Render.world=function(e){return window.Matter=i,i.Render.world(a.example.instance.render),window.Matter=o,o.Render._world(e)},i.Mouse.setElement=function(e){return i.Mouse._setElement(e,n.example.instance.render.canvas)},window.Matter=i,r.Demo._setExample(a,a.examples.find((function(e){return e.name===t.name}))),window.Matter=o},r.Demo._reset=r.Demo.reset,r.Demo.reset=function(e){i.Common._nextId=i.Common._seed=0,o.Common._nextId=o.Common._seed=0,window.Matter=i,r.Demo._reset(a),window.Matter=o,r.Demo._reset(n)},document.body.appendChild(n.dom.root),document.body.appendChild(a.dom.root),r.Demo.start(n),document.title="Matter.js Compare"+(t?" ・ Dev":""),console.info("Demo.Compare: matter-js@"+o.version+" with matter-js@"+i.version)}}},a3OZ:function(e,t,n){var r=r||{};r.compositeManipulation=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Events,o=Matter.Composite,i=Matter.Composites,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l),o.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.stack(200,200,4,4,0,0,(function(e,t){return c.rectangle(e,t,40,40)}));o.add(d,m),l.gravity.y=0,r.on(l,"afterUpdate",(function(e){var t=l.timing.timestamp,n=(e.delta||1e3/60)/1e3;o.translate(m,{x:10*Math.sin(.001*t)*n,y:0}),o.rotate(m,.75*Math.sin(.001*t)*n,{x:300,y:300});var r=1+.75*Math.sin(.001*t)*n;o.scale(m,r,r,{x:300,y:300})}));var f=s.create(u.canvas),v=a.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return o.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.compositeManipulation.title="Composite Manipulation",r.compositeManipulation.for=">0.16.1",e.exports=r.compositeManipulation},c7us:function(e,t,n){var r=r||{};r.ragdoll=function(){var e=Matter.Engine,t=Matter.Events,n=Matter.Render,o=Matter.Runner,i=Matter.Body,a=Matter.Common,s=Matter.Composite,c=Matter.Composites,l=Matter.MouseConstraint,d=Matter.Mouse,u=Matter.Bodies,p=e.create(),m=p.world,f=n.create({element:document.body,engine:p,options:{width:800,height:600,showAngleIndicator:!0}});n.run(f);var v=o.create();o.run(v,p);for(var g=(f.bounds.max.y-f.bounds.min.y)/50,y=c.stack(0,0,g+2,1,0,0,(function(e,t,n){return u.rectangle(e-50,t+50*n,100,1e3,{isStatic:!0,render:{fillStyle:"#060a19",strokeStyle:"#ffffff",lineWidth:1}})})),x=c.stack(300,0,15,3,10,10,(function(e,t,n){var r=Math.round(a.random(1,8)),o={render:{fillStyle:a.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"])}};switch(Math.round(a.random(0,1))){case 0:return a.random()<.8?u.rectangle(e,t,a.random(25,50),a.random(25,50),o):u.rectangle(e,t,a.random(80,120),a.random(25,30),o);case 1:return u.polygon(e,t,r,a.random(25,50),o)}})),h=s.create(),b=0;b<1;b+=1){var M=r.ragdoll.ragdoll(200,-1e3*b,1.3);s.add(h,M)}s.add(m,[y,x,h]);var S=1,w=a.now();t.on(p,"afterUpdate",(function(e){var t=(e.delta||1e3/60)/1e3;-1===C.button?p.timing.timeScale+=3*(S-p.timing.timeScale)*t:p.timing.timeScale=1,a.now()-w>=2e3&&(S=S<1?1:.05,w=a.now());for(var n=0;nf.bounds.max.y+100&&s.translate(o,{x:.9*-c.min.x,y:-f.bounds.max.y-400})}for(n=0;nf.bounds.max.y+100&&i.translate(r,{x:-c.min.x,y:-f.bounds.max.y-300})}}));var C=d.create(f.canvas),A=l.create(p,{mouse:C,constraint:{stiffness:.6,length:0,angularStiffness:0,render:{visible:!1}}});return s.add(m,A),f.mouse=C,n.lookAt(f,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.ragdoll.ragdoll=function(e,t,n,r){n=void 0===n?1:n;var o=Matter.Body,i=Matter.Bodies,a=Matter.Constraint,s=Matter.Composite,c=Matter.Common,l=c.extend({label:"head",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:[15*n,15*n,15*n,15*n]},render:{fillStyle:"#FFBC42"}},r),d=c.extend({label:"chest",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:[20*n,20*n,26*n,26*n]},render:{fillStyle:"#E0A423"}},r),u=c.extend({label:"left-arm",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),p=c.extend({},u,{render:{fillStyle:"#E59B12"}}),m=c.extend({label:"right-arm",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),f=c.extend({},m,{render:{fillStyle:"#E59B12"}}),v=c.extend({label:"left-leg",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),g=c.extend({},v,{render:{fillStyle:"#E59B12"}}),y=c.extend({label:"right-leg",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),x=c.extend({},y,{render:{fillStyle:"#E59B12"}}),h=i.rectangle(e,t-60*n,34*n,40*n,l),b=i.rectangle(e,t,55*n,80*n,d),M=i.rectangle(e+39*n,t-15*n,20*n,40*n,m),S=i.rectangle(e+39*n,t+25*n,20*n,60*n,f),w=i.rectangle(e-39*n,t-15*n,20*n,40*n,u),C=i.rectangle(e-39*n,t+25*n,20*n,60*n,p),A=i.rectangle(e-20*n,t+57*n,20*n,40*n,v),B=i.rectangle(e-20*n,t+97*n,20*n,60*n,g),k=i.rectangle(e+20*n,t+57*n,20*n,40*n,y),R=i.rectangle(e+20*n,t+97*n,20*n,60*n,x),P=a.create({bodyA:b,pointA:{x:24*n,y:-23*n},pointB:{x:0,y:-8*n},bodyB:M,stiffness:.6,render:{visible:!1}}),I=a.create({bodyA:b,pointA:{x:-24*n,y:-23*n},pointB:{x:0,y:-8*n},bodyB:w,stiffness:.6,render:{visible:!1}}),_=a.create({bodyA:b,pointA:{x:-10*n,y:30*n},pointB:{x:0,y:-10*n},bodyB:A,stiffness:.6,render:{visible:!1}}),E=a.create({bodyA:b,pointA:{x:10*n,y:30*n},pointB:{x:0,y:-10*n},bodyB:k,stiffness:.6,render:{visible:!1}}),T=a.create({bodyA:M,bodyB:S,pointA:{x:0,y:15*n},pointB:{x:0,y:-25*n},stiffness:.6,render:{visible:!1}}),F=a.create({bodyA:w,bodyB:C,pointA:{x:0,y:15*n},pointB:{x:0,y:-25*n},stiffness:.6,render:{visible:!1}}),V=a.create({bodyA:A,bodyB:B,pointA:{x:0,y:20*n},pointB:{x:0,y:-20*n},stiffness:.6,render:{visible:!1}}),D=a.create({bodyA:k,bodyB:R,pointA:{x:0,y:20*n},pointB:{x:0,y:-20*n},stiffness:.6,render:{visible:!1}}),L=a.create({bodyA:h,pointA:{x:0,y:25*n},pointB:{x:0,y:-35*n},bodyB:b,stiffness:.6,render:{visible:!1}}),O=a.create({bodyA:B,bodyB:R,stiffness:.01,render:{visible:!1}});return s.create({bodies:[b,h,C,w,S,M,B,R,A,k],constraints:[F,T,I,P,L,V,D,_,E,O]})},r.ragdoll.title="Ragdoll",r.ragdoll.for=">=0.14.2",e.exports=r.ragdoll},djnZ:function(e,t,n){var r=r||{};r.compound=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Constraint,i=Matter.Composite,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAxes:!0,showConvexHulls:!0}});t.run(u);var p=n.create();n.run(p,l);var m=200,f=200,v=200,g=c.rectangle(f,v,m,m/5),y=c.rectangle(f,v,m/5,m,{render:g.render}),x=r.create({parts:[g,y]});m=150,f=400,v=300;var h=c.circle(f,v,30),b=c.circle(f+m,v,30),M=c.circle(f+m,v+m,30),S=c.circle(f,v+m,30),w=r.create({parts:[h,b,M,S]}),C=o.create({pointA:{x:400,y:100},bodyB:w,pointB:{x:0,y:0}});i.add(d,[x,w,C,c.rectangle(400,600,800,50.5,{isStatic:!0})]);var A=s.create(u.canvas),B=a.create(l,{mouse:A,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(d,B),u.mouse=A,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.compound.title="Compound Bodies",r.compound.for=">=0.14.2",e.exports=r.compound},elWf:function(e,t,n){var r=r||{};r.rounded=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showAxes:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]),i.add(c,[a.rectangle(200,200,100,100,{chamfer:{radius:20}}),a.rectangle(300,200,100,100,{chamfer:{radius:[90,0,0,0]}}),a.rectangle(400,200,200,200,{chamfer:{radius:[150,20,40,20]}}),a.rectangle(200,200,200,200,{chamfer:{radius:[150,20,150,20]}}),a.rectangle(300,200,200,50,{chamfer:{radius:[25,25,0,0]}}),a.polygon(200,100,8,80,{chamfer:{radius:30}}),a.polygon(300,100,5,80,{chamfer:{radius:[10,40,20,40,10]}}),a.polygon(400,200,3,50,{chamfer:{radius:[20,0,20]}})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.rounded.title="Rounded Corners (Chamfering)",r.rounded.for=">=0.14.2",e.exports=r.rounded},ga9t:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("m6Dm"),a=n("yw0d"),s=n("Tgw/"),c=n("JKEF"),l=n("571F");r._warming=.4,r._torqueDampen=1,r._minLength=1e-6,r.create=function(e){var t=e;t.bodyA&&!t.pointA&&(t.pointA={x:0,y:0}),t.bodyB&&!t.pointB&&(t.pointB={x:0,y:0});var n=t.bodyA?i.add(t.bodyA.position,t.pointA):t.pointA,r=t.bodyB?i.add(t.bodyB.position,t.pointB):t.pointB,o=i.magnitude(i.sub(n,r));t.length=void 0!==t.length?t.length:o,t.id=t.id||l.nextId(),t.label=t.label||"Constraint",t.type="constraint",t.stiffness=t.stiffness||(t.length>0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=l.extend(a,t.render),t},r.preSolveAll=function(e){for(var t=0;t=1||0===e.length?e.stiffness*t:e.stiffness*t*t,h=e.damping*t,b=i.mult(d,y*x),M=(n?n.inverseMass:0)+(o?o.inverseMass:0),S=M+((n?n.inverseInertia:0)+(o?o.inverseInertia:0));if(h>0){var w=i.create();f=i.div(d,u),g=i.sub(o&&i.sub(o.position,o.positionPrev)||w,n&&i.sub(n.position,n.positionPrev)||w),v=i.dot(f,g)}n&&!n.isStatic&&(m=n.inverseMass/M,n.constraintImpulse.x-=b.x*m,n.constraintImpulse.y-=b.y*m,n.position.x-=b.x*m,n.position.y-=b.y*m,h>0&&(n.positionPrev.x-=h*f.x*v*m,n.positionPrev.y-=h*f.y*v*m),p=i.cross(a,b)/S*r._torqueDampen*n.inverseInertia*(1-e.angularStiffness),n.constraintImpulse.angle-=p,n.angle-=p),o&&!o.isStatic&&(m=o.inverseMass/M,o.constraintImpulse.x+=b.x*m,o.constraintImpulse.y+=b.y*m,o.position.x+=b.x*m,o.position.y+=b.y*m,h>0&&(o.positionPrev.x+=h*f.x*v*m,o.positionPrev.y+=h*f.y*v*m),p=i.cross(s,b)/S*r._torqueDampen*o.inverseInertia*(1-e.angularStiffness),o.constraintImpulse.angle+=p,o.angle+=p)}}},r.postSolveAll=function(e){for(var t=0;t0&&(u.position.x+=l.x,u.position.y+=l.y),0!==l.angle&&(o.rotate(u.vertices,l.angle,n.position),c.rotate(u.axes,l.angle),d>0&&i.rotateAbout(u.position,l.angle,n.position,u.position)),s.update(u.bounds,u.vertices,n.velocity)}l.angle*=r._warming,l.x*=r._warming,l.y*=r._warming}}},r.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+(e.pointA?e.pointA.x:0),y:(e.bodyA?e.bodyA.position.y:0)+(e.pointA?e.pointA.y:0)}},r.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+(e.pointB?e.pointB.x:0),y:(e.bodyB?e.bodyB.position.y:0)+(e.pointB?e.pointB.y:0)}}},ibhy:function(e,t,n){var r=r||{};r.mixed=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}));s.add(d,m),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.mixed.title="Mixed Shapes",r.mixed.for=">=0.14.2",e.exports=r.mixed},"ix+/":function(e,t,n){var r={};e.exports=r;var o=n("571F"),i=n("Z/YF");r.create=function(e){return o.extend({bodies:[],pairs:null},e)},r.setBodies=function(e,t){e.bodies=t.slice(0)},r.clear=function(e){e.bodies=[]},r.collisions=function(e){var t,n,o=[],a=e.pairs,s=e.bodies,c=s.length,l=r.canCollide,d=i.collides;for(s.sort(r._compareBoundsX),t=0;tm)break;if(!(fk.max.y)&&(!g||!h.isStatic&&!h.isSleeping)&&l(u.collisionFilter,h.collisionFilter)){var b=h.parts.length;if(x&&1===b)(A=d(u,h,a))&&o.push(A);else for(var M=b>1?1:0,S=y>1?1:0;Sk.max.x||p.max.xk.max.y||(A=d(w,B,a))&&o.push(A)}}}}return o},r.canCollide=function(e,t){return e.group===t.group&&0!==e.group?e.group>0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)},r._compareBoundsX=function(e,t){return e.bounds.min.x-t.bounds.min.x}},k7Ch:function(e,t,n){var r=r||{};r.gyro=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}));if(s.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]),"undefined"!=typeof window){var f=function(e){var t=void 0!==window.orientation?window.orientation:0,n=l.gravity;0===t?(n.x=o.clamp(e.gamma,-90,90)/90,n.y=o.clamp(e.beta,-90,90)/90):180===t?(n.x=o.clamp(e.gamma,-90,90)/90,n.y=o.clamp(-e.beta,-90,90)/90):90===t?(n.x=o.clamp(e.beta,-90,90)/90,n.y=o.clamp(-e.gamma,-90,90)/90):-90===t&&(n.x=o.clamp(-e.beta,-90,90)/90,n.y=o.clamp(e.gamma,-90,90)/90)};window.addEventListener("deviceorientation",f)}var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p),"undefined"!=typeof window&&window.removeEventListener("deviceorientation",f)}}},r.gyro.title="Gyroscope",r.gyro.for=">=0.14.2",e.exports=r.gyro},lWug:function(e,t,n){var r={};e.exports=r;var o=n("IbIC"),i=n("571F"),a=n("wAS/"),s=n("Tgw/"),c=n("yTB+"),l=n("m6Dm"),d=n("I5nt");!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout((function(){e(i.now())}),1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),r._goodFps=30,r._goodDelta=1e3/60,r.create=function(e){var t={engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,timing:{historySize:60,delta:0,deltaHistory:[],lastTime:0,lastTimestamp:0,lastElapsed:0,timestampElapsed:0,timestampElapsedHistory:[],engineDeltaHistory:[],engineElapsedHistory:[],elapsedHistory:[]},options:{width:800,height:600,pixelRatio:1,background:"#14151f",wireframeBackground:"#14151f",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showStats:!1,showPerformance:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},n=i.extend(t,e);return n.canvas&&(n.canvas.width=n.options.width||n.canvas.width,n.canvas.height=n.options.height||n.canvas.height),n.mouse=e.mouse,n.engine=e.engine,n.canvas=n.canvas||p(n.options.width,n.options.height),n.context=n.canvas.getContext("2d"),n.textures={},n.bounds=n.bounds||{min:{x:0,y:0},max:{x:n.canvas.width,y:n.canvas.height}},n.controller=r,n.options.showBroadphase=!1,1!==n.options.pixelRatio&&r.setPixelRatio(n,n.options.pixelRatio),i.isElement(n.element)&&n.element.appendChild(n.canvas),n},r.run=function(t){!function o(i){t.frameRequestId=e(o),n(t,i),r.world(t,i),(t.options.showStats||t.options.showDebug)&&r.stats(t,t.context,i),(t.options.showPerformance||t.options.showDebug)&&r.performance(t,t.context,i)}()},r.stop=function(e){t(e.frameRequestId)},r.setPixelRatio=function(e,t){var n=e.options,r=e.canvas;"auto"===t&&(t=m(r)),n.pixelRatio=t,r.setAttribute("data-pixel-ratio",t),r.width=n.width*t,r.height=n.height*t,r.style.width=n.width+"px",r.style.height=n.height+"px"},r.lookAt=function(e,t,n,r){r=void 0===r||r,t=i.isArray(t)?t:[t],n=n||{x:0,y:0};for(var o={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},a=0;ao.max.x&&(o.max.x=l.x),c.yo.max.y&&(o.max.y=l.y))}var u=o.max.x-o.min.x+2*n.x,p=o.max.y-o.min.y+2*n.y,m=e.canvas.height,f=e.canvas.width/m,v=u/p,g=1,y=1;v>f?y=v/f:g=f/v,e.options.hasBounds=!0,e.bounds.min.x=o.min.x,e.bounds.max.x=o.min.x+u*g,e.bounds.min.y=o.min.y,e.bounds.max.y=o.min.y+p*y,r&&(e.bounds.min.x+=.5*u-u*g*.5,e.bounds.max.x+=.5*u-u*g*.5,e.bounds.min.y+=.5*p-p*y*.5,e.bounds.max.y+=.5*p-p*y*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(d.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),d.setOffset(e.mouse,e.bounds.min))},r.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,r=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/r,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},r.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},r.world=function(e,t){var n,o=i.now(),u=e.engine,p=u.world,m=e.canvas,f=e.context,g=e.options,y=e.timing,x=a.allBodies(p),h=a.allConstraints(p),b=g.wireframes?g.wireframeBackground:g.background,M=[],S=[],w={timestamp:u.timing.timestamp};if(c.trigger(e,"beforeRender",w),e.currentBackground!==b&&v(e,b),f.globalCompositeOperation="source-in",f.fillStyle="transparent",f.fillRect(0,0,m.width,m.height),f.globalCompositeOperation="source-over",g.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;i1?1:0;s1?1:0;i1?1:0;i1?1:0;o0)){var d=r.activeContacts[0].vertex.x,u=r.activeContacts[0].vertex.y;2===r.activeContacts.length&&(d=(r.activeContacts[0].vertex.x+r.activeContacts[1].vertex.x)/2,u=(r.activeContacts[0].vertex.y+r.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(d-8*o.normal.x,u-8*o.normal.y):s.moveTo(d+8*o.normal.x,u+8*o.normal.y),s.lineTo(d,u)}c.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},r.separations=function(e,t,n){var r,o,i,a,s,c=n,l=e.options;for(c.beginPath(),s=0;s0&&r._bodiesUpdate(h,t),d.preSolveAll(h),n=0;n0&&c.trigger(e,"collisionStart",{pairs:v.collisionStart});var S=u.clamp(20/e.positionIterations,0,1);for(i.preSolvePosition(v.list),n=0;n0&&c.trigger(e,"collisionActive",{pairs:v.collisionActive}),v.collisionEnd.length>0&&c.trigger(e,"collisionEnd",{pairs:v.collisionEnd}),r._bodiesClearForces(h),c.trigger(e,"afterUpdate",x),e.timing.lastElapsed=u.now()-p,e},r.merge=function(e,t){if(u.extend(e,t),t.world){e.world=t.world,r.clear(e);for(var n=l.allBodies(e.world),i=0;i0&&o.area(B)1?(f=a.create(i.extend({parts:v.slice(0)},r)),a.setPosition(f,{x:e,y:t}),f):v[0]}},"pm/U":function(e,t,n){var r={};e.exports=r;var o=n("2Og8"),i=n("571F");r.name="matter-js",r.version="*",r.uses=[],r.used=[],r.use=function(){o.use(r,Array.prototype.slice.call(arguments))},r.before=function(e,t){return e=e.replace(/^Matter./,""),i.chainPathBefore(r,e,t)},r.after=function(e,t){return e=e.replace(/^Matter./,""),i.chainPathAfter(r,e,t)}},q4y7:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("yw0d"),a=n("I5nt"),s=n("yTB+"),c=n("ix+/"),l=n("ga9t"),d=n("wAS/"),u=n("571F"),p=n("Tgw/");r.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=a.create(e.render.canvas):t&&t.element?n=a.create(t.element):(n=a.create(),u.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var o={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:l.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),collisionFilter:{category:1,mask:4294967295,group:0}},i=u.extend(o,t);return s.on(e,"beforeUpdate",(function(){var t=d.allBodies(e.world);r.update(i,t),r._triggerEvents(i)})),i},r.update=function(e,t){var n=e.mouse,r=e.constraint,a=e.body;if(0===n.button){if(r.bodyB)i.set(r.bodyB,!1),r.pointA=n.position;else for(var l=0;l1?1:0;d=0.14.2",r.cloth.cloth=function(e,t,n,r,o,i,a,s,c,l){var d=Matter.Body,u=Matter.Bodies,p=Matter.Common,m=Matter.Composites,f=d.nextGroup(!0);c=p.extend({inertia:1/0,friction:1e-5,collisionFilter:{group:f},render:{visible:!1}},c),l=p.extend({stiffness:.06,render:{type:"line",anchors:!1}},l);var v=m.stack(e,t,n,r,o,i,(function(e,t){return u.circle(e,t,s,c)}));return m.mesh(v,n,r,a,l),v.label="Cloth Body",v},e.exports=r.cloth},t8gT:function(e,t,n){var r={};e.exports=r;var o=n("9K63");r.create=function(e,t){var n=e.bodyA,o=e.bodyB,i={id:r.id(n,o),bodyA:n,bodyB:o,collision:e,contacts:[],activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:n.isSensor||o.isSensor,timeCreated:t,timeUpdated:t,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return r.update(i,e,t),i},r.update=function(e,t,n){var r=e.contacts,i=t.supports,a=e.activeContacts,s=t.parentA,c=t.parentB,l=s.vertices.length;e.isActive=!0,e.timeUpdated=n,e.collision=t,e.separation=t.depth,e.inverseMass=s.inverseMass+c.inverseMass,e.friction=s.frictionc.frictionStatic?s.frictionStatic:c.frictionStatic,e.restitution=s.restitution>c.restitution?s.restitution:c.restitution,e.slop=s.slop>c.slop?s.slop:c.slop,t.pair=e,a.length=0;for(var d=0;d.35?c.rectangle(e,t,64,64,{render:{strokeStyle:"#ffffff",sprite:{texture:"./img/box.png"}}}):c.circle(e,t,46,{density:5e-4,frictionAir:.06,restitution:.3,friction:.01,render:{sprite:{texture:"./img/ball.png"}}})}));s.add(d,f);var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.sprites.title="Sprites",r.sprites.for=">=0.14.2",e.exports=r.sprites},ttsO:function(e,t,n){var r={};e.exports=r;var o=n("t8gT"),i=n("571F");r.create=function(e){return i.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},r.update=function(e,t,n){var r,i,a,s,c=e.list,l=c.length,d=e.table,u=t.length,p=e.collisionStart,m=e.collisionEnd,f=e.collisionActive;for(p.length=0,m.length=0,f.length=0,s=0;s=0?i(s,false):a(s,false)},vSND:function(e,t,n){var r=r||{};r.stats=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Common,o=Matter.Composites,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.World,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(u);var p=n.create();n.run(p,l);var m=o.stack(70,30,13,9,5,5,(function(e,t){return c.circle(e,t,10+20*r.random())}));s.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.stats.title="Stats & Performance",r.stats.for=">=0.16.1",e.exports=r.stats},"wAS/":function(e,t,n){var r={};e.exports=r;var o=n("yTB+"),i=n("571F"),a=n("Tgw/"),s=n("IbIC");r.create=function(e){return i.extend({id:i.nextId(),type:"composite",parent:null,isModified:!1,bodies:[],constraints:[],composites:[],label:"Composite",plugin:{},cache:{allBodies:null,allConstraints:null,allComposites:null}},e)},r.setModified=function(e,t,n,o){if(e.isModified=t,t&&e.cache&&(e.cache.allBodies=null,e.cache.allConstraints=null,e.cache.allComposites=null),n&&e.parent&&r.setModified(e.parent,t,n,o),o)for(var i=0;i=0.14.2",e.exports=r.bridge},xoNv:function(e,t,n){var r=r||{};r.newtonsCradle=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=Matter.Body,i=(Matter.Composites,Matter.MouseConstraint),a=Matter.Mouse,s=Matter.Composite,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showVelocity:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.newtonsCradle.newtonsCradle(280,100,5,30,200);s.add(l,p),o.translate(p.bodies[0],{x:-180,y:-100}),p=r.newtonsCradle.newtonsCradle(280,380,7,20,140),s.add(l,p),o.translate(p.bodies[0],{x:-140,y:-100});var m=a.create(d.canvas),f=i.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:50},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.newtonsCradle.title="Newton's Cradle",r.newtonsCradle.for=">=0.14.2",r.newtonsCradle.newtonsCradle=function(e,t,n,r,o){for(var i=Matter.Composite,a=Matter.Constraint,s=Matter.Bodies,c=i.create({label:"Newtons Cradle"}),l=0;l0){n||(n={}),r=t.split(" ");for(var l=0;l=0.14.2",e.exports=r.sensors},yw0d:function(e,t,n){var r={};e.exports=r;var o=n("IbIC"),i=n("yTB+"),a=n("571F");r._motionWakeThreshold=.18,r._motionSleepThreshold=.08,r._minBias=.9,r.update=function(e,t){for(var n=t/a._baseDelta,i=r._motionSleepThreshold,s=0;s0&&c.motion=c.sleepThreshold/n&&r.set(c,!0)):c.sleepCounter>0&&(c.sleepCounter-=1)}else r.set(c,!1)}},r.afterCollisions=function(e){for(var t=r._motionSleepThreshold,n=0;nt&&r.set(c,!1)}}}},r.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||i.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&i.trigger(e,"sleepEnd"))}},zc7U:function(e,t,n){var r=r||{};r.circleStack=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(100,179,10,10,20,0,(function(e,t){return s.circle(e,t,20)}));a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0}),p]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.circleStack.title="Circle Stack",r.circleStack.for=">=0.14.2",e.exports=r.circleStack}},[["uZME",1,2,3,4,5]]])})); \ No newline at end of file diff --git a/demo/js/matter-demo.a280d3.min.js b/demo/js/matter-demo.a280d3.min.js deleted file mode 100644 index 584548f..0000000 --- a/demo/js/matter-demo.a280d3.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * matter-demo bundle 0.18.0 by @liabru - * http://brm.io/matter-js/ - * License MIT - */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("MatterDemo",[],t):"object"==typeof exports?exports.MatterDemo=t():e.MatterDemo=t()}(this,(function(){return(this.webpackJsonpMatterDemo=this.webpackJsonpMatterDemo||[]).push([[0],{"+QOk":function(e,t,n){var r=r||{};r.timescale=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.Composite,a=Matter.Composites,s=Matter.Common,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,showAngleIndicator:!0}});t.run(m);var f=n.create();n.run(f,u),i.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var v=1,g=0;o.on(u,"afterUpdate",(function(e){u.timing.timeScale+=.05*(v-u.timing.timeScale),(g+=1)>=90&&(v=v<1?1:.05,function(e){for(var t=i.allBodies(e.world),n=0;n=500){var a=.05*o.mass;r.applyForce(o,o.position,{x:(a+s.random()*a)*s.choose([1,-1]),y:-a+s.random()*-a})}}}(u),g=0)}));var y={frictionAir:0,friction:1e-4,restitution:.8};i.add(p,a.stack(20,100,15,3,20,40,(function(e,t){return d.circle(e,t,s.random(10,20),y)}))),i.add(p,a.stack(50,50,8,3,0,0,(function(e,t){switch(Math.round(s.random(0,1))){case 0:return s.random()<.8?d.rectangle(e,t,s.random(20,50),s.random(20,50),y):d.rectangle(e,t,s.random(80,120),s.random(20,30),y);case 1:return d.polygon(e,t,Math.round(s.random(4,8)),s.random(20,50),y)}})));var x=l.create(m.canvas),h=c.create(u,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(p,h),m.mouse=x,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.timescale.title="Time Scaling",r.timescale.for=">=0.14.2",e.exports=r.timescale},"+jwT":function(e,t,n){var r=r||{};r.constraints=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=(Matter.Composites,Matter.Common,Matter.Constraint),o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=s.polygon(150,200,5,30),m=r.create({pointA:{x:150,y:100},bodyB:p,pointB:{x:-10,y:-10}});a.add(l,[p,m]);p=s.polygon(280,100,3,30),m=r.create({pointA:{x:280,y:120},bodyB:p,pointB:{x:-10,y:-7},stiffness:.001});a.add(l,[p,m]);p=s.polygon(400,100,4,30),m=r.create({pointA:{x:400,y:120},bodyB:p,pointB:{x:-10,y:-10},stiffness:.001,damping:.05});a.add(l,[p,m]);p=s.rectangle(600,200,200,20);var f=s.circle(550,150,20);m=r.create({pointA:{x:600,y:200},bodyB:p,length:0});a.add(l,[p,f,m]);p=s.rectangle(500,400,100,20,{collisionFilter:{group:-1}}),f=s.circle(600,400,20,{collisionFilter:{group:-1}}),m=r.create({bodyA:p,bodyB:f});a.add(l,[p,f,m]);var v=s.polygon(100,400,6,20),g=s.polygon(200,400,1,50);m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-10}});a.add(l,[v,g,m]);v=s.polygon(300,400,4,20),g=s.polygon(400,400,3,30),m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-7},stiffness:.001});a.add(l,[v,g,m]);v=s.polygon(500,400,6,30),g=s.polygon(600,400,7,60),m=r.create({bodyA:v,pointA:{x:-10,y:-10},bodyB:g,pointB:{x:-10,y:-10},stiffness:.001,damping:.1});a.add(l,[v,g,m]),a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var y=i.create(d.canvas),x=o.create(c,{mouse:y,constraint:{angularStiffness:0,render:{visible:!1}}});return a.add(l,x),d.mouse=y,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.constraints.title="Constraints",r.constraints.for=">=0.14.2",e.exports=r.constraints},"/iAh":function(e,t,n){var r=r||{};r.svg=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Vertices,l=Matter.Svg,d=Matter.Bodies;o.setDecomp(n("Dded"));var u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600}});t.run(m);var f=r.create();if(r.run(f,u),"undefined"!=typeof fetch){var v=function(e,t){return Array.prototype.slice.call(e.querySelectorAll(t))},g=function(e){return fetch(e).then((function(e){return e.text()})).then((function(e){return(new window.DOMParser).parseFromString(e,"image/svg+xml")}))};["./svg/iconmonstr-check-mark-8-icon.svg","./svg/iconmonstr-paperclip-2-icon.svg","./svg/iconmonstr-puzzle-icon.svg","./svg/iconmonstr-user-icon.svg"].forEach((function(e,t){g(e).then((function(e){var n=o.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),r=v(e,"path").map((function(e){return c.scale(l.pathToVertices(e,30),.4,.4)}));s.add(p,d.fromVertices(100+150*t,200+50*t,r,{render:{fillStyle:n,strokeStyle:n,lineWidth:1}},!0))}))})),g("./svg/svg.svg").then((function(e){var t=o.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),n=v(e,"path").map((function(e){return l.pathToVertices(e,30)}));s.add(p,d.fromVertices(400,80,n,{render:{fillStyle:t,strokeStyle:t,lineWidth:1}},!0))}))}else o.warn("Fetch is not available. Could not load SVG.");s.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var y=a.create(m.canvas),x=i.create(u,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(p,x),m.mouse=y,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.svg.title="Concave SVG Paths",r.svg.for=">0.16.1",e.exports=r.svg},"02te":function(e,t,n){var r=r||{};r.ballPool=function(){try{"undefined"!=typeof MatterWrap?Matter.use("matter-wrap"):Matter.use(n("OPlj"))}catch(e){}var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composite,i=Matter.Composites,a=Matter.Common,s=Matter.MouseConstraint,c=Matter.Mouse,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0}});t.run(p);var m=r.create();r.run(m,d),o.add(u,[l.rectangle(400,600,1200,50.5,{isStatic:!0,render:{fillStyle:"#060a19"}})]);var f=i.stack(100,0,10,8,10,10,(function(e,t){return l.circle(e,t,a.random(15,30),{restitution:.6,friction:.1})}));o.add(u,[f,l.polygon(200,460,3,60),l.polygon(400,460,5,60),l.rectangle(600,460,80,80)]);var v=c.create(p.canvas),g=s.create(d,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});o.add(u,g),p.mouse=v,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}});for(var y=o.allBodies(u),x=0;x1;if(!p||e!=p.x||t!=p.y){p&&r?(m=p.x,f=p.y):(m=0,f=0);var o={x:m+e,y:f+t};!r&&p||(p=o),v.push(o),y=m+e,x=f+t}},M=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":y=e.x,x=e.y;break;case"H":y=e.x;break;case"V":x=e.y}h(y,x,e.pathSegType)}};for(r._svgPathToAbsolute(e),a=e.getTotalLength(),l=[],n=0;n0)return!1;a=n}return!0},r.scale=function(e,t,n,i){if(1===t&&1===n)return e;var a,s;i=i||r.centre(e);for(var c=0;c=0?c-1:e.length-1],d=e[c],u=e[(c+1)%e.length],p=t[c0&&(i|=2),3===i)return!1;return 0!==i||null},r.hull=function(e){var t,n,r=[],i=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];r.length>=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}return r.pop(),i.pop(),r.concat(i)}},"0mtl":function(e,t,n){var r=r||{};r.catapult=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Constraint,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=Matter.Body,d=Matter.Vector,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0,showVelocity:!0}});t.run(m);var f=n.create();n.run(f,u);var v=l.nextGroup(!0),g=r.stack(250,255,1,6,0,0,(function(e,t){return c.rectangle(e,t,30,30)})),y=c.rectangle(400,520,320,20,{collisionFilter:{group:v}});s.add(p,[g,y,c.rectangle(400,600,800,50.5,{isStatic:!0,render:{fillStyle:"#060a19"}}),c.rectangle(250,555,20,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),c.rectangle(400,535,20,80,{isStatic:!0,collisionFilter:{group:v},render:{fillStyle:"#060a19"}}),c.circle(560,100,50,{density:.005}),o.create({bodyA:y,pointB:d.clone(y.position),stiffness:1,length:0})]);var x=a.create(m.canvas),h=i.create(u,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(p,h),m.mouse=x,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.catapult.title="Catapult",r.catapult.for=">=0.14.2",e.exports=r.catapult},"136C":function(e,t,n){var r=r||{};r.slingshot=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Events,i=Matter.Constraint,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0}});t.run(p);var m=n.create();n.run(m,d);var f=l.rectangle(395,600,815,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),v={density:.004},g=l.polygon(170,450,8,20,v),y=i.create({pointA:{x:170,y:450},bodyB:g,stiffness:.05}),x=r.pyramid(500,300,9,10,0,0,(function(e,t){return l.rectangle(e,t,25,40)})),h=l.rectangle(610,250,200,20,{isStatic:!0,render:{fillStyle:"#060a19"}}),M=r.pyramid(550,0,5,10,0,0,(function(e,t){return l.rectangle(e,t,25,40)}));c.add(d.world,[f,x,h,M,g,y]),o.on(d,"afterUpdate",(function(){-1===S.mouse.button&&(g.position.x>190||g.position.y<430)&&(g=l.polygon(170,450,7,20,v),c.add(d.world,g),y.bodyB=g)}));var b=s.create(p.canvas),S=a.create(d,{mouse:b,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(u,S),p.mouse=b,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.slingshot.title="Slingshot",r.slingshot.for=">=0.14.2",e.exports=r.slingshot},"2Og8":function(e,t,n){var r={};e.exports=r;var o=n("571F");r._registry={},r.register=function(e){if(r.isPlugin(e)||o.warn("Plugin.register:",r.toString(e),"does not implement all required fields."),e.name in r._registry){var t=r._registry[e.name],n=r.versionParse(e.version).number,i=r.versionParse(t.version).number;n>i?(o.warn("Plugin.register:",r.toString(t),"was upgraded to",r.toString(e)),r._registry[e.name]=e):n-1},r.isFor=function(e,t){var n=e.for&&r.dependencyParse(e.for);return!e.for||t.name===n.name&&r.versionSatisfies(t.version,n.range)},r.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=r.dependencies(e),i=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",r.toString(e),"does not specify any dependencies to install.")},r.dependencies=function(e,t){var n=r.dependencyParse(e),i=n.name;if(!(i in(t=t||{}))){e=r.resolve(e)||e,t[i]=o.map(e.uses||[],(function(t){r.isPlugin(t)&&r.register(t);var i=r.dependencyParse(t),a=r.resolve(t);return a&&!r.versionSatisfies(a.version,i.range)?(o.warn("Plugin.dependencies:",r.toString(a),"does not satisfy",r.toString(i),"used by",r.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",r.toString(t),"used by",r.toString(n),"could not be resolved."),e._warned=!0),i.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),r=Number(n[4]),i=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:r,minor:i,patch:a,parts:[r,i,a],prerelease:n[7],number:1e8*r+1e4*i+a}},r.versionSatisfies=function(e,t){t=t||"*";var n=r.versionParse(t),o=r.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},"2oV2":function(e,t,n){var r=r||{};r.raycasting=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composite,i=Matter.Composites,a=Matter.Common,s=Matter.Query,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Events,u=Matter.Vertices,p=Matter.Bodies,m=e.create(),f=m.world,v=t.create({element:document.body,engine:m,options:{width:800,height:600,showAngleIndicator:!0}});t.run(v);var g=r.create();r.run(g,m);var y=i.stack(20,20,12,4,0,0,(function(e,t){switch(Math.round(a.random(0,1))){case 0:return a.random()<.8?p.rectangle(e,t,a.random(20,50),a.random(20,50)):p.rectangle(e,t,a.random(80,120),a.random(20,30));case 1:var n=Math.round(a.random(1,8));return n=3===n?4:n,p.polygon(e,t,n,a.random(20,50))}}));a.setDecomp(n("Dded"));var x=u.fromPath("50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38"),h=p.fromVertices(200,200,x);o.add(f,[y,h,p.rectangle(400,0,800,50,{isStatic:!0}),p.rectangle(400,600,800,50,{isStatic:!0}),p.rectangle(800,300,50,600,{isStatic:!0}),p.rectangle(0,300,50,600,{isStatic:!0})]);var M=[],b={x:400,y:100};d.on(m,"afterUpdate",(function(){var e=w.mouse,t=o.allBodies(m.world),n=e.position||{x:100,y:600};M=s.ray(t,b,n)})),d.on(v,"afterRender",(function(){var e=w.mouse,n=v.context,r=e.position||{x:100,y:600};t.startViewTransform(v),n.beginPath(),n.moveTo(b.x,b.y),n.lineTo(r.x,r.y),M.length>0?n.strokeStyle="#fff":n.strokeStyle="#555",n.lineWidth=.5,n.stroke();for(var o=0;o0.16.1",e.exports=r.raycasting},"3Slt":function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("Tgw/");r._restingThresh=4,r._restingThreshTangent=6,r._positionDampen=.9,r._positionWarming=.8,r._frictionNormalMultiplier=5,r.preSolvePosition=function(e){var t,n,r,o=e.length;for(t=0;tH||-W>H?(o=W>0?W:-W,(n=m.friction*(W>0?1:-1)*s)<-o?n=-o:n>o&&(n=o)):(n=W,o=u);var G=I*M-E*h,U=_*M-T*h,N=A/(B+v.inverseInertia*G*G+g.inverseInertia*U*U),z=(1+m.restitution)*O*N;if(n*=N,O*O>c&&O<0)R.normalImpulse=0;else{var Z=R.normalImpulse;R.normalImpulse+=z,R.normalImpulse=Math.min(R.normalImpulse,0),z=R.normalImpulse-Z}if(W*W>d)R.tangentImpulse=0;else{var Q=R.tangentImpulse;R.tangentImpulse+=n,R.tangentImpulse<-o&&(R.tangentImpulse=-o),R.tangentImpulse>o&&(R.tangentImpulse=o),n=R.tangentImpulse-Q}var X=h*z+b*n,Y=M*z+S*n;v.isStatic||v.isSleeping||(v.positionPrev.x+=X*v.inverseMass,v.positionPrev.y+=Y*v.inverseMass,v.anglePrev+=(I*Y-E*X)*v.inverseInertia),g.isStatic||g.isSleeping||(g.positionPrev.x-=X*g.inverseMass,g.positionPrev.y-=Y*g.inverseMass,g.anglePrev-=(_*Y-T*X)*g.inverseInertia)}}}}},"4XQC":function(e,t,n){var r=r||{};r.staticFriction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Composites,i=Matter.Events,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showVelocity:!0}});t.run(p);var m=n.create();n.run(m,d);var f=l.rectangle(400,500,200,60,{isStatic:!0,chamfer:10,render:{fillStyle:"#060a19"}}),v=-1,g=o.stack(350,170,1,6,0,0,(function(e,t){return l.rectangle(e,t,100,50,{slop:.5,friction:1,frictionStatic:1/0})}));c.add(u,[f,g,l.rectangle(400,0,800,50,{isStatic:!0}),l.rectangle(400,600,800,50,{isStatic:!0}),l.rectangle(800,300,50,600,{isStatic:!0}),l.rectangle(0,300,50,600,{isStatic:!0})]),i.on(d,"beforeUpdate",(function(e){if(!((v+=.014)<0)){var t=400+100*Math.sin(v);r.setVelocity(f,{x:t-f.position.x,y:0}),r.setPosition(f,{x:t,y:f.position.y})}}));var y=s.create(p.canvas),x=a.create(d,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(u,x),p.mouse=y,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.staticFriction.title="Static Friction",r.staticFriction.for=">=0.14.2",e.exports=r.staticFriction},"4d8i":function(e,t,n){var r={};e.exports=r;var o=n("yTB+"),i=n("nIFq"),a=n("571F");!function(){var e,t,n;("undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),e)||(e=function(e){n=setTimeout((function(){e(a.now())}),1e3/60)},t=function(){clearTimeout(n)});r.create=function(e){var t=a.extend({fps:60,correction:1,deltaSampleSize:60,counterTimestamp:0,frameCounter:0,deltaHistory:[],timePrev:null,timeScalePrev:1,frameRequestId:null,isFixed:!1,enabled:!0},e);return t.delta=t.delta||1e3/t.fps,t.deltaMin=t.deltaMin||1e3/t.fps,t.deltaMax=t.deltaMax||1e3/(.5*t.fps),t.fps=1e3/t.delta,t},r.run=function(t,n){return void 0!==t.positionIterations&&(n=t,t=r.create()),function o(i){t.frameRequestId=e(o),i&&t.enabled&&r.tick(t,n,i)}(),t},r.tick=function(e,t,n){var r,a=t.timing,s=1,c={timestamp:a.timestamp};o.trigger(e,"beforeTick",c),e.isFixed?r=e.delta:(r=n-e.timePrev||e.delta,e.timePrev=n,e.deltaHistory.push(r),e.deltaHistory=e.deltaHistory.slice(-e.deltaSampleSize),s=(r=(r=(r=Math.min.apply(null,e.deltaHistory))e.deltaMax?e.deltaMax:r)/e.delta,e.delta=r),0!==e.timeScalePrev&&(s*=a.timeScale/e.timeScalePrev),0===a.timeScale&&(s=0),e.timeScalePrev=a.timeScale,e.correction=s,e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",c),o.trigger(e,"beforeUpdate",c),i.update(t,r,s),o.trigger(e,"afterUpdate",c),o.trigger(e,"afterTick",c)},r.stop=function(e){t(e.frameRequestId)},r.start=function(e,t){r.run(e,t)}}()},"52dP":function(e,t,n){var r=r||{};r.terrain=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Query,d=Matter.Svg,u=Matter.Bodies;i.setDecomp(n("Dded"));var p=e.create(),m=p.world,f=t.create({element:document.body,engine:p,options:{width:800,height:600}});t.run(f);var v,g=r.create();if(r.run(g,p),"undefined"!=typeof fetch){(v="./svg/terrain.svg",fetch(v).then((function(e){return e.text()})).then((function(e){return(new window.DOMParser).parseFromString(e,"image/svg+xml")}))).then((function(e){var t=function(e,t){return Array.prototype.slice.call(e.querySelectorAll(t))}(e,"path").map((function(e){return d.pathToVertices(e,30)})),n=u.fromVertices(400,350,t,{isStatic:!0,render:{fillStyle:"#060a19",strokeStyle:"#060a19",lineWidth:1}},!0);c.add(m,n);var r={frictionAir:0,friction:1e-4,restitution:.6};c.add(m,o.stack(80,100,20,20,10,10,(function(e,t){if(0===l.point([n],{x:e,y:t}).length)return u.polygon(e,t,5,12,r)})))}))}else i.warn("Fetch is not available. Could not load SVG.");var y=s.create(f.canvas),x=a.create(p,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(m,x),f.mouse=y,t.lookAt(f,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:p,runner:g,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(g)}}},r.terrain.title="Terrain",r.terrain.for=">0.16.1",e.exports=r.terrain},"571F":function(e,t){var n={};e.exports=n,function(){n._nextId=0,n._seed=0,n._nowStartTime=+new Date,n._warnedOnce={},n._decomp=null,n.extend=function(e,t){var r,o;"boolean"==typeof t?(r=2,o=t):(r=1,o=!0);for(var i=r;i0;t--){var r=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[r],e[r]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,r){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",r)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;n=0.14.2",e.exports=r.pyramid},"6IAi":function(e,t,n){var r=r||{};r.airFriction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showVelocity:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(200,100,60,60,{frictionAir:.001}),a.rectangle(400,100,60,60,{frictionAir:.05}),a.rectangle(600,100,60,60,{frictionAir:.1}),a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.airFriction.title="Air Friction",r.airFriction.for=">=0.14.2",e.exports=r.airFriction},"71Xj":function(e,t,n){var r=n("akk5");e.exports={demo:function(e,t){var n=r.Demo.create({toolbar:{title:"matter-js"+(t?" ・ dev":""),url:"https://github.com/liabru/matter-js",reset:!0,source:!0,inspector:!0,tools:!0,fullscreen:!0,exampleSelect:!0},tools:{inspector:!0,gui:!0},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!0,startExample:"mixed",examples:e});if(window.MatterDemoInstance=n,document.body.appendChild(n.dom.root),document.title="Matter.js Demo"+(t?" ・ Dev":""),t){var o=n.dom.buttonSource,i=o.cloneNode(!0);i.textContent="⎄",i.title="Compare",i.href="?compare",i.target="",i.className="matter-btn matter-btn-compare",i.addEventListener("click",(function(e){window.location="?compare#"+n.example.id,e.preventDefault()})),o.parentNode.insertBefore(i,o.nextSibling),Matter.before("Render.create",(function(e){e.options.showDebug=!0}))}r.Demo.start(n)}}},"74MQ":function(e,t,n){var r=r||{};r.doublePendulum=function(){var e=Matter.Engine,t=Matter.Events,n=Matter.Render,r=Matter.Runner,o=Matter.Body,i=Matter.Composite,a=Matter.Composites,s=Matter.Constraint,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=Matter.Vector,p=e.create(),m=p.world,f=n.create({element:document.body,engine:p,options:{width:800,height:600,wireframes:!1}});n.run(f);var v=r.create();r.run(v,p);var g=o.nextGroup(!0),y=a.stack(350,160,2,1,-20,0,(function(e,t){return d.rectangle(e,t,200,25,{collisionFilter:{group:g},frictionAir:0,chamfer:5,render:{fillStyle:"transparent",lineWidth:1}})}));p.gravity.scale=.002,a.chain(y,.45,0,-.45,0,{stiffness:.9,length:0,angularStiffness:.7,render:{strokeStyle:"#4a485b"}}),i.add(y,s.create({bodyB:y.bodies[0],pointB:{x:-84,y:0},pointA:{x:y.bodies[0].position.x-84,y:y.bodies[0].position.y},stiffness:.9,length:0,render:{strokeStyle:"#4a485b"}}));var x=y.bodies[1];o.rotate(x,.3*-Math.PI,{x:x.position.x-100,y:x.position.y}),i.add(m,y);var h=[];t.on(f,"afterRender",(function(){h.unshift({position:u.clone(x.position),speed:x.speed}),n.startViewTransform(f),f.context.globalAlpha=.7;for(var e=0;e2e3&&h.pop()}));var M=l.create(f.canvas),b=c.create(p,{mouse:M,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(m,b),f.mouse=M,n.lookAt(f,{min:{x:0,y:0},max:{x:700,y:600}}),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.doublePendulum.title="Double Pendulum",r.doublePendulum.for=">0.16.1",e.exports=r.doublePendulum},"7MJU":function(e,t,n){var r=r||{};r.gravity=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showVelocity:!0,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50.5,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]),l.gravity.y=-1;var m=r.stack(50,120,11,5,0,0,(function(e,t){switch(Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(20,50),o.random(20,50)):c.rectangle(e,t,o.random(80,120),o.random(20,30));case 1:return c.polygon(e,t,Math.round(o.random(1,8)),o.random(20,50))}}));s.add(d,m);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.gravity.title="Reverse Gravity",r.gravity.for=">0.16.1",e.exports=r.gravity},"9K63":function(e,t){var n={};e.exports=n,n.create=function(e){return{vertex:e,normalImpulse:0,tangentImpulse:0}}},"9Nbg":function(e,t,n){var r={};e.exports=r;var o=n("wAS/"),i=n("ga9t"),a=n("571F"),s=n("IbIC"),c=n("oT59"),l=a.deprecated;r.stack=function(e,t,n,r,i,a,c){for(var l,d=o.create({label:"Stack"}),u=e,p=t,m=0,f=0;fv&&(v=x),s.translate(y,{x:.5*h,y:.5*x}),u=y.bounds.max.x+i,o.addBody(d,y),l=y,m+=1}else u+=i}p+=v+a,u=e}return d},r.chain=function(e,t,n,r,s,c){for(var l=e.bodies,d=1;d0)for(l=0;l0&&(p=m[l-1+(c-1)*t],o.addConstraint(e,i.create(a.extend({bodyA:p,bodyB:u},s)))),r&&lp||a<(l=p-l)||a>n-1-l))return 1===u&&s.translate(d,{x:(a+(n%2==1?1:-1))*m,y:0}),c(e+(d?a*m:0)+a*i,r,a,l,d,u)}))},r.newtonsCradle=function(e,t,n,r,a){for(var s=o.create({label:"Newtons Cradle"}),l=0;l=0.14.2",e.exports=r.avalanche},"C6Q+":function(e,t,n){var r=r||{};r.events=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.Composite,a=Matter.Composites,s=Matter.Common,c=Matter.MouseConstraint,l=Matter.Mouse,d=Matter.Bodies,u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600,wireframes:!1}});t.run(m);var f=n.create();n.run(f,u),o.on(p,"afterAdd",(function(e){})),o.on(u,"beforeUpdate",(function(e){var t=e.source;e.timestamp%5e3<50&&y(t)})),o.on(u,"collisionStart",(function(e){for(var t=e.pairs,n=0;n=500){var a=.02*o.mass;r.applyForce(o,o.position,{x:(a+s.random()*a)*s.choose([1,-1]),y:-a+s.random()*-a})}}},x=l.create(m.canvas),h=c.create(u,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(p,h),m.mouse=x,o.on(h,"mousedown",(function(e){var t=e.mouse.position;console.log("mousedown at "+t.x+" "+t.y),y(u)})),o.on(h,"mouseup",(function(e){var t=e.mouse.position;console.log("mouseup at "+t.x+" "+t.y)})),o.on(h,"startdrag",(function(e){console.log("startdrag",e)})),o.on(h,"enddrag",(function(e){console.log("enddrag",e)})),t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.events.title="Events",r.events.for=">=0.14.2",e.exports=r.events},Czbd:function(e,t,n){var r=r||{};r.softBody=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=(Matter.Composites,Matter.MouseConstraint),i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!1}});t.run(d);var u=n.create();n.run(u,c);var p={friction:.05,frictionStatic:.1,render:{visible:!0}};a.add(l,[r.softBody.softBody(250,100,5,5,0,0,!0,18,p),r.softBody.softBody(400,300,8,3,0,0,!0,15,p),r.softBody.softBody(250,400,4,4,0,0,!0,15,p),s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.9,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.softBody.title="Soft Body",r.softBody.for=">=0.14.2",r.softBody.softBody=function(e,t,n,r,o,i,a,s,c,l){var d=Matter.Common,u=Matter.Composites,p=Matter.Bodies;c=d.extend({inertia:1/0},c),l=d.extend({stiffness:.2,render:{type:"line",anchors:!1}},l);var m=u.stack(e,t,n,r,o,i,(function(e,t){return p.circle(e,t,s,c)}));return u.mesh(m,n,r,a,l),m.label="Soft Body",m},e.exports=r.softBody},DeYi:function(e,t,n){var r=r||{};r.friction=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showVelocity:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]),i.add(c,[a.rectangle(300,180,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,70,40,40,{friction:.001})]),i.add(c,[a.rectangle(300,350,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,250,40,40,{friction:5e-4})]),i.add(c,[a.rectangle(300,520,700,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),a.rectangle(300,430,40,40,{friction:0})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.friction.title="Friction",r.friction.for=">=0.14.2",e.exports=r.friction},DqtB:function(e,t,n){var r={};e.exports=r;var o=n("Z/YF"),i=n("571F").deprecated;r.collides=function(e,t){return o.collides(e,t)},i(r,"collides","SAT.collides ➤ replaced by Collision.collides")},EUdY:function(e,t,n){var r=r||{};r.stress=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(90,50,18,15,0,0,(function(e,t){return s.rectangle(e,t,35,35)}));a.add(l,[p,s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.stress.title="Stress",r.stress.for=">=0.14.2",e.exports=r.stress},H5X8:function(e,t,n){var r=r||{};r.stress3=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create({positionIterations:10,velocityIterations:10}),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(u);var p=n.create({isFixed:!0});n.run(p,l);var m=.3,f=r.stack(40,40,38,18,0,0,(function(e,t){var n=Math.round(o.random(1,8));switch(Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50)*m,o.random(25,50)*m):c.rectangle(e,t,o.random(80,120)*m,o.random(25,30)*m);case 1:return c.polygon(e,t,n,o.random(25,50)*m)}}));s.add(d,f),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.stress3.title="Stress 3",r.stress3.for=">=0.14.2",e.exports=r.stress3},I5nt:function(e,t,n){var r={};e.exports=r;var o=n("571F");r.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=r._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},r.setElement(t,t.element),t},r.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},r.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},r.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},r.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},r._getRelativeMousePosition=function(e,t,n){var r,o,i=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,c=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,l=e.changedTouches;return l?(r=l[0].pageX-i.left-s,o=l[0].pageY-i.top-c):(r=e.pageX-i.left-s,o=e.pageY-i.top-c),{x:r/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},IOLg:function(e,t,n){var r=r||{};r.concave=function(){var e=Matter.Engine,t=Matter.Render,r=Matter.Runner,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Vertices,d=Matter.Bodies;i.setDecomp(n("Dded"));var u=e.create(),p=u.world,m=t.create({element:document.body,engine:u,options:{width:800,height:600}});t.run(m);var f=r.create();r.run(f,u),c.add(p,[d.rectangle(400,0,800,50,{isStatic:!0}),d.rectangle(400,600,800,50,{isStatic:!0}),d.rectangle(800,300,50,600,{isStatic:!0}),d.rectangle(0,300,50,600,{isStatic:!0})]);var v=l.fromPath("40 0 40 20 100 20 100 80 40 80 40 100 0 50"),g=l.fromPath("100 0 75 50 100 100 25 100 0 50 25 0"),y=l.fromPath("50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38"),x=l.fromPath("35 7 19 17 14 38 14 58 25 79 45 85 65 84 65 66 46 67 34 59 30 44 33 29 45 23 66 23 66 7 53 7"),h=o.stack(50,50,6,4,10,10,(function(e,t){var n=i.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]);return d.fromVertices(e,t,i.choose([v,g,y,x]),{render:{fillStyle:n,strokeStyle:n,lineWidth:1}},!0)}));c.add(p,h);var M=s.create(m.canvas),b=a.create(u,{mouse:M,constraint:{stiffness:.2,render:{visible:!1}}});return c.add(p,b),m.mouse=M,t.lookAt(m,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:u,runner:f,render:m,canvas:m.canvas,stop:function(){Matter.Render.stop(m),Matter.Runner.stop(f)}}},r.concave.title="Concave",r.concave.for=">0.16.1",e.exports=r.concave},IbIC:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("m6Dm"),a=n("yw0d"),s=(n("lWug"),n("571F")),c=n("Tgw/"),l=n("JKEF");!function(){r._inertiaScale=4,r._nextCollidingGroupId=1,r._nextNonCollidingGroupId=-1,r._nextCategory=1,r.create=function(t){var n={id:s.nextId(),type:"body",label:"Body",parts:[],plugin:{},angle:0,vertices:o.fromPath("L 0 0 L 40 0 L 40 40 L 0 40"),position:{x:0,y:0},force:{x:0,y:0},torque:0,positionImpulse:{x:0,y:0},constraintImpulse:{x:0,y:0,angle:0},totalContacts:0,speed:0,angularSpeed:0,velocity:{x:0,y:0},angularVelocity:0,isSensor:!1,isStatic:!1,isSleeping:!1,motion:0,sleepThreshold:60,density:.001,restitution:0,friction:.1,frictionStatic:.5,frictionAir:.01,collisionFilter:{category:1,mask:4294967295,group:0},slop:.05,timeScale:1,render:{visible:!0,opacity:1,strokeStyle:null,fillStyle:null,lineWidth:null,sprite:{xScale:1,yScale:1,xOffset:0,yOffset:0}},events:null,bounds:null,chamfer:null,circleRadius:0,positionPrev:null,anglePrev:0,parent:null,axes:null,area:0,mass:0,inertia:0,_original:null},r=s.extend(n,t);return e(r,t),r},r.nextGroup=function(e){return e?r._nextNonCollidingGroupId--:r._nextCollidingGroupId++},r.nextCategory=function(){return r._nextCategory=r._nextCategory<<1,r._nextCategory};var e=function(e,t){t=t||{},r.set(e,{bounds:e.bounds||c.create(e.vertices),positionPrev:e.positionPrev||i.clone(e.position),anglePrev:e.anglePrev||e.angle,vertices:e.vertices,parts:e.parts||[e],isStatic:e.isStatic,isSleeping:e.isSleeping,parent:e.parent||e}),o.rotate(e.vertices,e.angle,e.position),l.rotate(e.axes,e.angle),c.update(e.bounds,e.vertices,e.velocity),r.set(e,{axes:t.axes||e.axes,area:t.area||e.area,mass:t.mass||e.mass,inertia:t.inertia||e.inertia});var n=e.isStatic?"#14151f":s.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"]),a=e.isStatic?"#555":"#ccc",d=e.isStatic&&null===e.render.fillStyle?1:0;e.render.fillStyle=e.render.fillStyle||n,e.render.strokeStyle=e.render.strokeStyle||a,e.render.lineWidth=e.render.lineWidth||d,e.render.sprite.xOffset+=-(e.bounds.min.x-e.position.x)/(e.bounds.max.x-e.bounds.min.x),e.render.sprite.yOffset+=-(e.bounds.min.y-e.position.y)/(e.bounds.max.y-e.bounds.min.y)};r.set=function(e,t,n){var o;for(o in"string"==typeof t&&(o=t,(t={})[o]=n),t)if(Object.prototype.hasOwnProperty.call(t,o))switch(n=t[o],o){case"isStatic":r.setStatic(e,n);break;case"isSleeping":a.set(e,n);break;case"mass":r.setMass(e,n);break;case"density":r.setDensity(e,n);break;case"inertia":r.setInertia(e,n);break;case"vertices":r.setVertices(e,n);break;case"position":r.setPosition(e,n);break;case"angle":r.setAngle(e,n);break;case"velocity":r.setVelocity(e,n);break;case"angularVelocity":r.setAngularVelocity(e,n);break;case"parts":r.setParts(e,n);break;case"centre":r.setCentre(e,n);break;default:e[o]=n}},r.setStatic=function(e,t){for(var n=0;n0&&i.rotateAbout(a.position,n,e.position,a.position)}},r.setVelocity=function(e,t){e.positionPrev.x=e.position.x-t.x,e.positionPrev.y=e.position.y-t.y,e.velocity.x=t.x,e.velocity.y=t.y,e.speed=i.magnitude(e.velocity)},r.setAngularVelocity=function(e,t){e.anglePrev=e.angle-t,e.angularVelocity=t,e.angularSpeed=Math.abs(e.angularVelocity)},r.translate=function(e,t){r.setPosition(e,i.add(e.position,t))},r.rotate=function(e,t,n){if(n){var o=Math.cos(t),i=Math.sin(t),a=e.position.x-n.x,s=e.position.y-n.y;r.setPosition(e,{x:n.x+(a*o-s*i),y:n.y+(a*i+s*o)}),r.setAngle(e,e.angle+t)}else r.setAngle(e,e.angle+t)},r.scale=function(e,t,n,i){var a=0,s=0;i=i||e.position;for(var d=0;d0&&(a+=u.area,s+=u.inertia),u.position.x=i.x+(u.position.x-i.x)*t,u.position.y=i.y+(u.position.y-i.y)*n,c.update(u.bounds,u.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(r.setMass(e,e.density*a),r.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},r.update=function(e,t,n,r){var a=Math.pow(t*n*e.timeScale,2),s=1-e.frictionAir*n*e.timeScale,d=e.position.x-e.positionPrev.x,u=e.position.y-e.positionPrev.y;e.velocity.x=d*s*r+e.force.x/e.mass*a,e.velocity.y=u*s*r+e.force.y/e.mass*a,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.angularVelocity=(e.angle-e.anglePrev)*s*r+e.torque/e.inertia*a,e.anglePrev=e.angle,e.angle+=e.angularVelocity,e.speed=i.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var p=0;p0&&(m.position.x+=e.velocity.x,m.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(m.vertices,e.angularVelocity,e.position),l.rotate(m.axes,e.angularVelocity),p>0&&i.rotateAbout(m.position,e.angularVelocity,e.position,m.position)),c.update(m.bounds,m.vertices,e.velocity)}},r.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var r=t.x-e.position.x,o=t.y-e.position.y;e.torque+=r*n.y-o*n.x},r._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n=0.14.2",e.exports=r.sleeping},LS1c:function(e,t,n){var r=r||{};r.wreckingBall=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Constraint,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(400,175,5,10,0,0,(function(e,t){return c.rectangle(e,t,40,40)}));a.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=c.circle(100,400,50,{density:.04,frictionAir:.005});a.add(d,f),a.add(d,s.create({pointA:{x:300,y:100},bodyB:f}));var v=i.create(u.canvas),g=o.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.wreckingBall.title="Wrecking Ball",r.wreckingBall.for=">=0.14.2",e.exports=r.wreckingBall},Me0I:function(e,t,n){var r=r||{};r.car=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=(Matter.Composites,Matter.MouseConstraint),i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0}});t.run(d);var u=n.create();n.run(u,c),a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0})]);var p=.9;a.add(l,r.car.car(150,100,150*p,30*p,30*p)),p=.8,a.add(l,r.car.car(350,300,150*p,30*p,30*p)),a.add(l,[s.rectangle(200,150,400,20,{isStatic:!0,angle:.06*Math.PI,render:{fillStyle:"#060a19"}}),s.rectangle(500,350,650,20,{isStatic:!0,angle:.06*-Math.PI,render:{fillStyle:"#060a19"}}),s.rectangle(300,560,600,20,{isStatic:!0,angle:.04*Math.PI,render:{fillStyle:"#060a19"}})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.car.title="Car",r.car.for=">=0.14.2",r.car.car=function(e,t,n,r,o){var i=Matter.Body,a=Matter.Bodies,s=Matter.Composite,c=Matter.Constraint,l=i.nextGroup(!0),d=.5*-n+20,u=.5*n-20,p=s.create({label:"Car"}),m=a.rectangle(e,t,n,r,{collisionFilter:{group:l},chamfer:{radius:.5*r},density:2e-4}),f=a.circle(e+d,t+0,o,{collisionFilter:{group:l},friction:.8}),v=a.circle(e+u,t+0,o,{collisionFilter:{group:l},friction:.8}),g=c.create({bodyB:m,pointB:{x:d,y:0},bodyA:f,stiffness:1,length:0}),y=c.create({bodyB:m,pointB:{x:u,y:0},bodyA:v,stiffness:1,length:0});return s.addBody(p,m),s.addBody(p,f),s.addBody(p,v),s.addConstraint(p,g),s.addConstraint(p,y),p},e.exports=r.car},MhOg:function(e,t,n){var r=r||{};r.views=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Events,o=Matter.Composites,i=Matter.Common,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Composite,l=Matter.Vector,d=Matter.Bounds,u=Matter.Bodies,p=e.create(),m=p.world,f=t.create({element:document.body,engine:p,options:{width:800,height:600,hasBounds:!0,showAngleIndicator:!0}});t.run(f);var v=n.create();n.run(v,p);var g=s.create(f.canvas),y=a.create(p,{mouse:g,constraint:{stiffness:.2,render:{visible:!1}}});c.add(m,y),f.mouse=g;var x=o.stack(20,20,10,4,0,0,(function(e,t){switch(Math.round(i.random(0,1))){case 0:return i.random()<.8?u.rectangle(e,t,i.random(20,50),i.random(20,50)):u.rectangle(e,t,i.random(80,120),i.random(20,30));case 1:var n=Math.round(i.random(1,8));return n=3===n?4:n,u.polygon(e,t,n,i.random(20,50))}}));c.add(m,[x,u.rectangle(400,0,800,50,{isStatic:!0}),u.rectangle(400,600,800,50,{isStatic:!0}),u.rectangle(800,300,50,600,{isStatic:!0}),u.rectangle(0,300,50,600,{isStatic:!0})]);var h={x:.5*f.options.width,y:.5*f.options.height},M={x:-300,y:-300},b={x:1100,y:900},S=1,w={x:1,y:1};return r.on(f,"beforeRender",(function(){p.world;var e,t=y.mouse,n=-.1*t.wheelDelta;0!==n&&(n<0&&w.x>=.6||n>0&&w.x<=1.4)&&(S+=n),Math.abs(w.x-S)>.01&&(n=.2*(S-w.x),w.x+=n,w.y+=n,f.bounds.max.x=f.bounds.min.x+f.options.width*w.x,f.bounds.max.y=f.bounds.min.y+f.options.height*w.y,e={x:f.options.width*n*-.5,y:f.options.height*n*-.5},d.translate(f.bounds,e),s.setScale(t,w),s.setOffset(t,f.bounds.min));var r=l.sub(t.absolute,h),o=l.magnitude(r);if(o>50){var i=l.normalise(r),a=Math.min(10,2e-4*Math.pow(o-50,2));e=l.mult(i,a),f.bounds.min.x+e.xb.x&&(e.x=b.x-f.bounds.max.x),f.bounds.min.y+e.yb.y&&(e.y=b.y-f.bounds.max.y),d.translate(f.bounds,e),s.setOffset(t,f.bounds.min)}})),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.views.title="Views",r.views.for=">=0.14.2",e.exports=r.views},NDQ1:function(e,t,n){var r={};e.exports=r;var o=n("m6Dm"),i=n("Z/YF"),a=n("Tgw/"),s=n("oT59"),c=n("0kzT");r.collides=function(e,t){for(var n=[],r=t.length,o=e.bounds,s=i.collides,c=a.overlaps,l=0;ld.bounds.max.x||m.bounds.max.yd.bounds.max.y))){var f=r._getRegion(e,m);if(!m.region||f.id!==m.region.id||o){m.region&&!o||(m.region=f);var v=r._regionUnion(f,m.region);for(a=v.startCol;a<=v.endCol;a++)for(s=v.startRow;s<=v.endRow;s++){c=u[l=r._getBucketId(a,s)];var g=a>=f.startCol&&a<=f.endCol&&s>=f.startRow&&s<=f.endRow,y=a>=m.region.startCol&&a<=m.region.endCol&&s>=m.region.startRow&&s<=m.region.endRow;!g&&y&&y&&c&&r._bucketRemoveBody(e,c,m),(m.region===f||g&&!y||o)&&(c||(c=r._createBucket(u,l)),r._bucketAddBody(e,c,m))}m.region=f,p=!0}}}p&&(e.pairsList=r._createActivePairsList(e))},a(r,"update","Grid.update ➤ replaced by Matter.Detector"),r.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},a(r,"clear","Grid.clear ➤ replaced by Matter.Detector"),r._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),i=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return r._createRegion(n,o,i,a)},r._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),i=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return r._createRegion(o,i,a,s)},r._createRegion=function(e,t,n,r){return{id:e+","+t+","+n+","+r,startCol:e,endCol:t,startRow:n,endRow:r}},r._getBucketId=function(e,t){return"C"+e+"R"+t},r._createBucket=function(e,t){return e[t]=[]},r._bucketAddBody=function(e,t,n){var r,i=e.pairs,a=o.id,s=t.length;for(r=0;r0?s.push(t):delete r[o[n]];return s}},"Tgw/":function(e,t){var n={};e.exports=n,n.create=function(e){var t={min:{x:0,y:0},max:{x:0,y:0}};return e&&n.update(t,e),t},n.update=function(e,t,n){e.min.x=1/0,e.max.x=-1/0,e.min.y=1/0,e.max.y=-1/0;for(var r=0;re.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,r=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+r}},VZUp:function(e,t,n){var r=r||{};r.manipulation=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Events,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAxes:!0,showCollisions:!0,showConvexHulls:!0}});t.run(u);var p=n.create();n.run(p,l);var m=c.rectangle(100,200,50,50,{isStatic:!0,render:{fillStyle:"#060a19"}}),f=c.rectangle(200,200,50,50),v=c.rectangle(300,200,50,50),g=c.rectangle(400,200,50,50),y=c.rectangle(550,200,50,50),x=c.rectangle(700,200,50,50),h=c.circle(400,100,25,{render:{fillStyle:"#060a19"}}),M=c.rectangle(600,200,120,50,{render:{fillStyle:"#060a19"}}),b=c.rectangle(660,200,50,190,{render:{fillStyle:"#060a19"}}),S=r.create({parts:[M,b],isStatic:!0});s.add(d,[m,f,v,g,y,x,h,S]),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var w=0,C=1.01;o.on(p,"afterTick",(function(e){40===(w+=1)&&r.setStatic(h,!0),C>1&&(r.scale(x,C,C),r.scale(S,.995,.995),y.vertices[0].x-=.2,y.vertices[0].y-=.2,y.vertices[1].x+=.2,y.vertices[1].y-=.2,r.setVertices(y,y.vertices));var t=300+100*Math.sin(.002*l.timing.timestamp);r.setVelocity(m,{x:0,y:t-m.position.y}),r.setPosition(m,{x:100,y:t}),r.setVelocity(S,{x:0,y:t-S.position.y}),r.setAngularVelocity(S,.02),r.setPosition(S,{x:600,y:t}),r.rotate(S,.02),w>=90&&(r.setVelocity(f,{x:0,y:-10}),r.setAngle(v,.26*-Math.PI),r.setAngularVelocity(g,.2),w=0,C=1)}));var A=a.create(u.canvas),B=i.create(l,{mouse:A,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,B),u.mouse=A,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.manipulation.title="Manipulation",r.manipulation.for=">=0.14.2",e.exports=r.manipulation},Vyp4:function(e,t,n){var r=r||{};r.remove=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=Matter.Events,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0}});t.run(p);var m=n.create();n.run(m,d);var f=null,v=0,g=function(){return r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}))};l.on(d,"afterUpdate",(function(){f&&v<=50?v+=1:(v=0,f&&s.remove(u,f),f=g(),s.add(u,f))})),s.add(u,g()),s.add(u,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var y=a.create(p.canvas),x=i.create(d,{mouse:y,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(u,x),p.mouse=y,t.lookAt(p,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.remove.title="Composite Remove",r.remove.for=">=0.14.2",e.exports=r.remove},"Z/YF":function(e,t,n){var r={};e.exports=r;var o,i,a,s=n("0kzT"),c=n("t8gT");o=[],i={overlap:0,axis:null},a={overlap:0,axis:null},r.create=function(e,t){return{pair:null,collided:!1,bodyA:e,bodyB:t,parentA:e.parent,parentB:t.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},r.collides=function(e,t,n){if(r._overlapAxes(i,e.vertices,t.vertices,e.axes),i.overlap<=0)return null;if(r._overlapAxes(a,t.vertices,e.vertices,t.axes),a.overlap<=0)return null;var o,l,d=n&&n.table[c.id(e,t)];d?o=d.collision:((o=r.create(e,t)).collided=!0,o.bodyA=e.idC?C=s:sA?A=s:so?o=a:a=0.14.2",e.exports=r.restitution},ZUN1:function(e,t,n){var r=r||{};r.chains=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Composite,i=Matter.Composites,a=Matter.Constraint,s=Matter.MouseConstraint,c=Matter.Mouse,l=Matter.Bodies,d=e.create(),u=d.world,p=t.create({element:document.body,engine:d,options:{width:800,height:600,showAngleIndicator:!0,showCollisions:!0,showVelocity:!0}});t.run(p);var m=n.create();n.run(m,d);var f=r.nextGroup(!0),v=i.stack(100,50,8,1,10,10,(function(e,t){return l.rectangle(e,t,50,20,{collisionFilter:{group:f}})}));i.chain(v,.5,0,-.5,0,{stiffness:.8,length:2,render:{type:"line"}}),o.add(v,a.create({bodyB:v.bodies[0],pointB:{x:-25,y:0},pointA:{x:v.bodies[0].position.x,y:v.bodies[0].position.y},stiffness:.5})),f=r.nextGroup(!0);var g=i.stack(350,50,10,1,10,10,(function(e,t){return l.circle(e,t,20,{collisionFilter:{group:f}})}));i.chain(g,.5,0,-.5,0,{stiffness:.8,length:2,render:{type:"line"}}),o.add(g,a.create({bodyB:g.bodies[0],pointB:{x:-20,y:0},pointA:{x:g.bodies[0].position.x,y:g.bodies[0].position.y},stiffness:.5})),f=r.nextGroup(!0);var y=i.stack(600,50,13,1,10,10,(function(e,t){return l.rectangle(e-20,t,50,20,{collisionFilter:{group:f},chamfer:5})}));i.chain(y,.3,0,-.3,0,{stiffness:1,length:0}),o.add(y,a.create({bodyB:y.bodies[0],pointB:{x:-20,y:0},pointA:{x:y.bodies[0].position.x,y:y.bodies[0].position.y},stiffness:.5})),o.add(u,[v,g,y,l.rectangle(400,600,1200,50.5,{isStatic:!0})]);var x=c.create(p.canvas),h=s.create(d,{mouse:x,constraint:{stiffness:.2,render:{visible:!1}}});return o.add(u,h),p.mouse=x,t.lookAt(p,{min:{x:0,y:0},max:{x:700,y:600}}),{engine:d,runner:m,render:p,canvas:p.canvas,stop:function(){Matter.Render.stop(p),Matter.Runner.stop(m)}}},r.chains.title="Chains",r.chains.for=">=0.14.2",e.exports=r.chains},Zo9v:function(e,t,n){var r=r||{};r.collisionFiltering=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composite,o=Matter.Composites,i=(Matter.Common,Matter.MouseConstraint),a=Matter.Mouse,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,wireframes:!1}});t.run(d);var u=n.create();n.run(u,c);var p="#f55a3c",m="#063e7b",f="#f5d259";r.add(l,s.rectangle(400,600,900,50,{isStatic:!0,render:{fillStyle:"transparent",lineWidth:1}})),r.add(l,o.stack(275,100,5,9,10,10,(function(e,t,n,r){var o=2,i=p;return r>5?(o=8,i=m):r>2&&(o=4,i=f),s.circle(e,t,20,{collisionFilter:{category:o},render:{strokeStyle:i,fillStyle:"transparent",lineWidth:1}})}))),r.add(l,s.circle(310,40,30,{collisionFilter:{mask:5},render:{fillStyle:f}})),r.add(l,s.circle(400,40,30,{collisionFilter:{mask:3},render:{fillStyle:p}})),r.add(l,s.circle(480,40,30,{collisionFilter:{mask:9},render:{fillStyle:m}}));var v=a.create(d.canvas),g=i.create(c,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return r.add(l,g),d.mouse=v,g.collisionFilter.mask=13,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.collisionFiltering.title="Collision Filtering",r.collisionFiltering.for=">=0.14.2",e.exports=r.collisionFiltering},ZpbE:function(e,t,n){var r=r||{};r.stack=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(200,380.75,10,5,0,0,(function(e,t){return s.rectangle(e,t,40,40)}));a.add(l,[p,s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0}),s.rectangle(400,606,800,50.5,{isStatic:!0})]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.stack.title="Stack",r.stack.for=">=0.14.2",e.exports=r.stack},"a+ms":function(e,t,n){var r=n("akk5"),o=n("lniP"),i=n("lniP");e.exports={compare:function(e,t){var n=r.Demo.create({toolbar:{title:"matter-js ・ "+(t?"dev":"")+" ・ comparing to "+i.version,url:"https://github.com/liabru/matter-js",reset:!0,source:!0,inspector:!1,tools:!1,fullscreen:!0,exampleSelect:!0},tools:{inspector:!1,gui:!1},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!0,startExample:!1,examples:e}),a=r.Demo.create({toolbar:{title:"matter-js-compare-build",reset:!1,source:!1,inspector:!1,tools:!1,fullscreen:!1,exampleSelect:!1},tools:{inspector:!1,gui:!1},inline:!1,preventZoom:!0,resetOnOrientation:!0,routing:!1,startExample:!1,examples:e.map((function(e){return Matter.Common.extend({},e)}))});i.Runner.run=function(){},i.Render.run=function(){},o.Runner._tick=o.Runner.tick,o.Render._world=o.Render.world,i.Mouse._setElement=i.Mouse.setElement,r.Demo._setExample=r.Demo.setExample,r.Demo.setExample=function(e,t){i.Common._nextId=i.Common._seed=0,o.Common._nextId=o.Common._seed=0,i.Plugin._registry=o.Plugin._registry,i.use.apply(null,o.used),window.Matter=o,r.Demo._setExample(n,n.examples.find((function(e){return e.name===t.name})));var s=parseFloat(window.location.search.split("=")[1]),c=0;o.Runner.tick=function(e,t,n){if(-1!==c){if(c>=s)return console.info("Demo.Compare: ran "+c+" ticks, timestamp is now "+t.timing.timestamp.toFixed(2)),void(c=-1);c+=1;var r=a.example.instance;return e.isFixed=r.runner.isFixed=!0,e.delta=r.runner.delta=1e3/60,window.Matter=i,i.Runner.tick(r.runner,r.engine,n),window.Matter=o,o.Runner._tick(e,t,n)}},o.Render.world=function(e){return window.Matter=i,i.Render.world(a.example.instance.render),window.Matter=o,o.Render._world(e)},i.Mouse.setElement=function(e){return i.Mouse._setElement(e,n.example.instance.render.canvas)},window.Matter=i,r.Demo._setExample(a,a.examples.find((function(e){return e.name===t.name}))),window.Matter=o},r.Demo._reset=r.Demo.reset,r.Demo.reset=function(e){i.Common._nextId=i.Common._seed=0,o.Common._nextId=o.Common._seed=0,window.Matter=i,r.Demo._reset(a),window.Matter=o,r.Demo._reset(n)},document.body.appendChild(n.dom.root),document.body.appendChild(a.dom.root),r.Demo.start(n),document.title="Matter.js Compare"+(t?" ・ Dev":""),console.info("Demo.Compare: matter-js@"+o.version+" with matter-js@"+i.version)}}},a3OZ:function(e,t,n){var r=r||{};r.compositeManipulation=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Events,o=Matter.Composite,i=Matter.Composites,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l),o.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var m=i.stack(200,200,4,4,0,0,(function(e,t){return c.rectangle(e,t,40,40)}));o.add(d,m),l.gravity.y=0,r.on(l,"afterUpdate",(function(e){var t=l.timing.timestamp;o.translate(m,{x:2*Math.sin(.001*t),y:0}),o.rotate(m,.01*Math.sin(.001*t),{x:300,y:300});var n=1+.01*Math.sin(.001*t);o.scale(m,n,n,{x:300,y:300})}));var f=s.create(u.canvas),v=a.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return o.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.compositeManipulation.title="Composite Manipulation",r.compositeManipulation.for=">0.16.1",e.exports=r.compositeManipulation},c7us:function(e,t,n){var r=r||{};r.ragdoll=function(){var e=Matter.Engine,t=Matter.Events,n=Matter.Render,o=Matter.Runner,i=Matter.Body,a=Matter.Common,s=Matter.Composite,c=Matter.Composites,l=(Matter.Constraint,Matter.MouseConstraint),d=Matter.Mouse,u=Matter.Bodies,p=(Matter.Vector,e.create()),m=p.world,f=n.create({element:document.body,engine:p,options:{width:800,height:600,showAngleIndicator:!0}});n.run(f);var v=o.create();o.run(v,p);for(var g=(f.bounds.max.y-f.bounds.min.y)/50,y=c.stack(0,0,g+2,1,0,0,(function(e,t,n){return u.rectangle(e-50,t+50*n,100,1e3,{isStatic:!0,render:{fillStyle:"#060a19",strokeStyle:"#ffffff",lineWidth:1}})})),x=c.stack(300,0,15,3,10,10,(function(e,t,n){var r=Math.round(a.random(1,8)),o={render:{fillStyle:a.choose(["#f19648","#f5d259","#f55a3c","#063e7b","#ececd1"])}};switch(Math.round(a.random(0,1))){case 0:return a.random()<.8?u.rectangle(e,t,a.random(25,50),a.random(25,50),o):u.rectangle(e,t,a.random(80,120),a.random(25,30),o);case 1:return u.polygon(e,t,r,a.random(25,50),o)}})),h=s.create(),M=0;M<1;M+=1){var b=r.ragdoll.ragdoll(200,-1e3*M,1.3);s.add(h,b)}s.add(m,[y,x,h]);var S=1,w=0;t.on(p,"afterUpdate",(function(e){-1===C.button?p.timing.timeScale+=.05*(S-p.timing.timeScale):p.timing.timeScale=1,(w+=1)>=90&&(S=S<1?1:.05,w=0);for(var t=0;tf.bounds.max.y+100&&s.translate(r,{x:.9*-o.min.x,y:-f.bounds.max.y-400})}for(t=0;tf.bounds.max.y+100&&i.translate(n,{x:-o.min.x,y:-f.bounds.max.y-300})}}));var C=d.create(f.canvas),A=l.create(p,{mouse:C,constraint:{stiffness:.6,length:0,angularStiffness:0,render:{visible:!1}}});return s.add(m,A),f.mouse=C,n.lookAt(f,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:p,runner:v,render:f,canvas:f.canvas,stop:function(){Matter.Render.stop(f),Matter.Runner.stop(v)}}},r.ragdoll.ragdoll=function(e,t,n,r){n=void 0===n?1:n;var o=Matter.Body,i=Matter.Bodies,a=Matter.Constraint,s=Matter.Composite,c=Matter.Common,l=c.extend({label:"head",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:[15*n,15*n,15*n,15*n]},render:{fillStyle:"#FFBC42"}},r),d=c.extend({label:"chest",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:[20*n,20*n,26*n,26*n]},render:{fillStyle:"#E0A423"}},r),u=c.extend({label:"left-arm",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),p=c.extend({},u,{render:{fillStyle:"#E59B12"}}),m=c.extend({label:"right-arm",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),f=c.extend({},m,{render:{fillStyle:"#E59B12"}}),v=c.extend({label:"left-leg",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),g=c.extend({},v,{render:{fillStyle:"#E59B12"}}),y=c.extend({label:"right-leg",collisionFilter:{group:o.nextGroup(!0)},chamfer:{radius:10*n},render:{fillStyle:"#FFBC42"}},r),x=c.extend({},y,{render:{fillStyle:"#E59B12"}}),h=i.rectangle(e,t-60*n,34*n,40*n,l),M=i.rectangle(e,t,55*n,80*n,d),b=i.rectangle(e+39*n,t-15*n,20*n,40*n,m),S=i.rectangle(e+39*n,t+25*n,20*n,60*n,f),w=i.rectangle(e-39*n,t-15*n,20*n,40*n,u),C=i.rectangle(e-39*n,t+25*n,20*n,60*n,p),A=i.rectangle(e-20*n,t+57*n,20*n,40*n,v),B=i.rectangle(e-20*n,t+97*n,20*n,60*n,g),k=i.rectangle(e+20*n,t+57*n,20*n,40*n,y),R=i.rectangle(e+20*n,t+97*n,20*n,60*n,x),P=a.create({bodyA:M,pointA:{x:24*n,y:-23*n},pointB:{x:0,y:-8*n},bodyB:b,stiffness:.6,render:{visible:!1}}),I=a.create({bodyA:M,pointA:{x:-24*n,y:-23*n},pointB:{x:0,y:-8*n},bodyB:w,stiffness:.6,render:{visible:!1}}),E=a.create({bodyA:M,pointA:{x:-10*n,y:30*n},pointB:{x:0,y:-10*n},bodyB:A,stiffness:.6,render:{visible:!1}}),_=a.create({bodyA:M,pointA:{x:10*n,y:30*n},pointB:{x:0,y:-10*n},bodyB:k,stiffness:.6,render:{visible:!1}}),T=a.create({bodyA:b,bodyB:S,pointA:{x:0,y:15*n},pointB:{x:0,y:-25*n},stiffness:.6,render:{visible:!1}}),F=a.create({bodyA:w,bodyB:C,pointA:{x:0,y:15*n},pointB:{x:0,y:-25*n},stiffness:.6,render:{visible:!1}}),V=a.create({bodyA:A,bodyB:B,pointA:{x:0,y:20*n},pointB:{x:0,y:-20*n},stiffness:.6,render:{visible:!1}}),D=a.create({bodyA:k,bodyB:R,pointA:{x:0,y:20*n},pointB:{x:0,y:-20*n},stiffness:.6,render:{visible:!1}}),L=a.create({bodyA:h,pointA:{x:0,y:25*n},pointB:{x:0,y:-35*n},bodyB:M,stiffness:.6,render:{visible:!1}}),O=a.create({bodyA:B,bodyB:R,stiffness:.01,render:{visible:!1}});return s.create({bodies:[M,h,C,w,S,b,B,R,A,k],constraints:[F,T,I,P,L,V,D,E,_,O]})},r.ragdoll.title="Ragdoll",r.ragdoll.for=">=0.14.2",e.exports=r.ragdoll},djnZ:function(e,t,n){var r=r||{};r.compound=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Body,o=Matter.Constraint,i=Matter.Composite,a=Matter.MouseConstraint,s=Matter.Mouse,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAxes:!0,showConvexHulls:!0}});t.run(u);var p=n.create();n.run(p,l);var m=200,f=200,v=200,g=c.rectangle(f,v,m,m/5),y=c.rectangle(f,v,m/5,m,{render:g.render}),x=r.create({parts:[g,y]});m=150,f=400,v=300;var h=c.circle(f,v,30),M=c.circle(f+m,v,30),b=c.circle(f+m,v+m,30),S=c.circle(f,v+m,30),w=r.create({parts:[h,M,b,S]}),C=o.create({pointA:{x:400,y:100},bodyB:w,pointB:{x:0,y:0}});i.add(d,[x,w,C,c.rectangle(400,600,800,50.5,{isStatic:!0})]);var A=s.create(u.canvas),B=a.create(l,{mouse:A,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(d,B),u.mouse=A,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.compound.title="Compound Bodies",r.compound.for=">=0.14.2",e.exports=r.compound},elWf:function(e,t,n){var r=r||{};r.rounded=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.MouseConstraint,o=Matter.Mouse,i=Matter.Composite,a=Matter.Bodies,s=e.create(),c=s.world,l=t.create({element:document.body,engine:s,options:{width:800,height:600,showAxes:!0}});t.run(l);var d=n.create();n.run(d,s),i.add(c,[a.rectangle(400,0,800,50,{isStatic:!0}),a.rectangle(400,600,800,50,{isStatic:!0}),a.rectangle(800,300,50,600,{isStatic:!0}),a.rectangle(0,300,50,600,{isStatic:!0})]),i.add(c,[a.rectangle(200,200,100,100,{chamfer:{radius:20}}),a.rectangle(300,200,100,100,{chamfer:{radius:[90,0,0,0]}}),a.rectangle(400,200,200,200,{chamfer:{radius:[150,20,40,20]}}),a.rectangle(200,200,200,200,{chamfer:{radius:[150,20,150,20]}}),a.rectangle(300,200,200,50,{chamfer:{radius:[25,25,0,0]}}),a.polygon(200,100,8,80,{chamfer:{radius:30}}),a.polygon(300,100,5,80,{chamfer:{radius:[10,40,20,40,10]}}),a.polygon(400,200,3,50,{chamfer:{radius:[20,0,20]}})]);var u=o.create(l.canvas),p=r.create(s,{mouse:u,constraint:{stiffness:.2,render:{visible:!1}}});return i.add(c,p),l.mouse=u,t.lookAt(l,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:s,runner:d,render:l,canvas:l.canvas,stop:function(){Matter.Render.stop(l),Matter.Runner.stop(d)}}},r.rounded.title="Rounded Corners (Chamfering)",r.rounded.for=">=0.14.2",e.exports=r.rounded},ga9t:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("m6Dm"),a=n("yw0d"),s=n("Tgw/"),c=n("JKEF"),l=n("571F");r._warming=.4,r._torqueDampen=1,r._minLength=1e-6,r.create=function(e){var t=e;t.bodyA&&!t.pointA&&(t.pointA={x:0,y:0}),t.bodyB&&!t.pointB&&(t.pointB={x:0,y:0});var n=t.bodyA?i.add(t.bodyA.position,t.pointA):t.pointA,r=t.bodyB?i.add(t.bodyB.position,t.pointB):t.pointB,o=i.magnitude(i.sub(n,r));t.length=void 0!==t.length?t.length:o,t.id=t.id||l.nextId(),t.label=t.label||"Constraint",t.type="constraint",t.stiffness=t.stiffness||(t.length>0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=l.extend(a,t.render),t},r.preSolveAll=function(e){for(var t=0;t0&&(u.position.x+=l.x,u.position.y+=l.y),0!==l.angle&&(o.rotate(u.vertices,l.angle,n.position),c.rotate(u.axes,l.angle),d>0&&i.rotateAbout(u.position,l.angle,n.position,u.position)),s.update(u.bounds,u.vertices,n.velocity)}l.angle*=r._warming,l.x*=r._warming,l.y*=r._warming}}},r.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+e.pointA.x,y:(e.bodyA?e.bodyA.position.y:0)+e.pointA.y}},r.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+e.pointB.x,y:(e.bodyB?e.bodyB.position.y:0)+e.pointB.y}}},ibhy:function(e,t,n){var r=r||{};r.mixed=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}));s.add(d,m),s.add(d,[c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.mixed.title="Mixed Shapes",r.mixed.for=">=0.14.2",e.exports=r.mixed},"ix+/":function(e,t,n){var r={};e.exports=r;var o=n("571F"),i=n("Z/YF");r.create=function(e){return o.extend({bodies:[],pairs:null},e)},r.setBodies=function(e,t){e.bodies=t.slice(0)},r.clear=function(e){e.bodies=[]},r.collisions=function(e){var t,n,o=[],a=e.pairs,s=e.bodies,c=s.length,l=r.canCollide,d=i.collides;for(s.sort(r._compareBoundsX),t=0;tm)break;if(!(fk.max.y)&&(!g||!h.isStatic&&!h.isSleeping)&&l(u.collisionFilter,h.collisionFilter)){var M=h.parts.length;if(x&&1===M)(A=d(u,h,a))&&o.push(A);else for(var b=M>1?1:0,S=y>1?1:0;Sk.max.x||p.max.xk.max.y||(A=d(w,B,a))&&o.push(A)}}}}return o},r.canCollide=function(e,t){return e.group===t.group&&0!==e.group?e.group>0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)},r._compareBoundsX=function(e,t){return e.bounds.min.x-t.bounds.min.x}},k7Ch:function(e,t,n){var r=r||{};r.gyro=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.Common,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.Composite,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showAngleIndicator:!0}});t.run(u);var p=n.create();n.run(p,l);var m=r.stack(20,20,10,5,0,0,(function(e,t){var n=Math.round(o.random(1,8)),r=null;switch(n>2&&o.random()>.7&&(r={radius:10}),Math.round(o.random(0,1))){case 0:return o.random()<.8?c.rectangle(e,t,o.random(25,50),o.random(25,50),{chamfer:r}):c.rectangle(e,t,o.random(80,120),o.random(25,30),{chamfer:r});case 1:return c.polygon(e,t,n,o.random(25,50),{chamfer:r})}}));if(s.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]),"undefined"!=typeof window){var f=function(e){var t=void 0!==window.orientation?window.orientation:0,n=l.gravity;0===t?(n.x=o.clamp(e.gamma,-90,90)/90,n.y=o.clamp(e.beta,-90,90)/90):180===t?(n.x=o.clamp(e.gamma,-90,90)/90,n.y=o.clamp(-e.beta,-90,90)/90):90===t?(n.x=o.clamp(e.beta,-90,90)/90,n.y=o.clamp(-e.gamma,-90,90)/90):-90===t&&(n.x=o.clamp(-e.beta,-90,90)/90,n.y=o.clamp(e.gamma,-90,90)/90)};window.addEventListener("deviceorientation",f)}var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p),"undefined"!=typeof window&&window.removeEventListener("deviceorientation",f)}}},r.gyro.title="Gyroscope",r.gyro.for=">=0.14.2",e.exports=r.gyro},lWug:function(e,t,n){var r={};e.exports=r;var o=n("571F"),i=n("wAS/"),a=n("Tgw/"),s=n("yTB+"),c=n("m6Dm"),l=n("I5nt");!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout((function(){e(o.now())}),1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),r._goodFps=30,r._goodDelta=1e3/60,r.create=function(e){var t={controller:r,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,timing:{historySize:60,delta:0,deltaHistory:[],lastTime:0,lastTimestamp:0,lastElapsed:0,timestampElapsed:0,timestampElapsedHistory:[],engineDeltaHistory:[],engineElapsedHistory:[],elapsedHistory:[]},options:{width:800,height:600,pixelRatio:1,background:"#14151f",wireframeBackground:"#14151f",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showStats:!1,showPerformance:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},n=o.extend(t,e);return n.canvas&&(n.canvas.width=n.options.width||n.canvas.width,n.canvas.height=n.options.height||n.canvas.height),n.mouse=e.mouse,n.engine=e.engine,n.canvas=n.canvas||u(n.options.width,n.options.height),n.context=n.canvas.getContext("2d"),n.textures={},n.bounds=n.bounds||{min:{x:0,y:0},max:{x:n.canvas.width,y:n.canvas.height}},n.options.showBroadphase=!1,1!==n.options.pixelRatio&&r.setPixelRatio(n,n.options.pixelRatio),o.isElement(n.element)?n.element.appendChild(n.canvas):n.canvas.parentNode||o.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),n},r.run=function(t){!function o(i){t.frameRequestId=e(o),n(t,i),r.world(t,i),(t.options.showStats||t.options.showDebug)&&r.stats(t,t.context,i),(t.options.showPerformance||t.options.showDebug)&&r.performance(t,t.context,i)}()},r.stop=function(e){t(e.frameRequestId)},r.setPixelRatio=function(e,t){var n=e.options,r=e.canvas;"auto"===t&&(t=p(r)),n.pixelRatio=t,r.setAttribute("data-pixel-ratio",t),r.width=n.width*t,r.height=n.height*t,r.style.width=n.width+"px",r.style.height=n.height+"px"},r.lookAt=function(e,t,n,r){r=void 0===r||r,t=o.isArray(t)?t:[t],n=n||{x:0,y:0};for(var i={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},a=0;ai.max.x&&(i.max.x=d.x),c.yi.max.y&&(i.max.y=d.y))}var u=i.max.x-i.min.x+2*n.x,p=i.max.y-i.min.y+2*n.y,m=e.canvas.height,f=e.canvas.width/m,v=u/p,g=1,y=1;v>f?y=v/f:g=f/v,e.options.hasBounds=!0,e.bounds.min.x=i.min.x,e.bounds.max.x=i.min.x+u*g,e.bounds.min.y=i.min.y,e.bounds.max.y=i.min.y+p*y,r&&(e.bounds.min.x+=.5*u-u*g*.5,e.bounds.max.x+=.5*u-u*g*.5,e.bounds.min.y+=.5*p-p*y*.5,e.bounds.max.y+=.5*p-p*y*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(l.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),l.setOffset(e.mouse,e.bounds.min))},r.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,r=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/r,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},r.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},r.world=function(e,t){var n,d=o.now(),u=e.engine,p=u.world,m=e.canvas,v=e.context,g=e.options,y=e.timing,x=i.allBodies(p),h=i.allConstraints(p),M=g.wireframes?g.wireframeBackground:g.background,b=[],S=[],w={timestamp:u.timing.timestamp};if(s.trigger(e,"beforeRender",w),e.currentBackground!==M&&f(e,M),v.globalCompositeOperation="source-in",v.fillStyle="transparent",v.fillRect(0,0,m.width,m.height),v.globalCompositeOperation="source-over",g.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;i1?1:0;s1?1:0;i1?1:0;i1?1:0;o0)){var d=r.activeContacts[0].vertex.x,u=r.activeContacts[0].vertex.y;2===r.activeContacts.length&&(d=(r.activeContacts[0].vertex.x+r.activeContacts[1].vertex.x)/2,u=(r.activeContacts[0].vertex.y+r.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(d-8*o.normal.x,u-8*o.normal.y):s.moveTo(d+8*o.normal.x,u+8*o.normal.y),s.lineTo(d,u)}c.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},r.separations=function(e,t,n){var r,o,i,a,s,c=n,l=e.options;for(c.beginPath(),s=0;s0&&c.trigger(e,"collisionStart",{pairs:g.collisionStart}),i.preSolvePosition(g.list),m=0;m0&&c.trigger(e,"collisionActive",{pairs:g.collisionActive}),g.collisionEnd.length>0&&c.trigger(e,"collisionEnd",{pairs:g.collisionEnd}),r._bodiesClearForces(M),c.trigger(e,"afterUpdate",h),e.timing.lastElapsed=u.now()-p,e},r.merge=function(e,t){if(u.extend(e,t),t.world){e.world=t.world,r.clear(e);for(var n=l.allBodies(e.world),i=0;i0&&o.area(B)1?(f=a.create(i.extend({parts:v.slice(0)},r)),a.setPosition(f,{x:e,y:t}),f):v[0]}},"pm/U":function(e,t,n){var r={};e.exports=r;var o=n("2Og8"),i=n("571F");r.name="matter-js",r.version="*",r.uses=[],r.used=[],r.use=function(){o.use(r,Array.prototype.slice.call(arguments))},r.before=function(e,t){return e=e.replace(/^Matter./,""),i.chainPathBefore(r,e,t)},r.after=function(e,t){return e=e.replace(/^Matter./,""),i.chainPathAfter(r,e,t)}},q4y7:function(e,t,n){var r={};e.exports=r;var o=n("0kzT"),i=n("yw0d"),a=n("I5nt"),s=n("yTB+"),c=n("ix+/"),l=n("ga9t"),d=n("wAS/"),u=n("571F"),p=n("Tgw/");r.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=a.create(e.render.canvas):t&&t.element?n=a.create(t.element):(n=a.create(),u.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var o={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:l.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),collisionFilter:{category:1,mask:4294967295,group:0}},i=u.extend(o,t);return s.on(e,"beforeUpdate",(function(){var t=d.allBodies(e.world);r.update(i,t),r._triggerEvents(i)})),i},r.update=function(e,t){var n=e.mouse,r=e.constraint,a=e.body;if(0===n.button){if(r.bodyB)i.set(r.bodyB,!1),r.pointA=n.position;else for(var l=0;l1?1:0;d=0.14.2",r.cloth.cloth=function(e,t,n,r,o,i,a,s,c,l){var d=Matter.Body,u=Matter.Bodies,p=Matter.Common,m=Matter.Composites,f=d.nextGroup(!0);c=p.extend({inertia:1/0,friction:1e-5,collisionFilter:{group:f},render:{visible:!1}},c),l=p.extend({stiffness:.06,render:{type:"line",anchors:!1}},l);var v=m.stack(e,t,n,r,o,i,(function(e,t){return u.circle(e,t,s,c)}));return m.mesh(v,n,r,a,l),v.label="Cloth Body",v},e.exports=r.cloth},t8gT:function(e,t,n){var r={};e.exports=r;var o=n("9K63");r.create=function(e,t){var n=e.bodyA,o=e.bodyB,i={id:r.id(n,o),bodyA:n,bodyB:o,collision:e,contacts:[],activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:n.isSensor||o.isSensor,timeCreated:t,timeUpdated:t,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return r.update(i,e,t),i},r.update=function(e,t,n){var r=e.contacts,i=t.supports,a=e.activeContacts,s=t.parentA,c=t.parentB,l=s.vertices.length;e.isActive=!0,e.timeUpdated=n,e.collision=t,e.separation=t.depth,e.inverseMass=s.inverseMass+c.inverseMass,e.friction=s.frictionc.frictionStatic?s.frictionStatic:c.frictionStatic,e.restitution=s.restitution>c.restitution?s.restitution:c.restitution,e.slop=s.slop>c.slop?s.slop:c.slop,t.pair=e,a.length=0;for(var d=0;d.35?c.rectangle(e,t,64,64,{render:{strokeStyle:"#ffffff",sprite:{texture:"./img/box.png"}}}):c.circle(e,t,46,{density:5e-4,frictionAir:.06,restitution:.3,friction:.01,render:{sprite:{texture:"./img/ball.png"}}})}));s.add(d,f);var v=a.create(u.canvas),g=i.create(l,{mouse:v,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,g),u.mouse=v,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.sprites.title="Sprites",r.sprites.for=">=0.14.2",e.exports=r.sprites},ttsO:function(e,t,n){var r={};e.exports=r;var o=n("t8gT"),i=n("571F");r.create=function(e){return i.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},r.update=function(e,t,n){var r,i,a,s,c=e.list,l=c.length,d=e.table,u=t.length,p=e.collisionStart,m=e.collisionEnd,f=e.collisionActive;for(p.length=0,m.length=0,f.length=0,s=0;s=0?i(s,false):a(s,false)},vSND:function(e,t,n){var r=r||{};r.stats=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Common,o=Matter.Composites,i=Matter.MouseConstraint,a=Matter.Mouse,s=Matter.World,c=Matter.Bodies,l=e.create(),d=l.world,u=t.create({element:document.body,engine:l,options:{width:800,height:600,showStats:!0,showPerformance:!0}});t.run(u);var p=n.create();n.run(p,l);var m=o.stack(70,30,13,9,5,5,(function(e,t){return c.circle(e,t,10+20*r.random())}));s.add(d,[m,c.rectangle(400,0,800,50,{isStatic:!0}),c.rectangle(400,600,800,50,{isStatic:!0}),c.rectangle(800,300,50,600,{isStatic:!0}),c.rectangle(0,300,50,600,{isStatic:!0})]);var f=a.create(u.canvas),v=i.create(l,{mouse:f,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(d,v),u.mouse=f,t.lookAt(u,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:l,runner:p,render:u,canvas:u.canvas,stop:function(){Matter.Render.stop(u),Matter.Runner.stop(p)}}},r.stats.title="Stats & Performance",r.stats.for=">=0.16.1",e.exports=r.stats},"wAS/":function(e,t,n){var r={};e.exports=r;var o=n("yTB+"),i=n("571F"),a=n("Tgw/"),s=n("IbIC");r.create=function(e){return i.extend({id:i.nextId(),type:"composite",parent:null,isModified:!1,bodies:[],constraints:[],composites:[],label:"Composite",plugin:{},cache:{allBodies:null,allConstraints:null,allComposites:null}},e)},r.setModified=function(e,t,n,o){if(e.isModified=t,t&&e.cache&&(e.cache.allBodies=null,e.cache.allConstraints=null,e.cache.allComposites=null),n&&e.parent&&r.setModified(e.parent,t,n,o),o)for(var i=0;i=0.14.2",e.exports=r.bridge},xoNv:function(e,t,n){var r=r||{};r.newtonsCradle=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,o=Matter.Body,i=(Matter.Composites,Matter.MouseConstraint),a=Matter.Mouse,s=Matter.Composite,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showVelocity:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.newtonsCradle.newtonsCradle(280,100,5,30,200);s.add(l,p),o.translate(p.bodies[0],{x:-180,y:-100}),p=r.newtonsCradle.newtonsCradle(280,380,7,20,140),s.add(l,p),o.translate(p.bodies[0],{x:-140,y:-100});var m=a.create(d.canvas),f=i.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return s.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:50},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.newtonsCradle.title="Newton's Cradle",r.newtonsCradle.for=">=0.14.2",r.newtonsCradle.newtonsCradle=function(e,t,n,r,o){for(var i=Matter.Composite,a=Matter.Constraint,s=Matter.Bodies,c=i.create({label:"Newtons Cradle"}),l=0;l0){n||(n={}),r=t.split(" ");for(var l=0;l=0.14.2",e.exports=r.sensors},yw0d:function(e,t,n){var r={};e.exports=r;var o=n("yTB+");r._motionWakeThreshold=.18,r._motionSleepThreshold=.08,r._minBias=.9,r.update=function(e,t){for(var n=t*t*t,o=0;o0&&i.motion=i.sleepThreshold&&r.set(i,!0)):i.sleepCounter>0&&(i.sleepCounter-=1)}else r.set(i,!1)}},r.afterCollisions=function(e,t){for(var n=t*t*t,o=0;or._motionWakeThreshold*n&&r.set(l,!1)}}}},r.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||o.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&o.trigger(e,"sleepEnd"))}},zc7U:function(e,t,n){var r=r||{};r.circleStack=function(){var e=Matter.Engine,t=Matter.Render,n=Matter.Runner,r=Matter.Composites,o=Matter.MouseConstraint,i=Matter.Mouse,a=Matter.Composite,s=Matter.Bodies,c=e.create(),l=c.world,d=t.create({element:document.body,engine:c,options:{width:800,height:600,showAngleIndicator:!0}});t.run(d);var u=n.create();n.run(u,c);var p=r.stack(100,179,10,10,20,0,(function(e,t){return s.circle(e,t,20)}));a.add(l,[s.rectangle(400,0,800,50,{isStatic:!0}),s.rectangle(400,600,800,50,{isStatic:!0}),s.rectangle(800,300,50,600,{isStatic:!0}),s.rectangle(0,300,50,600,{isStatic:!0}),p]);var m=i.create(d.canvas),f=o.create(c,{mouse:m,constraint:{stiffness:.2,render:{visible:!1}}});return a.add(l,f),d.mouse=m,t.lookAt(d,{min:{x:0,y:0},max:{x:800,y:600}}),{engine:c,runner:u,render:d,canvas:d.canvas,stop:function(){Matter.Render.stop(d),Matter.Runner.stop(u)}}},r.circleStack.title="Circle Stack",r.circleStack.for=">=0.14.2",e.exports=r.circleStack}},[["uZME",1,2,3,4,5]]])})); \ No newline at end of file diff --git a/demo/js/matter-demo.main.5754e1.min.js b/demo/js/matter-demo.main.5754e1.min.js index 1455919..96e16ab 100644 --- a/demo/js/matter-demo.main.5754e1.min.js +++ b/demo/js/matter-demo.main.5754e1.min.js @@ -1,5 +1,5 @@ /*! - * matter-demo bundle 0.18.0 by @liabru + * matter-demo bundle 0.19.0 by @liabru * http://brm.io/matter-js/ * License MIT */!function(e){function t(t){for(var n,l,a=t[0],f=t[1],i=t[2],c=0,s=[];c (http://brm.io/)",