PageSourceSearch

https://wangyasai.github.io/js/matter.js

js wangyasai.github.io collected 2026-10-03 10:09:29 UTC 345,625 bytes, 10,361 lines download raw bytes

vendor: 22,746 bytes, lines 1-621
1/**
2* matter-js 0.14.2 by @liabru 2018-06-11
3* http://brm.io/matter-js/
4* License MIT
5*/
6
7/**
8 * The MIT License (MIT)
9 * 
10 * Copyright (c) Liam Brummitt and contributors.
11 * 
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
18 * 
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 * 
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 * THE SOFTWARE.
29 */
30
31(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Matter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
32/**
33* The `Matter.Body` module contains methods for creating and manipulating body models.
34* A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
35* Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`.
36*
37* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
38
39* @class Body
40*/
41
42var Body = {};
43
44module.exports = Body;
45
46var Vertices = _dereq_('../geometry/Vertices');
47var Vector = _dereq_('../geometry/Vector');
48var Sleeping = _dereq_('../core/Sleeping');
49var Render = _dereq_('../render/Render');
50var Common = _dereq_('../core/Common');
51var Bounds = _dereq_('../geometry/Bounds');
52var Axes = _dereq_('../geometry/Axes');
53
54(function() {
55
56    Body._inertiaScale = 4;
57    Body._nextCollidingGroupId = 1;
58    Body._nextNonCollidingGroupId = -1;
59    Body._nextCategory = 0x0001;
60
61    /**
62     * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults.
63     * All properties have default values, and many are pre-calculated automatically based on other properties.
64     * Vertices must be specified in clockwise order.
65     * See the properties section below for detailed information on what you can pass via the `options` object.
66     * @method create
67     * @param {} options
68     * @return {body} body
69     */
70    Body.create = function(options) {
71        var defaults = {
72            id: Common.nextId(),
73            type: 'body',
74            label: 'Body',
75            parts: [],
76            plugin: {},
77            angle: 0,
78            vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
79            position: { x: 0, y: 0 },
80            force: { x: 0, y: 0 },
81            torque: 0,
82            positionImpulse: { x: 0, y: 0 },
83            constraintImpulse: { x: 0, y: 0, angle: 0 },
84            totalContacts: 0,
85            speed: 0,
86            angularSpeed: 0,
87            velocity: { x: 0, y: 0 },
88            angularVelocity: 0,
89            isSensor: false,
90            isStatic: false,
91            isSleeping: false,
92            motion: 0,
93            sleepThreshold: 60,
94            density: 0.001,
95            restitution: 0,
96            friction: 0.1,
97            frictionStatic: 0.5,
98            frictionAir: 0.01,
99            collisionFilter: {
100                category: 0x0001,
101                mask: 0xFFFFFFFF,
102                group: 0
103            },
104            slop: 0.05,
105            timeScale: 1,
106            render: {
107                visible: true,
108                opacity: 1,
109                sprite: {
110                    xScale: 1,
111                    yScale: 1,
112                    xOffset: 0,
113                    yOffset: 0
114                },
115                lineWidth: 0
116            }
117        };
118
119        var body = Common.extend(defaults, options);
120
121        _initProperties(body, options);
122
123        return body;
124    };
125
126    /**
127     * Returns the next unique group index for which bodies will collide.
128     * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide.
129     * See `body.collisionFilter` for more information.
130     * @method nextGroup
131     * @param {bool} [isNonColliding=false]
132     * @return {Number} Unique group index
133     */
134    Body.nextGroup = function(isNonColliding) {
135        if (isNonColliding)
136            return Body._nextNonCollidingGroupId--;
137
138        return Body._nextCollidingGroupId++;
139    };
140
141    /**
142     * Returns the next unique category bitfield (starting after the initial default category `0x0001`).
143     * There are 32 available. See `body.collisionFilter` for more information.
144     * @method nextCategory
145     * @return {Number} Unique category bitfield
146     */
147    Body.nextCategory = function() {
148        Body._nextCategory = Body._nextCategory << 1;
149        return Body._nextCategory;
150    };
151
152    /**
153     * Initialises body properties.
154     * @method _initProperties
155     * @private
156     * @param {body} body
157     * @param {} [options]
158     */
159    var _initProperties = function(body, options) {
160        options = options || {};
161
162        // init required properties (order is important)
163        Body.set(body, {
164            bounds: body.bounds || Bounds.create(body.vertices),
165            positionPrev: body.positionPrev || Vector.clone(body.position),
166            anglePrev: body.anglePrev || body.angle,
167            vertices: body.vertices,
168            parts: body.parts || [body],
169            isStatic: body.isStatic,
170            isSleeping: body.isSleeping,
171            parent: body.parent || body
172        });
173
174        Vertices.rotate(body.vertices, body.angle, body.position);
175        Axes.rotate(body.axes, body.angle);
176        Bounds.update(body.bounds, body.vertices, body.velocity);
177
178        // allow options to override the automatically calculated properties
179        Body.set(body, {
180            axes: options.axes || body.axes,
181            area: options.area || body.area,
182            mass: options.mass || body.mass,
183            inertia: options.inertia || body.inertia
184        });
185
186        // render properties
187        var defaultFillStyle = (body.isStatic ? '#2e2b44' : Common.choose(['#006BA6', '#0496FF', '#FFBC42', '#D81159', '#8F2D56'])),
188            defaultStrokeStyle = '#000';
189        body.render.fillStyle = body.render.fillStyle || defaultFillStyle;
190        body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle;
191        body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x);
192        body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y);
193    };
194
195    /**
196     * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist.
197     * Prefer to use the actual setter functions in performance critical situations.
198     * @method set
199     * @param {body} body
200     * @param {} settings A property name (or map of properties and values) to set on the body.
201     * @param {} value The value to set if `settings` is a single property name.
202     */
203    Body.set = function(body, settings, value) {
204        var property;
205
206        if (typeof settings === 'string') {
207            property = settings;
208            settings = {};
209            settings[property] = value;
210        }
211
212        for (property in settings) {
213            value = settings[property];
214
215            if (!settings.hasOwnProperty(property))
216                continue;
217
218            switch (property) {
219
220            case 'isStatic':
221                Body.setStatic(body, value);
222                break;
223            case 'isSleeping':
224                Sleeping.set(body, value);
225                break;
226            case 'mass':
227                Body.setMass(body, value);
228                break;
229            case 'density':
230                Body.setDensity(body, value);
231                break;
232            case 'inertia':
233                Body.setInertia(body, value);
234                break;
235            case 'vertices':
236                Body.setVertices(body, value);
237                break;
238            case 'position':
239                Body.setPosition(body, value);
240                break;
241            case 'angle':
242                Body.setAngle(body, value);
243                break;
244            case 'velocity':
245                Body.setVelocity(body, value);
246                break;
247            case 'angularVelocity':
248                Body.setAngularVelocity(body, value);
249                break;
250            case 'parts':
251                Body.setParts(body, value);
252                break;
253            default:
254                body[property] = value;
255
256            }
257        }
258    };
259
260    /**
261     * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity.
262     * @method setStatic
263     * @param {body} body
264     * @param {bool} isStatic
265     */
266    Body.setStatic = function(body, isStatic) {
267        for (var i = 0; i < body.parts.length; i++) {
268            var part = body.parts[i];
269            part.isStatic = isStatic;
270
271            if (isStatic) {
272                part._original = {
273                    restitution: part.restitution,
274                    friction: part.friction,
275                    mass: part.mass,
276                    inertia: part.inertia,
277                    density: part.density,
278                    inverseMass: part.inverseMass,
279                    inverseInertia: part.inverseInertia
280                };
281
282                part.restitution = 0;
283                part.friction = 1;
284                part.mass = part.inertia = part.density = Infinity;
285                part.inverseMass = part.inverseInertia = 0;
286
287                part.positionPrev.x = part.position.x;
288                part.positionPrev.y = part.position.y;
289                part.anglePrev = part.angle;
290                part.angularVelocity = 0;
291                part.speed = 0;
292                part.angularSpeed = 0;
293                part.motion = 0;
294            } else if (part._original) {
295                part.restitution = part._original.restitution;
296                part.friction = part._original.friction;
297                part.mass = part._original.mass;
298                part.inertia = part._original.inertia;
299                part.density = part._original.density;
300                part.inverseMass = part._original.inverseMass;
301                part.inverseInertia = part._original.inverseInertia;
302
303                delete part._original;
304            }
305        }
306    };
307
308    /**
309     * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change.
310     * @method setMass
311     * @param {body} body
312     * @param {number} mass
313     */
314    Body.setMass = function(body, mass) {
315        var moment = body.inertia / (body.mass / 6);
316        body.inertia = moment * (mass / 6);
317        body.inverseInertia = 1 / body.inertia;
318
319        body.mass = mass;
320        body.inverseMass = 1 / body.mass;
321        body.density = body.mass / body.area;
322    };
323
324    /**
325     * Sets the density of the body. Mass and inertia are automatically updated to reflect the change.
326     * @method setDensity
327     * @param {body} body
328     * @param {number} density
329     */
330    Body.setDensity = function(body, density) {
331        Body.setMass(body, density * body.area);
332        body.density = density;
333    };
334
335    /**
336     * Sets the moment of inertia (i.e. second moment of area) of the body of the body. 
337     * Inverse inertia is automatically updated to reflect the change. Mass is not changed.
338     * @method setInertia
339     * @param {body} body
340     * @param {number} inertia
341     */
342    Body.setInertia = function(body, inertia) {
343        body.inertia = inertia;
344        body.inverseInertia = 1 / body.inertia;
345    };
346
347    /**
348     * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`).
349     * Vertices will be automatically transformed to be orientated around their centre of mass as the origin.
350     * They are then automatically translated to world space based on `body.position`.
351     *
352     * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array).
353     * Vertices must form a convex hull, concave hulls are not supported.
354     *
355     * @method setVertices
356     * @param {body} body
357     * @param {vector[]} vertices
358     */
359    Body.setVertices = function(body, vertices) {
360        // change vertices
361        if (vertices[0].body === body) {
362            body.vertices = vertices;
363        } else {
364            body.vertices = Vertices.create(vertices, body);
365        }
366
367        // update properties
368        body.axes = Axes.fromVertices(body.vertices);
369        body.area = Vertices.area(body.vertices);
370        Body.setMass(body, body.density * body.area);
371
372        // orient vertices around the centre of mass at origin (0, 0)
373        var centre = Vertices.centre(body.vertices);
374        Vertices.translate(body.vertices, centre, -1);
375
376        // update inertia while vertices are at origin (0, 0)
377        Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass));
378
379        // update geometry
380        Vertices.translate(body.vertices, body.position);
381        Bounds.update(body.bounds, body.vertices, body.velocity);
382    };
383
384    /**
385     * Sets the parts of the `body` and updates mass, inertia and centroid.
386     * Each part will have its parent set to `body`.
387     * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
388     * Note that this method will ensure that the first part in `body.parts` will always be the `body`.
389     * @method setParts
390     * @param {body} body
391     * @param [body] parts
392     * @param {bool} [autoHull=true]
393     */
394    Body.setParts = function(body, parts, autoHull) {
395        var i;
396
397        // add all the parts, ensuring that the first part is always the parent body
398        parts = parts.slice(0);
399        body.parts.length = 0;
400        body.parts.push(body);
401        body.parent = body;
402
403        for (i = 0; i < parts.length; i++) {
404            var part = parts[i];
405            if (part !== body) {
406                part.parent = body;
407                body.parts.push(part);
408            }
409        }
410
411        if (body.parts.length === 1)
412            return;
413
414        autoHull = typeof autoHull !== 'undefined' ? autoHull : true;
415
416        // find the convex hull of all parts to set on the parent body
417        if (autoHull) {
418            var vertices = [];
419            for (i = 0; i < parts.length; i++) {
420                vertices = vertices.concat(parts[i].vertices);
421            }
422
423            Vertices.clockwiseSort(vertices);
424
425            var hull = Vertices.hull(vertices),
426                hullCentre = Vertices.centre(hull);
427
428            Body.setVertices(body, hull);
429            Vertices.translate(body.vertices, hullCentre);
430        }
431
432        // sum the properties of all compound parts of the parent body
433        var total = Body._totalProperties(body);
434
435        body.area = total.area;
436        body.parent = body;
437        body.position.x = total.centre.x;
438        body.position.y = total.centre.y;
439        body.positionPrev.x = total.centre.x;
440        body.positionPrev.y = total.centre.y;
441
442        Body.setMass(body, total.mass);
443        Body.setInertia(body, total.inertia);
444        Body.setPosition(body, total.centre);
445    };
446
447    /**
448     * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
449     * @method setPosition
450     * @param {body} body
451     * @param {vector} position
452     */
453    Body.setPosition = function(body, position) {
454        var delta = Vector.sub(position, body.position);
455        body.positionPrev.x += delta.x;
456        body.positionPrev.y += delta.y;
457
458        for (var i = 0; i < body.parts.length; i++) {
459            var part = body.parts[i];
460            part.position.x += delta.x;
461            part.position.y += delta.y;
462            Vertices.translate(part.vertices, delta);
463            Bounds.update(part.bounds, part.vertices, body.velocity);
464        }
465    };
466
467    /**
468     * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged.
469     * @method setAngle
470     * @param {body} body
471     * @param {number} angle
472     */
473    Body.setAngle = function(body, angle) {
474        var delta = angle - body.angle;
475        body.anglePrev += delta;
476
477        for (var i = 0; i < body.parts.length; i++) {
478            var part = body.parts[i];
479            part.angle += delta;
480            Vertices.rotate(part.vertices, delta, body.position);
481            Axes.rotate(part.axes, delta);
482            Bounds.update(part.bounds, part.vertices, body.velocity);
483            if (i > 0) {
484                Vector.rotateAbout(part.position, delta, body.position, part.position);
485            }
486        }
487    };
488
489    /**
490     * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
491     * @method setVelocity
492     * @param {body} body
493     * @param {vector} velocity
494     */
495    Body.setVelocity = function(body, velocity) {
496        body.positionPrev.x = body.position.x - velocity.x;
497        body.positionPrev.y = body.position.y - velocity.y;
498        body.velocity.x = velocity.x;
499        body.velocity.y = velocity.y;
500        body.speed = Vector.magnitude(body.velocity);
501    };
502
503    /**
504     * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
505     * @method setAngularVelocity
506     * @param {body} body
507     * @param {number} velocity
508     */
509    Body.setAngularVelocity = function(body, velocity) {
510        body.anglePrev = body.angle - velocity;
511        body.angularVelocity = velocity;
512        body.angularSpeed = Math.abs(body.angularVelocity);
513    };
514
515    /**
516     * Moves a body by a given vector relative to its current position, without imparting any velocity.
517     * @method translate
518     * @param {body} body
519     * @param {vector} translation
520     */
521    Body.translate = function(body, translation) {
522        Body.setPosition(body, Vector.add(body.position, translation));
523    };
524
525    /**
526     * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity.
527     * @method rotate
528     * @param {body} body
529     * @param {number} rotation
530     * @param {vector} [point]
531     */
532    Body.rotate = function(body, rotation, point) {
533        if (!point) {
534            Body.setAngle(body, body.angle + rotation);
535        } else {
536            var cos = Math.cos(rotation),
537                sin = Math.sin(rotation),
538                dx = body.position.x - point.x,
539                dy = body.position.y - point.y;
540                
541            Body.setPosition(body, {
542                x: point.x + (dx * cos - dy * sin),
543                y: point.y + (dx * sin + dy * cos)
544            });
545
546            Body.setAngle(body, body.angle + rotation);
547        }
548    };
549
550    /**
551     * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre).
552     * @method scale
553     * @param {body} body
554     * @param {number} scaleX
555     * @param {number} scaleY
556     * @param {vector} [point]
557     */
558    Body.scale = function(body, scaleX, scaleY, point) {
559        var totalArea = 0,
560            totalInertia = 0;
561
562        point = point || body.position;
563
564        for (var i = 0; i < body.parts.length; i++) {
565            var part = body.parts[i];
566
567            // scale vertices
568            Vertices.scale(part.vertices, scaleX, scaleY, point);
569
570            // update properties
571            part.axes = Axes.fromVertices(part.vertices);
572            part.area = Vertices.area(part.vertices);
573            Body.setMass(part, body.density * part.area);
574
575            // update inertia (requires vertices to be at origin)
576            Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
577            Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
578            Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
579
580            if (i > 0) {
581                totalArea += part.area;
582                totalInertia += part.inertia;
583            }
584
585            // scale position
586            part.position.x = point.x + (part.position.x - point.x) * scaleX;
587            part.position.y = point.y + (part.position.y - point.y) * scaleY;
588
589            // update bounds
590            Bounds.update(part.bounds, part.vertices, body.velocity);
591        }
592
593        // handle parent body
594        if (body.parts.length > 1) {
595            body.area = totalArea;
596
597            if (!body.isStatic) {
598                Body.setMass(body, body.density * totalArea);
599                Body.setInertia(body, totalInertia);
600            }
601        }
602
603        // handle circles
604        if (body.circleRadius) { 
605            if (scaleX === scaleY) {
606                body.circleRadius *= scaleX;
607            } else {
608                // body is no longer a circle
609                body.circleRadius = null;
610            }
611        }
612    };
613
614    /**
615     * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration.
616     * @method update
617     * @param {body} body
618     * @param {number} deltaTime
619     * @param {number} timeScale
620     * @param {number} correction
621     */
622    Body.update = function(body, deltaTime, timeScale, correction) {
623        var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2);
624
625        // from the previous step
626        var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale,
627            velocityPrevX = body.position.x - body.positionPrev.x,
628            velocityPrevY = body.position.y - body.positionPrev.y;
629
630        // update velocity with Verlet integration
631        body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared;
632        body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared;
633
634        body.positionPrev.x = body.position.x;
635        body.positionPrev.y = body.position.y;
636        body.position.x += body.velocity.x;
637        body.position.y += body.velocity.y;
638
639        // update angular velocity with Verlet integration
640        body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared;
641        body.anglePrev = body.angle;
642        body.angle += body.angularVelocity;
643
644        // track speed and acceleration
645        body.speed = Vector.magnitude(body.velocity);
646        body.angularSpeed = Math.abs(body.angularVelocity);
647
648        // transform the body geometry
649        for (var i = 0; i < body.parts.length; i++) {
650            var part = body.parts[i];
651
652            Vertices.translate(part.vertices, body.velocity);
653            
654            if (i > 0) {
655                part.position.x += body.velocity.x;
656                part.position.y += body.velocity.y;
657            }
658
659            if (body.angularVelocity !== 0) {
660                Vertices.rotate(part.vertices, body.angularVelocity, body.position);
661                Axes.rotate(part.axes, body.angularVelocity);
662                if (i > 0) {
663                    Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position);
664                }
665            }
666
667            Bounds.update(part.bounds, part.vertices, body.velocity);
668        }
669    };
670
671    /**
672     * Applies a force to a body from a given world-space position, including resulting torque.
673     * @method applyForce
674     * @param {body} body
675     * @param {vector} position
676     * @param {vector} force
677     */
678    Body.applyForce = function(body, position, force) {
679        body.force.x += force.x;
680        body.force.y += force.y;
681        var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
682        body.torque += offset.x * force.y - offset.y * force.x;
683    };
684
685    /**
686     * Returns the sums of the properties of all compound parts of the parent body.
687     * @method _totalProperties
688     * @private
689     * @param {body} body
690     * @return {}
691     */
692    Body._totalProperties = function(body) {
693        // from equations at:
694        // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory
695        // http://output.to/sideway/default.asp?qno=121100087
696
697        var properties = {
698            mass: 0,
699            area: 0,
700            inertia: 0,
701            centre: { x: 0, y: 0 }
702        };
703
704        // sum the properties of all compound parts of the parent body
705        for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) {
706            var part = body.parts[i],
707                mass = part.mass !== Infinity ? part.mass : 1;
708
709            properties.mass += mass;
710            properties.area += part.area;
711            properties.inertia += part.inertia;
712            properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass));
713        }
714
715        properties.centre = Vector.div(properties.centre, properties.mass);
716
717        return properties;
718    };
719
720    /*
721    *
722    *  Events Documentation
723    *
724    */
725
726    /**
727    * Fired when a body starts sleeping (where `this` is the body).
728    *
729    * @event sleepStart
730    * @this {body} The body that has started sleeping
731    * @param {} event An event object
732    * @param {} event.source The source object of the event
733    * @param {} event.name The name of the event
734    */
735
736    /**
737    * Fired when a body ends sleeping (where `this` is the body).
738    *
739    * @event sleepEnd
740    * @this {body} The body that has ended sleeping
741    * @param {} event An event object
742    * @param {} event.source The source object of the event
743    * @param {} event.name The name of the event
744    */
745
746    /*
747    *
748    *  Properties Documentation
749    *
750    */
751
752    /**
753     * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`.
754     *
755     * @property id
756     * @type number
757     */
758
759    /**
760     * A `String` denoting the type of object.
761     *
762     * @property type
763     * @type string
764     * @default "body"
765     * @readOnly
766     */
767
768    /**
769     * An arbitrary `String` name to help the user identify and manage bodies.
770     *
771     * @property label
772     * @type string
773     * @default "Body"
774     */
775
776    /**
777     * An array of bodies that make up this body. 
778     * The first body in the array must always be a self reference to the current body instance.
779     * All bodies in the `parts` array together form a single rigid compound body.
780     * Parts are allowed to overlap, have gaps or holes or even form concave bodies.
781     * Parts themselves should never be added to a `World`, only the parent body should be.
782     * Use `Body.setParts` when setting parts to ensure correct updates of all properties.
783     *
784     * @property parts
785     * @type body[]
786     */
787
788    /**
789     * An object reserved for storing plugin-specific properties.
790     *
791     * @property plugin
792     * @type {}
793     */
794
795    /**
796     * A self reference if the body is _not_ a part of another body.
797     * Otherwise this is a reference to the body that this is a part of.
798     * See `body.parts`.
799     *
800     * @property parent
801     * @type body
802     */
803
804    /**
805     * A `Number` specifying the angle of the body, in radians.
806     *
807     * @property angle
808     * @type number
809     * @default 0
810     */
811
812    /**
813     * An array of `Vector` objects that specify the convex hull of the rigid body.
814     * These should be provided about the origin `(0, 0)`. E.g.
815     *
816     *     [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
817     *
818     * 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).
819     * The `Vector` objects are also augmented with additional properties required for efficient collision detection. 
820     *
821     * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`).
822     * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices.
823     *
824     * @property vertices
825     * @type vector[]
826     */
827
828    /**
829     * A `Vector` that specifies the current world-space position of the body.
830     *
831     * @property position
832     * @type vector
833     * @default { x: 0, y: 0 }
834     */
835
836    /**
837     * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`.
838     *
839     * @property force
840     * @type vector
841     * @default { x: 0, y: 0 }
842     */
843
844    /**
845     * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`.
846     *
847     * @property torque
848     * @type number
849     * @default 0
850     */
851
852    /**
853     * 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`).
854     *
855     * @readOnly
856     * @property speed
857     * @type number
858     * @default 0
859     */
860
861    /**
862     * 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`).
863     *
864     * @readOnly
865     * @property angularSpeed
866     * @type number
867     * @default 0
868     */
869
870    /**
871     * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. 
872     * 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).
873     *
874     * @readOnly
875     * @property velocity
876     * @type vector
877     * @default { x: 0, y: 0 }
878     */
879
880    /**
881     * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. 
882     * 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).
883     *
884     * @readOnly
885     * @property angularVelocity
886     * @type number
887     * @default 0
888     */
889
890    /**
891     * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed.
892     * 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.
893     *
894     * @property isStatic
895     * @type boolean
896     * @default false
897     */
898
899    /**
900     * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically.
901     *
902     * @property isSensor
903     * @type boolean
904     * @default false
905     */
906
907    /**
908     * 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.
909     * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag.
910     *
911     * @property isSleeping
912     * @type boolean
913     * @default false
914     */
915
916    /**
917     * 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.
918     * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest.
919     *
920     * @readOnly
921     * @property motion
922     * @type number
923     * @default 0
924     */
925
926    /**
927     * 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).
928     *
929     * @property sleepThreshold
930     * @type number
931     * @default 60
932     */
933
934    /**
935     * A `Number` that defines the density of the body, that is its mass per unit area.
936     * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object.
937     * 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).
938     *
939     * @property density
940     * @type number
941     * @default 0.001
942     */
943
944    /**
945     * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead.
946     * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`).
947     *
948     * @property mass
949     * @type number
950     */
951
952    /**
953     * A `Number` that defines the inverse mass of the body (`1 / mass`).
954     * If you modify this value, you must also modify the `body.mass` property.
955     *
956     * @property inverseMass
957     * @type number
958     */
959
960    /**
961     * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body.
962     * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`.
963     * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`).
964     *
965     * @property inertia
966     * @type number
967     */
968
969    /**
970     * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`).
971     * If you modify this value, you must also modify the `body.inertia` property.
972     *
973     * @property inverseInertia
974     * @type number
975     */
976
977    /**
978     * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`.
979     * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. 
980     * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy.
981     * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula:
982     *
983     *     Math.max(bodyA.restitution, bodyB.restitution)
984     *
985     * @property restitution
986     * @type number
987     * @default 0
988     */
989
990    /**
991     * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`.
992     * A value of `0` means that the body may slide indefinitely.
993     * A value of `1` means the body may come to a stop almost instantly after a force is applied.
994     *
995     * The effects of the value may be non-linear. 
996     * High values may be unstable depending on the body.
997     * The engine uses a Coulomb friction model including static and kinetic friction.
998     * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula:
999     *
1000     *     Math.min(bodyA.friction, bodyB.friction)
1001     *
1002     * @property friction
1003     * @type number
1004     * @default 0.1
1005     */
1006
1007    /**
1008     * A `Number` that defines the static friction of the body (in the Coulomb friction model). 
1009     * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used.
1010     * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary.
1011     * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction.
1012     *
1013     * @property frictionStatic
1014     * @type number
1015     * @default 0.5
1016     */
1017
1018    /**
1019     * A `Number` that defines the air friction of the body (air resistance). 
1020     * A value of `0` means the body will never slow as it moves through space.
1021     * The higher the value, the faster a body slows when moving through space.
1022     * The effects of the value are non-linear. 
1023     *
1024     * @property frictionAir
1025     * @type number
1026     * @default 0.01
1027     */
1028
1029    /**
1030     * An `Object` that specifies the collision filtering properties of this body.
1031     *
1032     * Collisions between two bodies will obey the following rules:
1033     * - If the two bodies have the same non-zero value of `collisionFilter.group`,
1034     *   they will always collide if the value is positive, and they will never collide
1035     *   if the value is negative.
1036     * - If the two bodies have different values of `collisionFilter.group` or if one
1037     *   (or both) of the bodies has a value of 0, then the category/mask rules apply as follows:
1038     *
1039     * Each body belongs to a collision category, given by `collisionFilter.category`. This
1040     * value is used as a bit field and the category should have only one bit set, meaning that
1041     * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32
1042     * different collision categories available.
1043     *
1044     * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies
1045     * the categories it collides with (the value is the bitwise AND value of all these categories).
1046     *
1047     * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's
1048     * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0`
1049     * are both true.
1050     *
1051     * @property collisionFilter
1052     * @type object
1053     */
1054
1055    /**
1056     * An Integer `Number`, that specifies the collision group this body belongs to.
1057     * See `body.collisionFilter` for more information.
1058     *
1059     * @property collisionFilter.group
1060     * @type object
1061     * @default 0
1062     */
1063
1064    /**
1065     * A bit field that specifies the collision category this body belongs to.
1066     * The category value should have only one bit set, for example `0x0001`.
1067     * This means there are up to 32 unique collision categories available.
1068     * See `body.collisionFilter` for more information.
1069     *
1070     * @property collisionFilter.category
1071     * @type object
1072     * @default 1
1073     */
1074
1075    /**
1076     * A bit mask that specifies the collision categories this body may collide with.
1077     * See `body.collisionFilter` for more information.
1078     *
1079     * @property collisionFilter.mask
1080     * @type object
1081     * @default -1
1082     */
1083
1084    /**
1085     * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies.
1086     * Avoid changing this value unless you understand the purpose of `slop` in physics engines.
1087     * The default should generally suffice, although very large bodies may require larger values for stable stacking.
1088     *
1089     * @property slop
1090     * @type number
1091     * @default 0.05
1092     */
1093
1094    /**
1095     * 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.
1096     *
1097     * @property timeScale
1098     * @type number
1099     * @default 1
1100     */
1101
1102    /**
1103     * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
1104     *
1105     * @property render
1106     * @type object
1107     */
1108
1109    /**
1110     * A flag that indicates if the body should be rendered.
1111     *
1112     * @property render.visible
1113     * @type boolean
1114     * @default true
1115     */
1116
1117    /**
1118     * Sets the opacity to use when rendering.
1119     *
1120     * @property render.opacity
1121     * @type number
1122     * @default 1
1123    */
1124
1125    /**
1126     * An `Object` that defines the sprite properties to use when rendering, if any.
1127     *
1128     * @property render.sprite
1129     * @type object
1130     */
1131
1132    /**
1133     * An `String` that defines the path to the image to use as the sprite texture, if any.
1134     *
1135     * @property render.sprite.texture
1136     * @type string
1137     */
1138     
1139    /**
1140     * A `Number` that defines the scaling in the x-axis for the sprite, if any.
1141     *
1142     * @property render.sprite.xScale
1143     * @type number
1144     * @default 1
1145     */
1146
1147    /**
1148     * A `Number` that defines the scaling in the y-axis for the sprite, if any.
1149     *
1150     * @property render.sprite.yScale
1151     * @type number
1152     * @default 1
1153     */
1154
1155     /**
1156      * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width).
1157      *
1158      * @property render.sprite.xOffset
1159      * @type number
1160      * @default 0
1161      */
1162
1163     /**
1164      * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height).
1165      *
1166      * @property render.sprite.yOffset
1167      * @type number
1168      * @default 0
1169      */
1170
1171    /**
1172     * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined).
1173     * A value of `0` means no outline will be rendered.
1174     *
1175     * @property render.lineWidth
1176     * @type number
1177     * @default 0
1178     */
1179
1180    /**
1181     * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined).
1182     * It is the same as when using a canvas, so it accepts CSS style property values.
1183     *
1184     * @property render.fillStyle
1185     * @type string
1186     * @default a random colour
1187     */
1188
1189    /**
1190     * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined).
1191     * It is the same as when using a canvas, so it accepts CSS style property values.
1192     *
1193     * @property render.strokeStyle
1194     * @type string
1195     * @default a random colour
1196     */
1197
1198    /**
1199     * An array of unique axis vectors (edge normals) used for c
vendor: 16,384 bytes, lines 1199-1681
1199ollision detection.
1200     * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`.
1201     * They are constantly updated by `Body.update` during the simulation.
1202     *
1203     * @property axes
1204     * @type vector[]
1205     */
1206     
1207    /**
1208     * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`.
1209     *
1210     * @property area
1211     * @type string
1212     * @default 
1213     */
1214
1215    /**
1216     * A `Bounds` object that defines the AABB region for the body.
1217     * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation.
1218     *
1219     * @property bounds
1220     * @type bounds
1221     */
1222
1223})();
1224
1225},{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31}],2:[function(_dereq_,module,exports){
1226/**
1227* The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
1228* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
1229* It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
1230* Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`.
1231*
1232* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
1233*
1234* @class Composite
1235*/
1236
1237var Composite = {};
1238
1239module.exports = Composite;
1240
1241var Events = _dereq_('../core/Events');
1242var Common = _dereq_('../core/Common');
1243var Bounds = _dereq_('../geometry/Bounds');
1244var Body = _dereq_('./Body');
1245
1246(function() {
1247
1248    /**
1249     * Creates a new composite. The options parameter is an object that specifies any properties you wish to override the defaults.
1250     * See the properites section below for detailed information on what you can pass via the `options` object.
1251     * @method create
1252     * @param {} [options]
1253     * @return {composite} A new composite
1254     */
1255    Composite.create = function(options) {
1256        return Common.extend({ 
1257            id: Common.nextId(),
1258            type: 'composite',
1259            parent: null,
1260            isModified: false,
1261            bodies: [], 
1262            constraints: [], 
1263            composites: [],
1264            label: 'Composite',
1265            plugin: {}
1266        }, options);
1267    };
1268
1269    /**
1270     * Sets the composite's `isModified` flag. 
1271     * If `updateParents` is true, all parents will be set (default: false).
1272     * If `updateChildren` is true, all children will be set (default: false).
1273     * @method setModified
1274     * @param {composite} composite
1275     * @param {boolean} isModified
1276     * @param {boolean} [updateParents=false]
1277     * @param {boolean} [updateChildren=false]
1278     */
1279    Composite.setModified = function(composite, isModified, updateParents, updateChildren) {
1280        composite.isModified = isModified;
1281
1282        if (updateParents && composite.parent) {
1283            Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
1284        }
1285
1286        if (updateChildren) {
1287            for(var i = 0; i < composite.composites.length; i++) {
1288                var childComposite = composite.composites[i];
1289                Composite.setModified(childComposite, isModified, updateParents, updateChildren);
1290            }
1291        }
1292    };
1293
1294    /**
1295     * Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite.
1296     * Triggers `beforeAdd` and `afterAdd` events on the `composite`.
1297     * @method add
1298     * @param {composite} composite
1299     * @param {} object
1300     * @return {composite} The original composite with the objects added
1301     */
1302    Composite.add = function(composite, object) {
1303        var objects = [].concat(object);
1304
1305        Events.trigger(composite, 'beforeAdd', { object: object });
1306
1307        for (var i = 0; i < objects.length; i++) {
1308            var obj = objects[i];
1309
1310            switch (obj.type) {
1311
1312            case 'body':
1313                // skip adding compound parts
1314                if (obj.parent !== obj) {
1315                    Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)');
1316                    break;
1317                }
1318
1319                Composite.addBody(composite, obj);
1320                break;
1321            case 'constraint':
1322                Composite.addConstraint(composite, obj);
1323                break;
1324            case 'composite':
1325                Composite.addComposite(composite, obj);
1326                break;
1327            case 'mouseConstraint':
1328                Composite.addConstraint(composite, obj.constraint);
1329                break;
1330
1331            }
1332        }
1333
1334        Events.trigger(composite, 'afterAdd', { object: object });
1335
1336        return composite;
1337    };
1338
1339    /**
1340     * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite.
1341     * Optionally searching its children recursively.
1342     * Triggers `beforeRemove` and `afterRemove` events on the `composite`.
1343     * @method remove
1344     * @param {composite} composite
1345     * @param {} object
1346     * @param {boolean} [deep=false]
1347     * @return {composite} The original composite with the objects removed
1348     */
1349    Composite.remove = function(composite, object, deep) {
1350        var objects = [].concat(object);
1351
1352        Events.trigger(composite, 'beforeRemove', { object: object });
1353
1354        for (var i = 0; i < objects.length; i++) {
1355            var obj = objects[i];
1356
1357            switch (obj.type) {
1358
1359            case 'body':
1360                Composite.removeBody(composite, obj, deep);
1361                break;
1362            case 'constraint':
1363                Composite.removeConstraint(composite, obj, deep);
1364                break;
1365            case 'composite':
1366                Composite.removeComposite(composite, obj, deep);
1367                break;
1368            case 'mouseConstraint':
1369                Composite.removeConstraint(composite, obj.constraint);
1370                break;
1371
1372            }
1373        }
1374
1375        Events.trigger(composite, 'afterRemove', { object: object });
1376
1377        return composite;
1378    };
1379
1380    /**
1381     * Adds a composite to the given composite.
1382     * @private
1383     * @method addComposite
1384     * @param {composite} compositeA
1385     * @param {composite} compositeB
1386     * @return {composite} The original compositeA with the objects from compositeB added
1387     */
1388    Composite.addComposite = function(compositeA, compositeB) {
1389        compositeA.composites.push(compositeB);
1390        compositeB.parent = compositeA;
1391        Composite.setModified(compositeA, true, true, false);
1392        return compositeA;
1393    };
1394
1395    /**
1396     * Removes a composite from the given composite, and optionally searching its children recursively.
1397     * @private
1398     * @method removeComposite
1399     * @param {composite} compositeA
1400     * @param {composite} compositeB
1401     * @param {boolean} [deep=false]
1402     * @return {composite} The original compositeA with the composite removed
1403     */
1404    Composite.removeComposite = function(compositeA, compositeB, deep) {
1405        var position = Common.indexOf(compositeA.composites, compositeB);
1406        if (position !== -1) {
1407            Composite.removeCompositeAt(compositeA, position);
1408            Composite.setModified(compositeA, true, true, false);
1409        }
1410
1411        if (deep) {
1412            for (var i = 0; i < compositeA.composites.length; i++){
1413                Composite.removeComposite(compositeA.composites[i], compositeB, true);
1414            }
1415        }
1416
1417        return compositeA;
1418    };
1419
1420    /**
1421     * Removes a composite from the given composite.
1422     * @private
1423     * @method removeCompositeAt
1424     * @param {composite} composite
1425     * @param {number} position
1426     * @return {composite} The original composite with the composite removed
1427     */
1428    Composite.removeCompositeAt = function(composite, position) {
1429        composite.composites.splice(position, 1);
1430        Composite.setModified(composite, true, true, false);
1431        return composite;
1432    };
1433
1434    /**
1435     * Adds a body to the given composite.
1436     * @private
1437     * @method addBody
1438     * @param {composite} composite
1439     * @param {body} body
1440     * @return {composite} The original composite with the body added
1441     */
1442    Composite.addBody = function(composite, body) {
1443        composite.bodies.push(body);
1444        Composite.setModified(composite, true, true, false);
1445        return composite;
1446    };
1447
1448    /**
1449     * Removes a body from the given composite, and optionally searching its children recursively.
1450     * @private
1451     * @method removeBody
1452     * @param {composite} composite
1453     * @param {body} body
1454     * @param {boolean} [deep=false]
1455     * @return {composite} The original composite with the body removed
1456     */
1457    Composite.removeBody = function(composite, body, deep) {
1458        var position = Common.indexOf(composite.bodies, body);
1459        if (position !== -1) {
1460            Composite.removeBodyAt(composite, position);
1461            Composite.setModified(composite, true, true, false);
1462        }
1463
1464        if (deep) {
1465            for (var i = 0; i < composite.composites.length; i++){
1466                Composite.removeBody(composite.composites[i], body, true);
1467            }
1468        }
1469
1470        return composite;
1471    };
1472
1473    /**
1474     * Removes a body from the given composite.
1475     * @private
1476     * @method removeBodyAt
1477     * @param {composite} composite
1478     * @param {number} position
1479     * @return {composite} The original composite with the body removed
1480     */
1481    Composite.removeBodyAt = function(composite, position) {
1482        composite.bodies.splice(position, 1);
1483        Composite.setModified(composite, true, true, false);
1484        return composite;
1485    };
1486
1487    /**
1488     * Adds a constraint to the given composite.
1489     * @private
1490     * @method addConstraint
1491     * @param {composite} composite
1492     * @param {constraint} constraint
1493     * @return {composite} The original composite with the constraint added
1494     */
1495    Composite.addConstraint = function(composite, constraint) {
1496        composite.constraints.push(constraint);
1497        Composite.setModified(composite, true, true, false);
1498        return composite;
1499    };
1500
1501    /**
1502     * Removes a constraint from the given composite, and optionally searching its children recursively.
1503     * @private
1504     * @method removeConstraint
1505     * @param {composite} composite
1506     * @param {constraint} constraint
1507     * @param {boolean} [deep=false]
1508     * @return {composite} The original composite with the constraint removed
1509     */
1510    Composite.removeConstraint = function(composite, constraint, deep) {
1511        var position = Common.indexOf(composite.constraints, constraint);
1512        if (position !== -1) {
1513            Composite.removeConstraintAt(composite, position);
1514        }
1515
1516        if (deep) {
1517            for (var i = 0; i < composite.composites.length; i++){
1518                Composite.removeConstraint(composite.composites[i], constraint, true);
1519            }
1520        }
1521
1522        return composite;
1523    };
1524
1525    /**
1526     * Removes a body from the given composite.
1527     * @private
1528     * @method removeConstraintAt
1529     * @param {composite} composite
1530     * @param {number} position
1531     * @return {composite} The original composite with the constraint removed
1532     */
1533    Composite.removeConstraintAt = function(composite, position) {
1534        composite.constraints.splice(position, 1);
1535        Composite.setModified(composite, true, true, false);
1536        return composite;
1537    };
1538
1539    /**
1540     * Removes all bodies, constraints and composites from the given composite.
1541     * Optionally clearing its children recursively.
1542     * @method clear
1543     * @param {composite} composite
1544     * @param {boolean} keepStatic
1545     * @param {boolean} [deep=false]
1546     */
1547    Composite.clear = function(composite, keepStatic, deep) {
1548        if (deep) {
1549            for (var i = 0; i < composite.composites.length; i++){
1550                Composite.clear(composite.composites[i], keepStatic, true);
1551            }
1552        }
1553        
1554        if (keepStatic) {
1555            composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; });
1556        } else {
1557            composite.bodies.length = 0;
1558        }
1559
1560        composite.constraints.length = 0;
1561        composite.composites.length = 0;
1562        Composite.setModified(composite, true, true, false);
1563
1564        return composite;
1565    };
1566
1567    /**
1568     * Returns all bodies in the given composite, including all bodies in its children, recursively.
1569     * @method allBodies
1570     * @param {composite} composite
1571     * @return {body[]} All the bodies
1572     */
1573    Composite.allBodies = function(composite) {
1574        var bodies = [].concat(composite.bodies);
1575
1576        for (var i = 0; i < composite.composites.length; i++)
1577            bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
1578
1579        return bodies;
1580    };
1581
1582    /**
1583     * Returns all constraints in the given composite, including all constraints in its children, recursively.
1584     * @method allConstraints
1585     * @param {composite} composite
1586     * @return {constraint[]} All the constraints
1587     */
1588    Composite.allConstraints = function(composite) {
1589        var constraints = [].concat(composite.constraints);
1590
1591        for (var i = 0; i < composite.composites.length; i++)
1592            constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
1593
1594        return constraints;
1595    };
1596
1597    /**
1598     * Returns all composites in the given composite, including all composites in its children, recursively.
1599     * @method allComposites
1600     * @param {composite} composite
1601     * @return {composite[]} All the composites
1602     */
1603    Composite.allComposites = function(composite) {
1604        var composites = [].concat(composite.composites);
1605
1606        for (var i = 0; i < composite.composites.length; i++)
1607            composites = composites.concat(Composite.allComposites(composite.composites[i]));
1608
1609        return composites;
1610    };
1611
1612    /**
1613     * Searches the composite recursively for an object matching the type and id supplied, null if not found.
1614     * @method get
1615     * @param {composite} composite
1616     * @param {number} id
1617     * @param {string} type
1618     * @return {object} The requested object, if found
1619     */
1620    Composite.get = function(composite, id, type) {
1621        var objects,
1622            object;
1623
1624        switch (type) {
1625        case 'body':
1626            objects = Composite.allBodies(composite);
1627            break;
1628        case 'constraint':
1629            objects = Composite.allConstraints(composite);
1630            break;
1631        case 'composite':
1632            objects = Composite.allComposites(composite).concat(composite);
1633            break;
1634        }
1635
1636        if (!objects)
1637            return null;
1638
1639        object = objects.filter(function(object) { 
1640            return object.id.toString() === id.toString(); 
1641        });
1642
1643        return object.length === 0 ? null : object[0];
1644    };
1645
1646    /**
1647     * Moves the given object(s) from compositeA to compositeB (equal to a remove followed by an add).
1648     * @method move
1649     * @param {compositeA} compositeA
1650     * @param {object[]} objects
1651     * @param {compositeB} compositeB
1652     * @return {composite} Returns compositeA
1653     */
1654    Composite.move = function(compositeA, objects, compositeB) {
1655        Composite.remove(compositeA, objects);
1656        Composite.add(compositeB, objects);
1657        return compositeA;
1658    };
1659
1660    /**
1661     * Assigns new ids for all objects in the composite, recursively.
1662     * @method rebase
1663     * @param {composite} composite
1664     * @return {composite} Returns composite
1665     */
1666    Composite.rebase = function(composite) {
1667        var objects = Composite.allBodies(composite)
1668                        .concat(Composite.allConstraints(composite))
1669                        .concat(Composite.allComposites(composite));
1670
1671        for (var i = 0; i < objects.length; i++) {
1672            objects[i].id = Common.nextId();
1673        }
1674
1675        Composite.setModified(composite, true, true, false);
1676
1677        return composite;
1678    };
1679
1680    /**
1681     * Translates all children in the composite by 
1681a given vector relative to their current positions, 
1682     * without imparting any velocity.
1683     * @method translate
1684     * @param {composite} composite
1685     * @param {vector} translation
1686     * @param {bool} [recursive=true]
1687     */
1688    Composite.translate = function(composite, translation, recursive) {
1689        var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
1690
1691        for (var i = 0; i < bodies.length; i++) {
1692            Body.translate(bodies[i], translation);
1693        }
1694
1695        Composite.setModified(composite, true, true, false);
1696
1697        return composite;
1698    };
1699
1700    /**
1701     * Rotates all children in the composite by a given angle about the given point, without imparting any angular velocity.
1702     * @method rotate
1703     * @param {composite} composite
1704     * @param {number} rotation
1705     * @param {vector} point
1706     * @param {bool} [recursive=true]
1707     */
1708    Composite.rotate = function(composite, rotation, point, recursive) {
1709        var cos = Math.cos(rotation),
1710            sin = Math.sin(rotation),
1711            bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
1712
1713        for (var i = 0; i < bodies.length; i++) {
1714            var body = bodies[i],
1715                dx = body.position.x - point.x,
1716                dy = body.position.y - point.y;
1717                
1718            Body.setPosition(body, {
1719                x: point.x + (dx * cos - dy * sin),
1720                y: point.y + (dx * sin + dy * cos)
1721            });
1722
1723            Body.rotate(body, rotation);
1724        }
1725
1726        Composite.setModified(composite, true, true, false);
1727
1728        return composite;
1729    };
1730
1731    /**
1732     * Scales all children in the composite, including updating physical properties (mass, area, axes, inertia), from a world-space point.
1733     * @method scale
1734     * @param {composite} composite
1735     * @param {number} scaleX
1736     * @param {number} scaleY
1737     * @param {vector} point
1738     * @param {bool} [recursive=true]
1739     */
1740    Composite.scale = function(composite, scaleX, scaleY, point, recursive) {
1741        var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
1742
1743        for (var i = 0; i < bodies.length; i++) {
1744            var body = bodies[i],
1745                dx = body.position.x - point.x,
1746                dy = body.position.y - point.y;
1747                
1748            Body.setPosition(body, {
1749                x: point.x + dx * scaleX,
1750                y: point.y + dy * scaleY
1751            });
1752
1753            Body.scale(body, scaleX, scaleY);
1754        }
1755
1756        Composite.setModified(composite, true, true, false);
1757
1758        return composite;
1759    };
1760
1761    /**
1762     * Returns the union of the bounds of all of the composite's bodies.
1763     * @method bounds
1764     * @param {composite} composite The composite.
1765     * @returns {bounds} The composite bounds.
1766     */
1767    Composite.bounds = function(composite) {
1768        var bodies = Composite.allBodies(composite),
1769            vertices = [];
1770
1771        for (var i = 0; i < bodies.length; i += 1) {
1772            var body = bodies[i];
1773            vertices.push(body.bounds.min, body.bounds.max);
1774        }
1775
1776        return Bounds.create(vertices);
1777    };
1778
1779    /*
1780    *
1781    *  Events Documentation
1782    *
1783    */
1784
1785    /**
1786    * Fired when a call to `Composite.add` is made, before objects have been added.
1787    *
1788    * @event beforeAdd
1789    * @param {} event An event object
1790    * @param {} event.object The object(s) to be added (may be a single body, constraint, composite or a mixed array of these)
1791    * @param {} event.source The source object of the event
1792    * @param {} event.name The name of the event
1793    */
1794
1795    /**
1796    * Fired when a call to `Composite.add` is made, after objects have been added.
1797    *
1798    * @event afterAdd
1799    * @param {} event An event object
1800    * @param {} event.object The object(s) that have been added (may be a single body, constraint, composite or a mixed array of these)
1801    * @param {} event.source The source object of the event
1802    * @param {} event.name The name of the event
1803    */
1804
1805    /**
1806    * Fired when a call to `Composite.remove` is made, before objects have been removed.
1807    *
1808    * @event beforeRemove
1809    * @param {} event An event object
1810    * @param {} event.object The object(s) to be removed (may be a single body, constraint, composite or a mixed array of these)
1811    * @param {} event.source The source object of the event
1812    * @param {} event.name The name of the event
1813    */
1814
1815    /**
1816    * Fired when a call to `Composite.remove` is made, after objects have been removed.
1817    *
1818    * @event afterRemove
1819    * @param {} event An event object
1820    * @param {} event.object The object(s) that have been removed (may be a single body, constraint, composite or a mixed array of these)
1821    * @param {} event.source The source object of the event
1822    * @param {} event.name The name of the event
1823    */
1824
1825    /*
1826    *
1827    *  Properties Documentation
1828    *
1829    */
1830
1831    /**
1832     * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
1833     *
1834     * @property id
1835     * @type number
1836     */
1837
1838    /**
1839     * A `String` denoting the type of object.
1840     *
1841     * @property type
1842     * @type string
1843     * @default "composite"
1844     * @readOnly
1845     */
1846
1847    /**
1848     * An arbitrary `String` name to help the user identify and manage composites.
1849     *
1850     * @property label
1851     * @type string
1852     * @default "Composite"
1853     */
1854
1855    /**
1856     * A flag that specifies whether the composite has been modified during the current step.
1857     * Most `Matter.Composite` methods will automatically set this flag to `true` to inform the engine of changes to be handled.
1858     * If you need to change it manually, you should use the `Composite.setModified` method.
1859     *
1860     * @property isModified
1861     * @type boolean
1862     * @default false
1863     */
1864
1865    /**
1866     * The `Composite` that is the parent of this composite. It is automatically managed by the `Matter.Composite` methods.
1867     *
1868     * @property parent
1869     * @type composite
1870     * @default null
1871     */
1872
1873    /**
1874     * An array of `Body` that are _direct_ children of this composite.
1875     * To add or remove bodies you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
1876     * If you wish to recursively find all descendants, you should use the `Composite.allBodies` method.
1877     *
1878     * @property bodies
1879     * @type body[]
1880     * @default []
1881     */
1882
1883    /**
1884     * An array of `Constraint` that are _direct_ children of this composite.
1885     * To add or remove constraints you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
1886     * If you wish to recursively find all descendants, you should use the `Composite.allConstraints` method.
1887     *
1888     * @property constraints
1889     * @type constraint[]
1890     * @default []
1891     */
1892
1893    /**
1894     * An array of `Composite` that are _direct_ children of this composite.
1895     * To add or remove composites you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
1896     * If you wish to recursively find all descendants, you should use the `Composite.allComposites` method.
1897     *
1898     * @property composites
1899     * @type composite[]
1900     * @default []
1901     */
1902
1903    /**
1904     * An object reserved for storing plugin-specific properties.
1905     *
1906     * @property plugin
1907     * @type {}
1908     */
1909
1910})();
1911
1912},{"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"./Body":1}],3:[function(_dereq_,module,exports){
1913/**
1914* The `Matter.World` module contains methods for creating and manipulating the world composite.
1915* A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`.
1916* A `Matter.World` has a few additional properties including `gravity` and `bounds`.
1917* It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties.
1918* There are also a few methods here that alias those in `Matter.Composite` for easier readability.
1919*
1920* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
1921*
1922* @class World
1923* @extends Composite
1924*/
1925
1926var World = {};
1927
1928module.exports = World;
1929
1930var Composite = _dereq_('./Composite');
1931var Constraint = _dereq_('../constraint/Constraint');
1932var Common = _dereq_('../core/Common');
1933
1934(function() {
1935
1936    /**
1937     * Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults.
1938     * See the properties section below for detailed information on what you can pass via the `options` object.
1939     * @method create
1940     * @constructor
1941     * @param {} options
1942     * @return {world}
1942 A new world
1943     */
1944    World.create = function(options) {
1945        var composite = Composite.create();
1946
1947        var defaults = {
1948            label: 'World',
1949            gravity: {
1950                x: 0,
1951                y: 1,
1952                scale: 0.001
1953            },
1954            bounds: { 
1955                min: { x: -Infinity, y: -Infinity }, 
1956                max: { x: Infinity, y: Infinity } 
1957            }
1958        };
1959        
1960        return Common.extend(composite, defaults, options);
1961    };
1962
1963    /*
1964    *
1965    *  Properties Documentation
1966    *
1967    */
1968
1969    /**
1970     * The gravity to apply on the world.
1971     *
1972     * @property gravity
1973     * @type object
1974     */
1975
1976    /**
1977     * The gravity x component.
1978     *
1979     * @property gravity.x
1980     * @type object
1981     * @default 0
1982     */
1983
1984    /**
1985     * The gravity y component.
1986     *
1987     * @property gravity.y
1988     * @type object
1989     * @default 1
1990     */
1991
1992    /**
1993     * The gravity scale factor.
1994     *
1995     * @property gravity.scale
1996     * @type object
1997     * @default 0.001
1998     */
1999
2000    /**
2001     * A `Bounds` object that defines the world bounds for collision detection.
2002     *
2003     * @property bounds
2004     * @type bounds
2005     * @default { min: { x: -Infinity, y: -Infinity }, max: { x: Infinity, y: Infinity } }
2006     */
2007
2008    // World is a Composite body
2009    // see src/module/Outro.js for these aliases:
2010    
2011    /**
2012     * An alias for Composite.add
2013     * @method add
2014     * @param {world} world
2015     * @param {} object
2016     * @return {composite} The original world with the objects added
2017     */
2018
2019    /**
2020     * An alias for Composite.remove
2021     * @method remove
2022     * @param {world} world
2023     * @param {} object
2024     * @param {boolean} [deep=false]
2025     * @return {composite} The original world with the objects removed
2026     */
2027
2028    /**
2029     * An alias for Composite.clear
2030     * @method clear
2031     * @param {world} world
2032     * @param {boolean} keepStatic
2033     */
2034
2035    /**
2036     * An alias for Composite.addComposite
2037     * @method addComposite
2038     * @param {world} world
2039     * @param {composite} composite
2040     * @return {world} The original world with the objects from composite added
2041     */
2042    
2043     /**
2044      * An alias for Composite.addBody
2045      * @method addBody
2046      * @param {world} world
2047      * @param {body} body
2048      * @return {world} The original world with the body added
2049      */
2050
2051     /**
2052      * An alias for Composite.addConstraint
2053      * @method addConstraint
2054      * @param {world} world
2055      * @param {constraint} constraint
2056      * @return {world} The original world with the constraint added
2057      */
2058
2059})();
2060
2061},{"../constraint/Constraint":12,"../core/Common":14,"./Composite":2}],4:[function(_dereq_,module,exports){
2062/**
2063* The `Matter.Contact` module contains methods for creating and manipulating collision contacts.
2064*
2065* @class Contact
2066*/
2067
2068var Contact = {};
2069
2070module.exports = Contact;
2071
2072(function() {
2073
2074    /**
2075     * Creates a new contact.
2076     * @method create
2077     * @param {vertex} vertex
2078     * @return {contact} A new contact
2079     */
2080    Contact.create = function(vertex) {
2081        return {
2082            id: Contact.id(vertex),
2083            vertex: vertex,
2084            normalImpulse: 0,
2085            tangentImpulse: 0
2086        };
2087    };
2088    
2089    /**
2090     * Generates a contact id.
2091     * @method id
2092     * @param {vertex} vertex
2093     * @return {string} Unique contactID
2094     */
2095    Contact.id = function(vertex) {
2096        return vertex.body.id + '_' + vertex.index;
2097    };
2098
2099})();
2100
2101},{}],5:[function(_dereq_,module,exports){
2102/**
2103* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
2104*
2105* @class Detector
2106*/
2107
2108// TODO: speculative contacts
2109
2110var Detector = {};
2111
2112module.exports = Detector;
2113
2114var SAT = _dereq_('./SAT');
2115var Pair = _dereq_('./Pair');
2116var Bounds = _dereq_('../geometry/Bounds');
2117
2118(function() {
2119
2120    /**
2121     * Finds all collisions given a list of pairs.
2122     * @method collisions
2123     * @param {pair[]} broadphasePairs
2124     * @param {engine} engine
2125     * @return {array} collisions
2126     */
2127    Detector.collisions = function(broadphasePairs, engine) {
2128        var collisions = [],
2129            pairsTable = engine.pairs.table;
2130
2131        
2132        for (var i = 0; i < broadphasePairs.length; i++) {
2133            var bodyA = broadphasePairs[i][0], 
2134                bodyB = broadphasePairs[i][1];
2135
2136            if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
2137                continue;
2138            
2139            if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
2140                continue;
2141
2142
2143            // mid phase
2144            if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
2145                for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
2146                    var partA = bodyA.parts[j];
2147
2148                    for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
2149                        var partB = bodyB.parts[k];
2150
2151                        if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
2152                            // find a previous collision we could reuse
2153                            var pairId = Pair.id(partA, partB),
2154                                pair = pairsTable[pairId],
2155                                previousCollision;
2156
2157                            if (pair && pair.isActive) {
2158                                previousCollision = pair.collision;
2159                            } else {
2160                                previousCollision = null;
2161                            }
2162
2163                            // narrow phase
2164                            var collision = SAT.collides(partA, partB, previousCollision);
2165
2166
2167                            if (collision.collided) {
2168                                collisions.push(collision);
2169                            }
2170                        }
2171                    }
2172                }
2173            }
2174        }
2175
2176        return collisions;
2177    };
2178
2179    /**
2180     * Returns `true` if both supplied collision filters will allow a collision to occur.
2181     * See `body.collisionFilter` for more information.
2182     * @method canCollide
2183     * @param {} filterA
2184     * @param {} filterB
2185     * @return {bool} `true` if collision can occur
2186     */
2187    Detector.canCollide = function(filterA, filterB) {
2188        if (filterA.group === filterB.group && filterA.group !== 0)
2189            return filterA.group > 0;
2190
2191        return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
2192    };
2193
2194})();
2195
2196},{"../geometry/Bounds":26,"./Pair":7,"./SAT":11}],6:[function(_dereq_,module,exports){
2197/**
2198* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
2199*
2200* @class Grid
2201*/
2202
2203var Grid = {};
2204
2205module.exports = Grid;
2206
2207var Pair = _dereq_('./Pair');
2208var Detector = _dereq_('./Detector');
2209var Common = _dereq_('../core/Common');
2210
2211(function() {
2212
2213    /**
2214     * Creates a new grid.
2215     * @method create
2216     * @param {} options
2217     * @return {grid} A new grid
2218     */
2219    Grid.create = function(options) {
2220        var defaults = {
2221            controller: Grid,
2222            detector: Detector.collisions,
2223            buckets: {},
2224            pairs: {},
2225            pairsList: [],
2226            bucketWidth: 48,
2227            bucketHeight: 48
2228        };
2229
2230        return Common.extend(defaults, options);
2231    };
2232
2233    /**
2234     * The width of a single grid bucket.
2235     *
2236     * @property bucketWidth
2237     * @type number
2238     * @default 48
2239     */
2240
2241    /**
2242     * The height of a single grid bucket.
2243     *
2244     * @property bucketHeight
2245     * @type number
2246     * @default 48
2247     */
2248
2249    /**
2250     * Updates the grid.
2251     * @method update
2252     * @param {grid} grid
2253     * @param {body[]} bodies
2254     * @param {engine} engine
2255     * @param {boolean} forceUpdate
2256     */
2257    Grid.update = function(grid, bodies, engine, forceUpdate) {
2258        var i, col, row,
2259            world = engine.world,
2260            buckets = grid.buckets,
2261            bucket,
2262            bucketId,
2263            gridChanged = false;
2264
2265
2266        for (i = 0; i < bodies.length; i++) {
2267            var body = bodies[i];
2268
2269            if (body.isSleeping && !forceUpdate)
2270                continue;
2271
2272            // don't update out of world bodies
2273            if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
2274                || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)
2275                continue;
2276
2277            var newRegion = Grid._getRegion(grid, body);
2278
2279            // if the body has changed grid region
2280            if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
2281
2282
vendor: 4,380 bytes, lines 2283-2410
2283                if (!body.region || forceUpdate)
2284                    body.region = newRegion;
2285
2286                var union = Grid._regionUnion(newRegion, body.region);
2287
2288                // update grid buckets affected by region change
2289                // iterate over the union of both regions
2290                for (col = union.startCol; col <= union.endCol; col++) {
2291                    for (row = union.startRow; row <= union.endRow; row++) {
2292                        bucketId = Grid._getBucketId(col, row);
2293                        bucket = buckets[bucketId];
2294
2295                        var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol
2296                                                && row >= newRegion.startRow && row <= newRegion.endRow);
2297
2298                        var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol
2299                                                && row >= body.region.startRow && row <= body.region.endRow);
2300
2301                        // remove from old region buckets
2302                        if (!isInsideNewRegion && isInsideOldRegion) {
2303                            if (isInsideOldRegion) {
2304                                if (bucket)
2305                                    Grid._bucketRemoveBody(grid, bucket, body);
2306                            }
2307                        }
2308
2309                        // add to new region buckets
2310                        if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) {
2311                            if (!bucket)
2312                                bucket = Grid._createBucket(buckets, bucketId);
2313                            Grid._bucketAddBody(grid, bucket, body);
2314                        }
2315                    }
2316                }
2317
2318                // set the new region
2319                body.region = newRegion;
2320
2321                // flag changes so we can update pairs
2322                gridChanged = true;
2323            }
2324        }
2325
2326        // update pairs list only if pairs changed (i.e. a body changed region)
2327        if (gridChanged)
2328            grid.pairsList = Grid._createActivePairsList(grid);
2329    };
2330
2331    /**
2332     * Clears the grid.
2333     * @method clear
2334     * @param {grid} grid
2335     */
2336    Grid.clear = function(grid) {
2337        grid.buckets = {};
2338        grid.pairs = {};
2339        grid.pairsList = [];
2340    };
2341
2342    /**
2343     * Finds the union of two regions.
2344     * @method _regionUnion
2345     * @private
2346     * @param {} regionA
2347     * @param {} regionB
2348     * @return {} region
2349     */
2350    Grid._regionUnion = function(regionA, regionB) {
2351        var startCol = Math.min(regionA.startCol, regionB.startCol),
2352            endCol = Math.max(regionA.endCol, regionB.endCol),
2353            startRow = Math.min(regionA.startRow, regionB.startRow),
2354            endRow = Math.max(regionA.endRow, regionB.endRow);
2355
2356        return Grid._createRegion(startCol, endCol, startRow, endRow);
2357    };
2358
2359    /**
2360     * Gets the region a given body falls in for a given grid.
2361     * @method _getRegion
2362     * @private
2363     * @param {} grid
2364     * @param {} body
2365     * @return {} region
2366     */
2367    Grid._getRegion = function(grid, body) {
2368        var bounds = body.bounds,
2369            startCol = Math.floor(bounds.min.x / grid.bucketWidth),
2370            endCol = Math.floor(bounds.max.x / grid.bucketWidth),
2371            startRow = Math.floor(bounds.min.y / grid.bucketHeight),
2372            endRow = Math.floor(bounds.max.y / grid.bucketHeight);
2373
2374        return Grid._createRegion(startCol, endCol, startRow, endRow);
2375    };
2376
2377    /**
2378     * Creates a region.
2379     * @method _createRegion
2380     * @private
2381     * @param {} startCol
2382     * @param {} endCol
2383     * @param {} startRow
2384     * @param {} endRow
2385     * @return {} region
2386     */
2387    Grid._createRegion = function(startCol, endCol, startRow, endRow) {
2388        return { 
2389            id: startCol + ',' + endCol + ',' + startRow + ',' + endRow,
2390            startCol: startCol, 
2391            endCol: endCol, 
2392            startRow: startRow, 
2393            endRow: endRow 
2394        };
2395    };
2396
2397    /**
2398     * Gets the bucket id at the given position.
2399     * @method _getBucketId
2400     * @private
2401     * @param {} column
2402     * @param {} row
2403     * @return {string} bucket id
2404     */
2405    Grid._getBucketId = function(column, row) {
2406        return 'C' + column + 'R' + row;
2407    };
2408
2409    /**
2410     * Creates a bucket.
2411     * @method _createBucket
2412     * @private
2413     * @param {} buckets
2414     * @param {} bucketId
2415     * @return {} bucket
2416     */
2417    Grid._createBucket = function(buckets, bucketId) {
2418        var bucket = buckets[bucketId] = [];
2419        return bucket;
2420    };
2421
2422    /**
2423     * Adds a body to a bucket.
2424     * @method _bucketAddBody
2425     * @private
2426     * @param {} grid
2427     * @param {} bucket
2428     * @param {} body
2429     */
2430    Grid._bucketAddBody = function(grid, bucket, body) {
2431        // add new pairs
2432        for (var i = 0; i < bucket.length; i++) {
2433            var bodyB = bucket[i];
2434
2435            if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic))
2436                continue;
2437
2438            // keep track of the number of buckets the pair exists in
2439            // important for Grid.update to work
2440            var pairId = Pair.id(body, bodyB),
2441                pair = grid.pairs[pairId];
2442
2443            if (pair) {
2444                pair[2] += 1;
2445            } else {
2446                grid.pairs[pairId] = [body, bodyB, 1];
2447            }
2448        }
2449
2450        // add to bodies (after pairs, otherwise pairs with self)
2451        bucket.push(body);
2452    };
2453
2454    /**
2455     * Removes a body from a bucket.
2456     * @method _bucketRemoveBody
2457     * @private
2458     * @param {} grid
2459     * @param {} bucket
2460     * @param {} body
2461     */
2462    Grid._bucketRemoveBody = function(grid, bucket, body) {
2463        // remove from bucket
2464        bucket.splice(Common.indexOf(bucket, body), 1);
2465
2466        // update pair counts
2467        for (var i = 0; i < bucket.length; i++) {
2468            // keep track of the number of buckets the pair exists in
2469            // important for _createActivePairsList to work
2470            var bodyB = bucket[i],
2471                pairId = Pair.id(body, bodyB),
2472                pair = grid.pairs[pairId];
2473
2474            if (pair)
2475                pair[2] -= 1;
2476        }
2477    };
2478
2479    /**
2480     * Generates a list of the active pairs in the grid.
2481     * @method _createActivePairsList
2482     * @private
2483     * @param {} grid
2484     * @return [] pairs
2485     */
2486    Grid._createActivePairsList = function(grid) {
2487        var pairKeys,
2488            pair,
2489            pairs = [];
2490
2491        // grid.pairs is used as a hashmap
2492        pairKeys = Common.keys(grid.pairs);
2493
2494        // iterate over grid.pairs
2495        for (var k = 0; k < pairKeys.length; k++) {
2496            pair = grid.pairs[pairKeys[k]];
2497
2498            // if pair exists in at least one bucket
2499            // it is a pair that needs further collision testing so push it
2500            if (pair[2] > 0) {
2501                pairs.push(pair);
2502            } else {
2503                delete grid.pairs[pairKeys[k]];
2504            }
2505        }
2506
2507        return pairs;
2508    };
2509    
2510})();
2511
2512},{"../core/Common":14,"./Detector":5,"./Pair":7}],7:[function(_dereq_,module,exports){
2513/**
2514* The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
2515*
2516* @class Pair
2517*/
2518
2519var Pair = {};
2520
2521module.exports = Pair;
2522
2523var Contact = _dereq_('./Contact');
2524
2525(function() {
2526    
2527    /**
2528     * Creates a pair.
2529     * @method create
2530     * @param {collision} collision
2531     * @param {number} timestamp
2532     * @return {pair} A new pair
2533     */
2534    Pair.create = function(collision, timestamp) {
2535        var bodyA = collision.bodyA,
2536            bodyB = collision.bodyB,
2537            parentA = collision.parentA,
2538            parentB = collision.parentB;
2539
2540        var pair = {
2541            id: Pair.id(bodyA, bodyB),
2542            bodyA: bodyA,
2543            bodyB: bodyB,
2544            contacts: {},
2545            activeContacts: [],
2546            separation: 0,
2547            isActive: true,
2548            isSensor: bodyA.isSensor || bodyB.isSensor,
2549            timeCreated: timestamp,
2550            timeUpdated: timestamp,
2551            inverseMass: parentA.inverseMass + parentB.inverseMass,
2552            friction: Math.min(parentA.friction, parentB.friction),
2553            frictionStatic: Math.max(parentA.frictionStatic, parentB.frictionStatic),
2554            restitution: Math.max(parentA.restitution, parentB.restitution),
2555            slop: Math.max(parentA.slop, parentB.slop)
2556        };
2557
2558        Pair.update(pair, collision, timestamp);
2559
2560        return pair;
2561    };
2562
2563    /**
2564     * Updates a pair given a collision.
2565     * @method update
2566     * @param {pair} pair
2567     * @param {collision} collision
2568     * @param {number} timestamp
2569     */
2570    Pair.update = function(pair, collision, timestamp) {
2571        var contacts = pair.contacts,
2572            supports = collision.supports,
2573            activeContacts = pair.activeContacts,
2574            parentA = collision.parentA,
2575            parentB = collision.parentB;
2576        
2577        pair.collision = collision;
2578        pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
2579        pair.friction = Math.min(parentA.friction, parentB.friction);
2580        pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic);
2581        pair.restitution = Math.max(parentA.restitution, parentB.restitution);
2582        pair.slop = Math.max(parentA.slop, parentB.slop);
2583        activeContacts.length = 0;
2584        
2585        if (collision.collided) {
2586            for (var i = 0; i < supports.length; i++) {
2587                var support = supports[i],
2588                    contactId = Contact.id(support),
2589                    contact = contacts[contactId];
2590
2591                if (contact) {
2592                    activeContacts.push(contact);
2593                } else {
2594                    activeContacts.push(contacts[contactId] = Contact.create(support));
2595                }
2596            }
2597
2598            pair.separation = collision.depth;
2599            Pair.setActive(pair, true, timestamp);
2600        } else {
2601            if (pair.isActive === true)
2602                Pair.setActive(pair, false, timestamp);
2603        }
2604    };
2605    
2606    /**
2607     * Set a pair as active or inactive.
2608     * @method setActive
2609     * @param {pair} pair
2610     * @param {bool} isActive
2611     * @param {number} timestamp
2612     */
2613    Pair.setActive = function(pair, isActive, timestamp) {
2614        if (isActive) {
2615            pair.isActive = true;
2616            pair.timeUpdated = timestamp;
2617        } else {
2618            pair.isActive = false;
2619            pair.activeContacts.length = 0;
2620        }
2621    };
2622
2623    /**
2624     * Get the id for the given pair.
2625     * @method id
2626     * @param {body} bodyA
2627     * @param {body} bodyB
2628     * @return {string} Unique pairId
2629     */
2630    Pair.id = function(bodyA, bodyB) {
2631        if (bodyA.id < bodyB.id) {
2632            return 'A' + bodyA.id + 'B' + bodyB.id;
2633        } else {
2634            return 'A' + bodyB.id + 'B' + bodyA.id;
2635        }
2636    };
2637
2638})();
2639
2640},{"./Contact":4}],8:[function(_dereq_,module,exports){
2641/**
2642* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
2643*
2644* @class Pairs
2645*/
2646
2647var Pairs = {};
2648
2649module.exports = Pairs;
2650
2651var Pair = _dereq_('./Pair');
2652var Common = _dereq_('../core/Common');
2653
2654(function() {
2655    
2656    Pairs._pairMaxIdleLife = 1000;
2657
2658    /**
2659     * Creates a new pairs structure.
2660     * @method create
2661     * @param {object} options
2662     * @return {pairs} A new pairs structure
2663     */
2664    Pairs.create = function(options) {
2665        return Common.extend({ 
2666            table: {},
2667            list: [],
2668            collisionStart: [],
2669            collisionActive: [],
2670            collisionEnd: []
2671        }, options);
2672    };
2673
2674    /**
2675     * Updates pairs given a list of collisions.
2676     * @method update
2677     * @param {object} pairs
2678     * @param {collision[]} collisions
2679     * @param {number} timestamp
2680     */
2681    Pairs.update = function(pairs, collisions, timestamp) {
2682        var pairsList = pairs.list,
2683            pairsTable = pairs.table,
2684            collisionStart = pairs.collisionStart,
2685            collisionEnd = pairs.collisionEnd,
2686            collisionActive = pairs.collisionActive,
2687            activePairIds = [],
2688            collision,
2689            pairId,
2690            pair,
2691            i;
2692
2693        // clear collision state arrays, but maintain old reference
2694        collisionStart.length = 0;
2695        collisionEnd.length = 0;
2696        collisionActive.length = 0;
2697
2698        for (i = 0; i < collisions.length; i++) {
2699            collision = collisions[i];
2700
2701            if (collision.collided) {
2702                pairId = Pair.id(collision.bodyA, collision.bodyB);
2703                activePairIds.push(pairId);
2704
2705                pair = pairsTable[pairId];
2706                
2707                if (pair) {
2708                    // pair already exists (but may or may not be active)
2709                    if (pair.isActive) {
2710                        // pair exists and is active
2711                        collisionActive.push(pair);
2712                    } else {
2713                        // pair exists but was inactive, so a collision has just started again
2714                        collisionStart.push(pair);
2715                    }
2716
2717                    // update the pair
2718                    Pair.update(pair, collision, timestamp);
2719                } else {
2720                    // pair did not exist, create a new pair
2721                    pair = Pair.create(collision, timestamp);
2722                    pairsTable[pairId] = pair;
2723
2724                    // push the new pair
2725                    collisionStart.push(pair);
2726                    pairsList.push(pair);
2727                }
2728            }
2729        }
2730
2731        // deactivate previously active pairs that are now inactive
2732        for (i = 0; i < pairsList.length; i++) {
2733            pair = pairsList[i];
2734            if (pair.isActive && Common.indexOf(activePairIds, pair.id) === -1) {
2735                Pair.setActive(pair, false, timestamp);
2736                collisionEnd.push(pair);
2737            }
2738        }
2739    };
2740    
2741    /**
2742     * Finds and removes pairs that have been inactive for a set amount of time.
2743     * @method removeOld
2744     * @param {object} pairs
2745     * @param {number} timestamp
2746     */
2747    Pairs.removeOld = function(pairs, timestamp) {
2748        var pairsList = pairs.list,
2749            pairsTable = pairs.table,
2750            indexesToRemove = [],
2751            pair,
2752            collision,
2753            pairIndex,
2754            i;
2755
2756        for (i = 0; i < pairsList.length; i++) {
2757            pair = pairsList[i];
2758            collision = pair.collision;
2759            
2760            // never remove sleeping pairs
2761            if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
2762                pair.timeUpdated = timestamp;
2763                continue;
2764            }
2765
2766            // if pair is inactive for too long, mark it to be removed
2767            if (timestamp - pair.timeUpdated > Pairs._pairMaxIdleLife) {
2768                indexesToRemove.push(i);
2769            }
2770        }
2771
2772        // remove marked pairs
2773        for (i = 0; i < indexesToRemove.length; i++) {
2774            pairIndex = indexesToRemove[i] - i;
2775            pair = pairsList[pairIndex];
2776            delete pairsTable[pair.id];
2777            pairsList.splice(pairIndex, 1);
2778        }
2779    };
2780
2781    /**
2782     * Clears the given pairs structure.
2783     * @method clear
2784     * @param {pairs} pairs
2785     * @return {pairs} pairs
2786     */
2787    Pairs.clear = function(pairs) {
2788        pairs.table = {};
2789        pairs.list.length = 0;
2790        pairs.collisionStart.length = 0;
2791        pairs.collisionActive.length = 0;
2792        pairs.collisionEnd.length = 0;
2793        return pairs;
2794    };
2795
2796})();
2797
2798},{"../core/Common":14,"./Pair":7}],9:[function(_dereq_,module,exports){
2799/**
2800* The `Matter.Query` module contains methods for performing collision queries.
2801*
2802* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
2803*
2804* @class Query
2805*/
2806
2807var Query = {};
2808
2809module.exports = Query;
2810
2811var Vector = _dereq_('../geometry/Vector');
2812var SAT = _dereq_('./SAT');
2813var Bounds = _dereq_('../geometry/Bounds');
2814var Bodies = _dereq_('../factory/Bodies');
2815var Vertices = _dereq_('../geometry/Vertices');
2816
2817(function() {
2818
2819    /**
2820     * Returns a list of collisions between `body` and `bodies`.
2821     * @method collides
2822     * @param {body} body
2823     * @param {body[]} bodies
2824     * @return {object[]} Collisions
2825     */
2826    Query.collides = function(body, bodies) {
2827        var collisions = [];
2828
2829        for (var i = 0; i < bodies.length; i++) {
2830            var bodyA = bodies[i];
2831            
2832            if (Bounds.overlaps(bodyA.bounds, body.bounds)) {
2833                for (var j = bodyA.parts.length === 1 ? 0 : 1; j < bodyA.parts.length; j++) {
2834                    var part = bodyA.parts[j];
2835
2836                    if (Bounds.overlaps(part.bounds, body.bounds)) {
2837                        var collision = SAT.collides(part, body);
2838
2839                        if (collision.collided) {
2840                            collisions.push(collision);
2841                            break;
2842                        }
2843                    }
2844                }
2845            }
2846        }
2847
2848        return collisions;
2849    };
2850
2851    /**
2852     * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided.
2853     * @method ray
2854     * @param {body[]} bodies
2855     * @param {vector} startPoint
2856     * @param {vector} endPoint
2857     * @param {number} [rayWidth]
2858     * @return {object[]} Collisions
2859     */
2860    Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
2861        rayWidth = rayWidth || 1e-100;
2862
2863        var rayAngle = Vector.angle(startPoint, endPoint),
2864            rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)),
2865            rayX = (endPoint.x + startPoint.x) * 0.5,
2866            rayY = (endPoint.y + startPoint.y) * 0.5,
2867            ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }),
2868            collisions = Query.collides(ray, bodies);
2869
2870        for (var i = 0; i < collisions.length; i += 1) {
2871            var collision = collisions[i];
2872            collision.body = collision.bodyB = collision.bodyA;            
2873        }
2874
2875        return collisions;
2876    };
2877
2878    /**
2879     * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies.
2880     * @method region
2881     * @param {body[]} bodies
2882     * @param {bounds} bounds
2883     * @param {bool} [outside=false]
2884     * @return {body[]} The bodies matching the query
2885     */
2886    Query.region = function(bodies, bounds, outside) {
2887        var result = [];
2888
2889        for (var i = 0; i < bodies.length; i++) {
2890            var body = bodies[i],
2891                overlaps = Bounds.overlaps(body.bounds, bounds);
2892            if ((overlaps && !outside) || (!overlaps && outside))
2893                result.push(body);
2894        }
2895
2896        return result;
2897    };
2898
2899    /**
2900     * Returns all bodies whose vertices contain the given point, from the given set of bodies.
2901     * @method point
2902     * @param {body[]} bodies
2903     * @param {vector} point
2904     * @return {body[]} The bodies matching the query
2905     */
2906    Query.point = function(bodies, point) {
2907        var result = [];
2908
2909        for (var i = 0; i < bodies.length; i++) {
2910            var body = bodies[i];
2911            
2912            if (Bounds.contains(body.bounds, point)) {
2913                for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
2914                    var part = body.parts[j];
2915
2916                    if (Bounds.contains(part.bounds, point)
2917                        && Vertices.contains(part.vertices, point)) {
2918                        result.push(body);
2919                        break;
2920                    }
2921                }
2922            }
2923        }
2924
2925        return result;
2926    };
2927
2928})();
2929
2930},{"../factory/Bodies":23,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"./SAT":11}],10:[function(_dereq_,module,exports){
2931/**
2932* The `Matter.Resolver` module contains methods for resolving collision pairs.
2933*
2934* @class Resolver
2935*/
2936
2937var Resolver = {};
2938
2939module.exports = Resolver;
2940
2941var Vertices = _dereq_('../geometry/Vertices');
2942var Vector = _dereq_('../geometry/Vector');
2943var Common = _dereq_('../core/Common');
2944var Bounds = _dereq_('../geometry/Bounds');
2945
2946(function() {
2947
2948    Resolver._restingThresh = 4;
2949    Resolver._restingThreshTangent = 6;
2950    Resolver._positionDampen = 0.9;
2951    Resolver._positionWarming = 0.8;
2952    Resolver._frictionNormalMultiplier = 5;
2953
2954    /**
2955     * Prepare pairs for position solving.
2956     * @method preSolvePosition
2957     * @param {pair[]} pairs
2958     */
2959    Resolver.preSolvePosition = function(pairs) {
2960        var i,
2961            pair,
2962            activeCount;
2963
2964        // find total contacts on each body
2965        for (i = 0; i < pairs.length; i++) {
2966            pair = pairs[i];
2967            
2968            if (!pair.isActive)
2969                continue;
2970            
2971            activeCount = pair.activeContacts.length;
2972            pair.collision.parentA.totalContacts += activeCount;
2973            pair.collision.parentB.totalContacts += activeCount;
2974        }
2975    };
2976
2977    /**
2978     * Find a solution for pair positions.
2979     * @method solvePosition
2980     * @param {pair[]} pairs
2981     * @param {number} timeScale
2982     */
2983    Resolver.solvePosition = function(pairs, timeScale) {
2984        var i,
2985            pair,
2986            collision,
2987            bodyA,
2988            bodyB,
2989            normal,
2990            bodyBtoA,
2991            contactShare,
2992            positionImpulse,
2993            contactCount = {},
2994            tempA = Vector._temp[0],
2995            tempB = Vector._temp[1],
2996            tempC = Vector._temp[2],
2997            tempD = Vector._temp[3];
2998
2999        // find impulses required to resolve penetration
3000        for (i = 0; i < pairs.length; i++) {
3001            pair = pairs[i];
3002            
3003            if (!pair.isActive || pair.isSensor)
3004                continue;
3005
3006            collision = pair.collision;
3007            bodyA = collision.parentA;
3008            bodyB = collision.parentB;
3009            normal = collision.normal;
3010
3011            // get current separation between body edges involved in collision
3012            bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA), 
3013                                    Vector.add(bodyA.positionImpulse, 
3014                                        Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
3015
3016            pair.separation = Vector.dot(normal, bodyBtoA);
3017        }
3018        
3019        for (i = 0; i < pairs.length; i++) {
3020            pair = pairs[i];
3021
3022            if (!pair.isActive || pair.isSensor)
3023                continue;
3024            
3025            collision = pair.collision;
3026            bodyA = collision.parentA;
3027            bodyB = collision.parentB;
3028            normal = collision.normal;
3029            positionImpulse = (pair.separation - pair.slop) * timeScale;
3030
3031            if (bodyA.isStatic || bodyB.isStatic)
3032                positionImpulse *= 2;
3033            
3034            if (!(bodyA.isStatic || bodyA.isSleeping)) {
3035                contactShare = Resolver._positionDampen / bodyA.totalContacts;
3036                bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
3037                bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
3038            }
3039
3040            if (!(bodyB.isStatic || bodyB.isSleeping)) {
3041                contactShare = Resolver._positionDampen / bodyB.totalContacts;
3042                bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
3043                bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
3044            }
3045        }
3046    };
3047
3048    /**
3049     * Apply position resolution.
3050     * @method postSolvePosition
3051     * @param {body[]} bodies
3052     */
3053    Resolver.postSolvePosition = function(bodies) {
3054        for (var i = 0; i < bodies.length; i++) {
3055            var body = bodies[i];
3056
3057            // reset contact count
3058            body.totalContacts = 0;
3059
3060            if (body.positionImpulse.x !== 0 || body.positionImpulse.y !== 0) {
3061                // update body geometry
3062                for (var j = 0; j < body.parts.length; j++) {
3063                    var part = body.parts[j];
3064                    Vertices.translate(part.vertices, body.positionImpulse);
3065                    Bounds.update(part.bounds, part.vertices, body.velocity);
3066                    part.position.x += body.positionImpulse.x;
3067                    part.position.y += body.positionImpulse.y;
3068                }
3069
3070                // move the body without changing velocity
3071                body.positionPrev.x += body.positionImpulse.x;
3072                body.positionPrev.y += body.positionImpulse.y;
3073
3074                if (Vector.dot(body.positionImpulse, body.velocity) < 0) {
3075                    // reset cached impulse if the body has velocity along it
3076                    body.positionImpulse.x = 0;
3077                    body.positionImpulse.y = 0;
3078                } else {
3079                    // warm the next iteration
3080                    body.positionImpulse.x *= Resolver._positionWarming;
3081                    body.positionImpulse.y *= Resolver._positionWarming;
3082                }
3083            }
3084        }
3085    };
3086
3087    /**
3088     * Prepare pairs for velocity solving.
3089     * @method preSolveVelocity
3090     * @param {pair[]} pairs
3091     */
3092    Resolver.preSolveVelocity = function(pairs) {
3093        var i,
3094            j,
3095            pair,
3096            contacts,
3097            collision,
3098            bodyA,
3099            bodyB,
3100            normal,
3101            tangent,
3102            contact,
3103            contactVertex,
3104            normalImpulse,
3105            tangentImpulse,
3106            offset,
3107            impulse = Vector._temp[0],
3108            tempA = Vector._temp[1];
3109        
3110        for (i = 0; i < pairs.length; i++) {
3111            pair = pairs[i];
3112            
3113            if (!pair.isActive || pair.
3113isSensor)
3114                continue;
3115            
3116            contacts = pair.activeContacts;
3117            collision = pair.collision;
3118            bodyA = collision.parentA;
3119            bodyB = collision.parentB;
3120            normal = collision.normal;
3121            tangent = collision.tangent;
3122
3123            // resolve each contact
3124            for (j = 0; j < contacts.length; j++) {
3125                contact = contacts[j];
3126                contactVertex = contact.vertex;
3127                normalImpulse = contact.normalImpulse;
3128                tangentImpulse = contact.tangentImpulse;
3129
3130                if (normalImpulse !== 0 || tangentImpulse !== 0) {
3131                    // total impulse from contact
3132                    impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
3133                    impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
3134                    
3135                    // apply impulse from contact
3136                    if (!(bodyA.isStatic || bodyA.isSleeping)) {
3137                        offset = Vector.sub(contactVertex, bodyA.position, tempA);
3138                        bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
3139                        bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
3140                        bodyA.anglePrev += Vector.cross(offset, impulse) * bodyA.inverseInertia;
3141                    }
3142
3143                    if (!(bodyB.isStatic || bodyB.isSleeping)) {
3144                        offset = Vector.sub(contactVertex, bodyB.position, tempA);
3145                        bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
3146                        bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
3147                        bodyB.anglePrev -= Vector.cross(offset, impulse) * bodyB.inverseInertia;
3148                    }
3149                }
3150            }
3151        }
3152    };
3153
3154    /**
3155     * Find a solution for pair velocities.
3156     * @method solveVelocity
3157     * @param {pair[]} pairs
3158     * @param {number} timeScale
3159     */
3160    Resolver.solveVelocity = function(pairs, timeScale) {
3161        var timeScaleSquared = timeScale * timeScale,
3162            impulse = Vector._temp[0],
3163            tempA = Vector._temp[1],
3164            tempB = Vector._temp[2],
3165            tempC = Vector._temp[3],
3166            tempD = Vector._temp[4],
3167            tempE = Vector._temp[5];
3168        
3169        for (var i = 0; i < pairs.length; i++) {
3170            var pair = pairs[i];
3171            
3172            if (!pair.isActive || pair.isSensor)
3173                continue;
3174            
3175            var collision = pair.collision,
3176                bodyA = collision.parentA,
3177                bodyB = collision.parentB,
3178                normal = collision.normal,
3179                tangent = collision.tangent,
3180                contacts = pair.activeContacts,
3181                contactShare = 1 / contacts.length;
3182
3183            // update body velocities
3184            bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x;
3185            bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y;
3186            bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x;
3187            bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y;
3188            bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
3189            bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
3190
3191            // resolve each contact
3192            for (var j = 0; j < contacts.length; j++) {
3193                var contact = contacts[j],
3194                    contactVertex = contact.vertex,
3195                    offsetA = Vector.sub(contactVertex, bodyA.position, tempA),
3196                    offsetB = Vector.sub(contactVertex, bodyB.position, tempB),
3197                    velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(offsetA), bodyA.angularVelocity), tempC),
3198                    velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(offsetB), bodyB.angularVelocity), tempD), 
3199                    relativeVelocity = Vector.sub(velocityPointA, velocityPointB, tempE),
3200                    normalVelocity = Vector.dot(normal, relativeVelocity);
3201
3202                var tangentVelocity = Vector.dot(tangent, relativeVelocity),
3203                    tangentSpeed = Math.abs(tangentVelocity),
3204                    tangentVelocityDirection = Common.sign(tangentVelocity);
3205
3206                // raw impulses
3207                var normalImpulse = (1 + pair.restitution) * normalVelocity,
3208                    normalForce = Common.clamp(pair.separation + normalVelocity, 0, 1) * Resolver._frictionNormalMultiplier;
3209
3210                // coulomb friction
3211                var tangentImpulse = tangentVelocity,
3212                    maxFriction = Infinity;
3213
3214                if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) {
3215                    maxFriction = tangentSpeed;
3216                    tangentImpulse = Common.clamp(
3217                        pair.friction * tangentVelocityDirection * timeScaleSquared,
3218                        -maxFriction, maxFriction
3219                    );
3220                }
3221
3222                // modify impulses accounting for mass, inertia and offset
3223                var oAcN = Vector.cross(offsetA, normal),
3224                    oBcN = Vector.cross(offsetB, normal),
3225                    share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN  + bodyB.inverseInertia * oBcN * oBcN);
3226
3227                normalImpulse *= share;
3228                tangentImpulse *= share;
3229
3230                // handle high velocity and resting collisions separately
3231                if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) {
3232                    // high normal velocity so clear cached contact normal impulse
3233                    contact.normalImpulse = 0;
3234                } else {
3235                    // solve resting collision constraints using Erin Catto's method (GDC08)
3236                    // impulse constraint tends to 0
3237                    var contactNormalImpulse = contact.normalImpulse;
3238                    contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0);
3239                    normalImpulse = contact.normalImpulse - contactNormalImpulse;
3240                }
3241
3242                // handle high velocity and resting collisions separately
3243                if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) {
3244                    // high tangent velocity so clear cached contact tangent impulse
3245                    contact.tangentImpulse = 0;
3246                } else {
3247                    // solve resting collision constraints using Erin Catto's method (GDC08)
3248                    // tangent impulse tends to -tangentSpeed or +tangentSpeed
3249                    var contactTangentImpulse = contact.tangentImpulse;
3250                    contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction);
3251                    tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
3252                }
3253
3254                // total impulse from contact
3255                impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
3256                impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
3257                
3258                // apply impulse from contact
3259                if (!(bodyA.isStatic || bodyA.isSleeping)) {
3260                    bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
3261                    bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
3262                    bodyA.anglePrev += Vector.cross(offsetA, impulse) * bodyA.inverseInertia;
3263                }
3264
3265                if (!(bodyB.isStatic || bodyB.isSleeping)) {
3266                    bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
3267                    bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
3268                    bodyB.anglePrev -= Vector.cross(offsetB, impulse) * bodyB.inverseInertia;
3269                }
3270            }
3271        }
3272    };
3273
3274})();
3275
3276},{"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],11:[function(_dereq_,module,exports){
3277/**
3278* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
3279*
3280* @class SAT
3281*/
3282
3283// TODO: true circles and curves
3284
3285var SAT = {};
3286
3287module.exports = SAT;
3288
3289var Vertices = _dereq_('../geometry/Vertices');
3290var Vector = _dereq_('../geometry/Vector');
3291
3292(function() {
3293
3294    /**
3295     * Detect collision between two bodies using the Separating Axis Theorem.
3296     * @method collides
3297     * @param {body} bodyA
3298     * @param {body} bodyB
3299     * @param {collision} previousCollision
3300     * @return {collision} collision
3301     */
3302    SAT.collides = function(bodyA, bodyB, previousCollision) {
3303        var overlapAB,
3304            overlapBA, 
3305            minOverlap,
3306            collision,
3307            canReusePrevCol = false;
3308
3309        if (previousCollision) {
3310            // estimate total motion
3311            var parentA = bodyA.parent,
3312                parentB = bodyB.parent,
3313                motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
3314                       + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;
3315
3316            // we may be able to (partially) reuse collision result 
3317            // but only safe if collision was resting
3318            canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2;
3319
3320            // reuse collision object
3321            collision = previousCollision;
3322        } else {
3323            collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
3324        }
3325
3326        if (previousCollision && canReusePrevCol) {
3327            // if we can reuse the collision result
3328            // we only need to test the previously found axis
3329            var axisBodyA = collision.axisBody,
3330                axisBodyB = axisBodyA === bodyA ? bodyB : bodyA,
3331                axes = [axisBodyA.axes[previousCollision.axisNumber]];
3332
3333            minOverlap = SAT._overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes);
3334            collision.reused = true;
3335
3336            if (minOverlap.overlap <= 0) {
3337                collision.collided = false;
3338                return collision;
3339            }
3340        } else {
3341            // if we can't reuse a result, perform a full SAT test
3342
3343            overlapAB = SAT._overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);
3344
3345            if (overlapAB.overlap <= 0) {
3346                collision.collided = false;
3347                return collision;
3348            }
3349
3350            overlapBA = SAT._overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);
3351
3352            if (overlapBA.overlap <= 0) {
3353                collision.collided = false;
3354                return collision;
3355            }
3356
3357            if (overlapAB.overlap < overlapBA.overlap) {
3358                minOverlap = overlapAB;
3359                collision.axisBody = bodyA;
3360            } else {
3361                minOverlap = overlapBA;
3362                collision.axisBody = bodyB;
3363            }
3364
3365            // important for reuse later
3366            collision.axisNumber = minOverlap.axisNumber;
3367        }
3368
3369        collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
3370        collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
3371        collision.collided = true;
3372        collision.depth = minOverlap.overlap;
3373        collision.parentA = collision.bodyA.parent;
3374        collision.parentB = collision.bodyB.parent;
3375        
3376        bodyA = collision.bodyA;
3377        bodyB = collision.bodyB;
3378
3379        // ensure normal is facing away from bodyA
3380        if (Vector.dot(minOverlap.axis, Vector.sub(bodyB.position, bodyA.position)) < 0) {
3381            collision.normal = {
3382                x: minOverlap.axis.x,
3383                y: minOverlap.axis.y
3384            };
3385        } else {
3386            collision.normal = {
3387                x: -minOverlap.axis.x,
3388                y: -minOverlap.axis.y
3389            };
3390        }
3391
3392        collision.tangent = Vector.perp(collision.normal);
3393
3394        collision.penetration = collision.penetration || {};
3395        collision.penetration.x = collision.normal.x * collision.depth;
3396        collision.penetration.y = collision.normal.y * collision.depth; 
3397
3398        // find support points, there is always either exactly one or two
3399        var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal),
3400            supports = [];
3401
3402        // find the supports from bodyB that are inside bodyA
3403        if (Vertices.contains(bodyA.vertices, verticesB[0]))
3404            supports.push(verticesB[0]);
3405
3406        if (Vertices.contains(bodyA.vertices, verticesB[1]))
3407            supports.push(verticesB[1]);
3408
3409        // find the supports from bodyA that are inside bodyB
3410        if (supports.length < 2) {
3411            var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal));
3412                
3413            if (Vertices.contains(bodyB.vertices, verticesA[0]))
3414                supports.push(verticesA[0]);
3415
3416            if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
3417                supports.push(verticesA[1]);
3418        }
3419
3420        // account for the edge case of overlapping but no vertex containment
3421        if (supports.length < 1)
3422            supports = [verticesB[0]];
3423        
3424        collision.supports = supports;
3425
3426        return collision;
3427    };
3428
3429    /**
3430     * Find the overlap between two sets of vertices.
3431     * @method _overlapAxes
3432     * @private
3433     * @param {} verticesA
3434     * @param {} verticesB
3435     * @param {} axes
3436     * @return result
3437     */
3438    SAT._overlapAxes = function(verticesA, verticesB, axes) {
3439        var projectionA = Vector._temp[0], 
3440            projectionB = Vector._temp[1],
3441            result = { overlap: Number.MAX_VALUE },
3442            overlap,
3443            axis;
3444
3445        for (var i = 0; i < axes.length; i++) {
3446            axis = axes[i];
3447
3448            SAT._projectToAxis(projectionA, verticesA, axis);
3449            SAT._projectToAxis(projectionB, verticesB, axis);
3450
3451            overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);
3452
3453            if (overlap <= 0) {
3454                result.overlap = overlap;
3455                return result;
3456            }
3457
3458            if (overlap < result.overlap) {
3459                result.overlap = overlap;
3460                result.axis = axis;
3461                result.axisNumber = i;
3462            }
3463        }
3464
3465        return result;
3466    };
3467
3468    /**
3469     * Projects vertices on an axis and returns an interval.
3470     * @method _projectToAxis
3471     * @private
3472     * @param {} projection
3473     * @param {} vertices
3474     * @param {} axis
3475     */
3476    SAT._projectToAxis = function(projection, vertices, axis) {
3477        var min = Vector.dot(vertices[0], axis),
3478            max = min;
3479
3480        for (var i = 1; i < vertices.length; i += 1) {
3481            var dot = Vector.dot(vertices[i], axis);
3482
3483            if (dot > max) { 
3484                max = dot; 
3485            } else if (dot < min) { 
3486                min = dot; 
3487            }
3488        }
3489
3490        projection.min = min;
3491        projection.max = max;
3492    };
3493    
3494    /**
3495     * Finds supporting vertices given two bodies along a given direction using hill-climbing.
3496     * @method _findSupports
3497     * @private
3498     * @param {} bodyA
3499     * @param {} bodyB
3500     * @param {} normal
3501     * @return [vector]
3502     */
3503    SAT._findSupports = function(bodyA, bodyB, normal) {
3504        var nearestDistance = Number.MAX_VALUE,
3505            vertexToBody = Vector._temp[0],
3506            vertices = bodyB.vertices,
3507            bodyAPosition = bodyA.position,
3508            distance,
3509            vertex,
3510            vertexA,
3511            vertexB;
3512
3513        // find closest vertex on bodyB
3514        for (var i = 0; i < vertices.length; i++) {
3515            vertex = vertices[i];
3516            vertexToBody.x = vertex.x - bodyAPosition.x;
3517            vertexToBody.y = vertex.y - bodyAPosition.y;
3518            distance = -Vector.dot(normal, vertexToBody);
3519
3520            if (distance < nearestDistance) {
3521                nearestDistance = distance;
3522                vertexA = vertex;
3523            }
3524        }
3525
3526        // find next closest vertex using the two connected to it
3527        var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
3528        vertex = vertices[prevIndex];
3529        vertexToBody.x = vertex.x - bodyAPosition.x;
3530        vertexToBody.y = vertex.y - bodyAPosition.y;
3531        nearestDistance = -Vector.dot(normal, vertexToBody);
3532        vertexB = vertex;
3533
3534        var nextIndex = (vertexA.index + 1) % vertices.length;
3535        vertex = vertices[nextIndex];
3536        vertexToBody.x = vertex.x - bodyAPosition.x;
3537        vertexToBody.y = vertex.y - bodyAPosition.y;
3538        distance = -Vector.dot(normal, vertexToBody);
3539        if (distance < nearestDistance) {
3540            vertexB = vertex;
3541        }
3542
3543        return [vertexA, vertexB];
3544    };
3545
3546})();
3547
3548},{"../geometry/Vector":28,"../geometry/Vertices":29}],12:[function(_dereq_,module,exports){
3549/**
3550* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
3551* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
3552* The stiffness of constraints can be modified to create springs or elastic.
3553*
3554* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
3555*
3556* @class Constraint
3557*/
3558
3559var Constraint = {};
3560
3561module.exports = Constraint;
3562
3563var Vertices = _dereq_('../geometry/Vertices');
3564var Vector = _dereq_('../geometry/Vector');
3565var Sleeping = _dereq_('../core/Sleeping');
3566var Bounds = _dereq_('../geometry/Bounds');
3567var Axes = _dereq_('../geometry/Axes');
3568var Common = _dereq_('../core/Common');
3569
3570(function() {
3571
3572    Constraint._warming = 0.4;
3573    Constraint._torqueDampen = 1;
3574    Constraint._minLength = 0.000001;
3575
3576    /**
3577     * Creates a new constraint.
3578     * All properties have default values, and many are pre-calculated automatically based on other properties.
3579     * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above).
3580     * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`.
3581     * For compound bodies, constraints must be applied to the parent body (not one of its parts).
3582     * See the properties section below for detailed information on what you can pass via the `options` object.
3583     * @method create
3584     * @param {} options
3585     * @return {constraint} constraint
3586     */
3587    Constraint.create = function(options) {
3588        var constraint = options;
3589
3590        // if bodies defined but no points, use body centre
3591        if (constraint.bodyA && !constraint.pointA)
3592            constraint.pointA = { x: 0, y: 0 };
3593        if (constraint.bodyB && !constraint.pointB)
3594            constraint.pointB = { x: 0, y: 0 };
3595
3596        // calculate static length using initial world space points
3597        var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA,
3598            initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB,
3599            length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));
3600    
3601        constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length;
3602
3603        // option defaults
3604        constraint.id = constraint.id || Common.nextId();
3605        constraint.label = constraint.label || 'Constraint';
3606        constraint.type = 'constraint';
3607        constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
3608        constraint.damping = constraint.damping || 0;
3609        constraint.angularStiffness = constraint.angularStiffness || 0;
3610        constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
3611        constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
3612        constraint.plugin = {};
3613
3614        // render
3615        var render = {
3616            visible: true,
3617            lineWidth: 2,
3618            strokeStyle: '#ffffff',
3619            type: 'line',
3620            anchors: true
3621        };
3622
3623        if (constraint.length === 0 && constraint.stiffness > 0.1) {
3624            render.type = 'pin';
3625            render.anchors = false;
vendor: 34,448 bytes, lines 3626-4718
3626        } else if (constraint.stiffness < 0.9) {
3627            render.type = 'spring';
3628        }
3629
3630        constraint.render = Common.extend(render, constraint.render);
3631
3632        return constraint;
3633    };
3634
3635    /**
3636     * Prepares for solving by constraint warming.
3637     * @private
3638     * @method preSolveAll
3639     * @param {body[]} bodies
3640     */
3641    Constraint.preSolveAll = function(bodies) {
3642        for (var i = 0; i < bodies.length; i += 1) {
3643            var body = bodies[i],
3644                impulse = body.constraintImpulse;
3645
3646            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
3647                continue;
3648            }
3649
3650            body.position.x += impulse.x;
3651            body.position.y += impulse.y;
3652            body.angle += impulse.angle;
3653        }
3654    };
3655
3656    /**
3657     * Solves all constraints in a list of collisions.
3658     * @private
3659     * @method solveAll
3660     * @param {constraint[]} constraints
3661     * @param {number} timeScale
3662     */
3663    Constraint.solveAll = function(constraints, timeScale) {
3664        // Solve fixed constraints first.
3665        for (var i = 0; i < constraints.length; i += 1) {
3666            var constraint = constraints[i],
3667                fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic),
3668                fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
3669
3670            if (fixedA || fixedB) {
3671                Constraint.solve(constraints[i], timeScale);
3672            }
3673        }
3674
3675        // Solve free constraints last.
3676        for (i = 0; i < constraints.length; i += 1) {
3677            constraint = constraints[i];
3678            fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic);
3679            fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
3680
3681            if (!fixedA && !fixedB) {
3682                Constraint.solve(constraints[i], timeScale);
3683            }
3684        }
3685    };
3686
3687    /**
3688     * Solves a distance constraint with Gauss-Siedel method.
3689     * @private
3690     * @method solve
3691     * @param {constraint} constraint
3692     * @param {number} timeScale
3693     */
3694    Constraint.solve = function(constraint, timeScale) {
3695        var bodyA = constraint.bodyA,
3696            bodyB = constraint.bodyB,
3697            pointA = constraint.pointA,
3698            pointB = constraint.pointB;
3699
3700        if (!bodyA && !bodyB)
3701            return;
3702
3703        // update reference angle
3704        if (bodyA && !bodyA.isStatic) {
3705            Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
3706            constraint.angleA = bodyA.angle;
3707        }
3708        
3709        // update reference angle
3710        if (bodyB && !bodyB.isStatic) {
3711            Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
3712            constraint.angleB = bodyB.angle;
3713        }
3714
3715        var pointAWorld = pointA,
3716            pointBWorld = pointB;
3717
3718        if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
3719        if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);
3720
3721        if (!pointAWorld || !pointBWorld)
3722            return;
3723
3724        var delta = Vector.sub(pointAWorld, pointBWorld),
3725            currentLength = Vector.magnitude(delta);
3726
3727        // prevent singularity
3728        if (currentLength < Constraint._minLength) {
3729            currentLength = Constraint._minLength;
3730        }
3731
3732        // solve distance constraint with Gauss-Siedel method
3733        var difference = (currentLength - constraint.length) / currentLength,
3734            stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
3735            force = Vector.mult(delta, difference * stiffness),
3736            massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
3737            inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
3738            resistanceTotal = massTotal + inertiaTotal,
3739            torque,
3740            share,
3741            normal,
3742            normalVelocity,
3743            relativeVelocity;
3744
3745        if (constraint.damping) {
3746            var zero = Vector.create();
3747            normal = Vector.div(delta, currentLength);
3748
3749            relativeVelocity = Vector.sub(
3750                bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
3751                bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
3752            );
3753
3754            normalVelocity = Vector.dot(normal, relativeVelocity);
3755        }
3756
3757        if (bodyA && !bodyA.isStatic) {
3758            share = bodyA.inverseMass / massTotal;
3759
3760            // keep track of applied impulses for post solving
3761            bodyA.constraintImpulse.x -= force.x * share;
3762            bodyA.constraintImpulse.y -= force.y * share;
3763
3764            // apply forces
3765            bodyA.position.x -= force.x * share;
3766            bodyA.position.y -= force.y * share;
3767
3768            // apply damping
3769            if (constraint.damping) {
3770                bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share;
3771                bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share;
3772            }
3773
3774            // apply torque
3775            torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
3776            bodyA.constraintImpulse.angle -= torque;
3777            bodyA.angle -= torque;
3778        }
3779
3780        if (bodyB && !bodyB.isStatic) {
3781            share = bodyB.inverseMass / massTotal;
3782
3783            // keep track of applied impulses for post solving
3784            bodyB.constraintImpulse.x += force.x * share;
3785            bodyB.constraintImpulse.y += force.y * share;
3786            
3787            // apply forces
3788            bodyB.position.x += force.x * share;
3789            bodyB.position.y += force.y * share;
3790
3791            // apply damping
3792            if (constraint.damping) {
3793                bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share;
3794                bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share;
3795            }
3796
3797            // apply torque
3798            torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
3799            bodyB.constraintImpulse.angle += torque;
3800            bodyB.angle += torque;
3801        }
3802
3803    };
3804
3805    /**
3806     * Performs body updates required after solving constraints.
3807     * @private
3808     * @method postSolveAll
3809     * @param {body[]} bodies
3810     */
3811    Constraint.postSolveAll = function(bodies) {
3812        for (var i = 0; i < bodies.length; i++) {
3813            var body = bodies[i],
3814                impulse = body.constraintImpulse;
3815
3816            if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
3817                continue;
3818            }
3819
3820            Sleeping.set(body, false);
3821
3822            // update geometry and reset
3823            for (var j = 0; j < body.parts.length; j++) {
3824                var part = body.parts[j];
3825                
3826                Vertices.translate(part.vertices, impulse);
3827
3828                if (j > 0) {
3829                    part.position.x += impulse.x;
3830                    part.position.y += impulse.y;
3831                }
3832
3833                if (impulse.angle !== 0) {
3834                    Vertices.rotate(part.vertices, impulse.angle, body.position);
3835                    Axes.rotate(part.axes, impulse.angle);
3836                    if (j > 0) {
3837                        Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
3838                    }
3839                }
3840
3841                Bounds.update(part.bounds, part.vertices, body.velocity);
3842            }
3843
3844            // dampen the cached impulse for warming next step
3845            impulse.angle *= Constraint._warming;
3846            impulse.x *= Constraint._warming;
3847            impulse.y *= Constraint._warming;
3848        }
3849    };
3850
3851    /*
3852    *
3853    *  Properties Documentation
3854    *
3855    */
3856
3857    /**
3858     * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
3859     *
3860     * @property id
3861     * @type number
3862     */
3863
3864    /**
3865     * A `String` denoting the type of object.
3866     *
3867     * @property type
3868     * @type string
3869     * @default "constraint"
3870     * @readOnly
3871     */
3872
3873    /**
3874     * An arbitrary `String` name to help the user identify and manage bodies.
3875     *
3876     * @property label
3877     * @type string
3878     * @default "Constraint"
3879     */
3880
3881    /**
3882     * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
3883     *
3884     * @property render
3885     * @type object
3886     */
3887
3888    /**
3889     * A flag that indicates if the constraint should be rendered.
3890     *
3891     * @property render.visible
3892     * @type boolean
3893     * @default true
3894     */
3895
3896    /**
3897     * A `Number` that defines the line width to use when rendering the constraint outline.
3898     * A value of `0` means no outline will be rendered.
3899     *
3900     * @property render.lineWidth
3901     * @type number
3902     * @default 2
3903     */
3904
3905    /**
3906     * A `String` that defines the stroke style to use when rendering the constraint outline.
3907     * It is the same as when using a canvas, so it accepts CSS style property values.
3908     *
3909     * @property render.strokeStyle
3910     * @type string
3911     * @default a random colour
3912     */
3913
3914    /**
3915     * A `String` that defines the constraint rendering type. 
3916     * The possible values are 'line', 'pin', 'spring'.
3917     * An appropriate render type will be automatically chosen unless one is given in options.
3918     *
3919     * @property render.type
3920     * @type string
3921     * @default 'line'
3922     */
3923
3924    /**
3925     * A `Boolean` that defines if the constraint's anchor points should be rendered.
3926     *
3927     * @property render.anchors
3928     * @type boolean
3929     * @default true
3930     */
3931
3932    /**
3933     * The first possible `Body` that this constraint is attached to.
3934     *
3935     * @property bodyA
3936     * @type body
3937     * @default null
3938     */
3939
3940    /**
3941     * The second possible `Body` that this constraint is attached to.
3942     *
3943     * @property bodyB
3944     * @type body
3945     * @default null
3946     */
3947
3948    /**
3949     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
3950     *
3951     * @property pointA
3952     * @type vector
3953     * @default { x: 0, y: 0 }
3954     */
3955
3956    /**
3957     * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position.
3958     *
3959     * @property pointB
3960     * @type vector
3961     * @default { x: 0, y: 0 }
3962     */
3963
3964    /**
3965     * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`.
3966     * A value of `1` means the constraint should be very stiff.
3967     * A value of `0.2` means the constraint acts like a soft spring.
3968     *
3969     * @property stiffness
3970     * @type number
3971     * @default 1
3972     */
3973
3974    /**
3975     * A `Number` that specifies the damping of the constraint, 
3976     * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation.
3977     * Damping will only be apparent when the constraint also has a very low `stiffness`.
3978     * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation.
3979     * A value of `0` means the constraint will apply no damping.
3980     *
3981     * @property damping
3982     * @type number
3983     * @default 0
3984     */
3985
3986    /**
3987     * A `Number` that specifies the target resting length of the constraint. 
3988     * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
3989     *
3990     * @property length
3991     * @type number
3992     */
3993
3994    /**
3995     * An object reserved for storing plugin-specific properties.
3996     *
3997     * @property plugin
3998     * @type {}
3999     */
4000
4001})();
4002
4003},{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],13:[function(_dereq_,module,exports){
4004/**
4005* The `Matter.MouseConstraint` module contains methods for creating mouse constraints.
4006* Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch.
4007*
4008* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
4009*
4010* @class MouseConstraint
4011*/
4012
4013var MouseConstraint = {};
4014
4015module.exports = MouseConstraint;
4016
4017var Vertices = _dereq_('../geometry/Vertices');
4018var Sleeping = _dereq_('../core/Sleeping');
4019var Mouse = _dereq_('../core/Mouse');
4020var Events = _dereq_('../core/Events');
4021var Detector = _dereq_('../collision/Detector');
4022var Constraint = _dereq_('./Constraint');
4023var Composite = _dereq_('../body/Composite');
4024var Common = _dereq_('../core/Common');
4025var Bounds = _dereq_('../geometry/Bounds');
4026
4027(function() {
4028
4029    /**
4030     * Creates a new mouse constraint.
4031     * All properties have default values, and many are pre-calculated automatically based on other properties.
4032     * See the properties section below for detailed information on what you can pass via the `options` object.
4033     * @method create
4034     * @param {engine} engine
4035     * @param {} options
4036     * @return {MouseConstraint} A new MouseConstraint
4037     */
4038    MouseConstraint.create = function(engine, options) {
4039        var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null);
4040
4041        if (!mouse) {
4042            if (engine && engine.render && engine.render.canvas) {
4043                mouse = Mouse.create(engine.render.canvas);
4044            } else if (options && options.element) {
4045                mouse = Mouse.create(options.element);
4046            } else {
4047                mouse = Mouse.create();
4048                Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected');
4049            }
4050        }
4051
4052        var constraint = Constraint.create({ 
4053            label: 'Mouse Constraint',
4054            pointA: mouse.position,
4055            pointB: { x: 0, y: 0 },
4056            length: 0.01, 
4057            stiffness: 0.1,
4058            angularStiffness: 1,
4059            render: {
4060                strokeStyle: '#90EE90',
4061                lineWidth: 3
4062            }
4063        });
4064
4065        var defaults = {
4066            type: 'mouseConstraint',
4067            mouse: mouse,
4068            element: null,
4069            body: null,
4070            constraint: constraint,
4071            collisionFilter: {
4072                category: 0x0001,
4073                mask: 0xFFFFFFFF,
4074                group: 0
4075            }
4076        };
4077
4078        var mouseConstraint = Common.extend(defaults, options);
4079
4080        Events.on(engine, 'beforeUpdate', function() {
4081            var allBodies = Composite.allBodies(engine.world);
4082            MouseConstraint.update(mouseConstraint, allBodies);
4083            MouseConstraint._triggerEvents(mouseConstraint);
4084        });
4085
4086        return mouseConstraint;
4087    };
4088
4089    /**
4090     * Updates the given mouse constraint.
4091     * @private
4092     * @method update
4093     * @param {MouseConstraint} mouseConstraint
4094     * @param {body[]} bodies
4095     */
4096    MouseConstraint.update = function(mouseConstraint, bodies) {
4097        var mouse = mouseConstraint.mouse,
4098            constraint = mouseConstraint.constraint,
4099            body = mouseConstraint.body;
4100
4101        if (mouse.button === 0) {
4102            if (!constraint.bodyB) {
4103                for (var i = 0; i < bodies.length; i++) {
4104                    body = bodies[i];
4105                    if (Bounds.contains(body.bounds, mouse.position) 
4106                            && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) {
4107                        for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) {
4108                            var part = body.parts[j];
4109                            if (Vertices.contains(part.vertices, mouse.position)) {
4110                                constraint.pointA = mouse.position;
4111                                constraint.bodyB = mouseConstraint.body = body;
4112                                constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y };
4113                                constraint.angleB = body.angle;
4114
4115                                Sleeping.set(body, false);
4116                                Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body });
4117
4118                                break;
4119                            }
4120                        }
4121                    }
4122                }
4123            } else {
4124                Sleeping.set(constraint.bodyB, false);
4125                constraint.pointA = mouse.position;
4126            }
4127        } else {
4128            constraint.bodyB = mouseConstraint.body = null;
4129            constraint.pointB = null;
4130
4131            if (body)
4132                Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body });
4133        }
4134    };
4135
4136    /**
4137     * Triggers mouse constraint events.
4138     * @method _triggerEvents
4139     * @private
4140     * @param {mouse} mouseConstraint
4141     */
4142    MouseConstraint._triggerEvents = function(mouseConstraint) {
4143        var mouse = mouseConstraint.mouse,
4144            mouseEvents = mouse.sourceEvents;
4145
4146        if (mouseEvents.mousemove)
4147            Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse });
4148
4149        if (mouseEvents.mousedown)
4150            Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse });
4151
4152        if (mouseEvents.mouseup)
4153            Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse });
4154
4155        // reset the mouse state ready for the next step
4156        Mouse.clearSourceEvents(mouse);
4157    };
4158
4159    /*
4160    *
4161    *  Events Documentation
4162    *
4163    */
4164
4165    /**
4166    * Fired when the mouse has moved (or a touch moves) during the last step
4167    *
4168    * @event mousemove
4169    * @param {} event An event object
4170    * @param {mouse} event.mouse The engine's mouse instance
4171    * @param {} event.source The source object of the event
4172    * @param {} event.name The name of the event
4173    */
4174
4175    /**
4176    * Fired when the mouse is down (or a touch has started) during the last step
4177    *
4178    * @event mousedown
4179    * @param {} event An event object
4180    * @param {mouse} event.mouse The engine's mouse instance
4181    * @param {} event.source The source object of the event
4182    * @param {} event.name The name of the event
4183    */
4184
4185    /**
4186    * Fired when the mouse is up (or a touch has ended) during the last step
4187    *
4188    * @event mouseup
4189    * @param {} event An event object
4190    * @param {mouse} event.mouse The engine's mouse instance
4191    * @param {} event.source The source object of the event
4192    * @param {} event.name The name of the event
4193    */
4194
4195    /**
4196    * Fired when the user starts dragging a body
4197    *
4198    * @event startdrag
4199    * @param {} event An event object
4200    * @param {mouse} event.mouse The engine's mouse instance
4201    * @param {body} event.body The body being dragged
4202    * @param {} event.source The source object of the event
4203    * @param {} event.name The name of the event
4204    */
4205
4206    /**
4207    * Fired when the user ends dragging a body
4208    *
4209    * @event enddrag
4210    * @param {} event An event object
4211    * @param {mouse} event.mouse The engine's mouse instance
4212    * @param {body} event.body The body that has stopped being dragged
4213    * @param {} event.source The source object of the event
4214    * @param {} event.name The name of the event
4215    */
4216
4217    /*
4218    *
4219    *  Properties Documentation
4220    *
4221    */
4222
4223    /**
4224     * A `String` denoting the type of object.
4225     *
4226     * @property type
4227     * @type string
4228     * @default "constraint"
4229     * @readOnly
4230     */
4231
4232    /**
4233     * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created.
4234     *
4235     * @property mouse
4236     * @type mouse
4237     * @default mouse
4238     */
4239
4240    /**
4241     * The `Body` that is currently being moved by the user, or `null` if no body.
4242     *
4243     * @property body
4244     * @type body
4245     * @default null
4246     */
4247
4248    /**
4249     * The `Constraint` object that is used to move the body during interaction.
4250     *
4251     * @property constraint
4252     * @type constraint
4253     */
4254
4255    /**
4256     * An `Object` that specifies the collision filter properties.
4257     * The collision filter allows the user to define which types of body this mouse constraint can interact with.
4258     * See `body.collisionFilter` for more information.
4259     *
4260     * @property collisionFilter
4261     * @type object
4262     */
4263
4264})();
4265
4266},{"../body/Composite":2,"../collision/Detector":5,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../core/Sleeping":22,"../geometry/Bounds":26,"../geometry/Vertices":29,"./Constraint":12}],14:[function(_dereq_,module,exports){
4267(function (global){
4268/**
4269* The `Matter.Common` module contains utility functions that are common to all modules.
4270*
4271* @class Common
4272*/
4273
4274var Common = {};
4275
4276module.exports = Common;
4277
4278(function() {
4279
4280    Common._nextId = 0;
4281    Common._seed = 0;
4282    Common._nowStartTime = +(new Date());
4283
4284    /**
4285     * Extends the object in the first argument using the object in the second argument.
4286     * @method extend
4287     * @param {} obj
4288     * @param {boolean} deep
4289     * @return {} obj extended
4290     */
4291    Common.extend = function(obj, deep) {
4292        var argsStart,
4293            args,
4294            deepClone;
4295
4296        if (typeof deep === 'boolean') {
4297            argsStart = 2;
4298            deepClone = deep;
4299        } else {
4300            argsStart = 1;
4301            deepClone = true;
4302        }
4303
4304        for (var i = argsStart; i < arguments.length; i++) {
4305            var source = arguments[i];
4306
4307            if (source) {
4308                for (var prop in source) {
4309                    if (deepClone && source[prop] && source[prop].constructor === Object) {
4310                        if (!obj[prop] || obj[prop].constructor === Object) {
4311                            obj[prop] = obj[prop] || {};
4312                            Common.extend(obj[prop], deepClone, source[prop]);
4313                        } else {
4314                            obj[prop] = source[prop];
4315                        }
4316                    } else {
4317                        obj[prop] = source[prop];
4318                    }
4319                }
4320            }
4321        }
4322        
4323        return obj;
4324    };
4325
4326    /**
4327     * Creates a new clone of the object, if deep is true references will also be cloned.
4328     * @method clone
4329     * @param {} obj
4330     * @param {bool} deep
4331     * @return {} obj cloned
4332     */
4333    Common.clone = function(obj, deep) {
4334        return Common.extend({}, deep, obj);
4335    };
4336
4337    /**
4338     * Returns the list of keys for the given object.
4339     * @method keys
4340     * @param {} obj
4341     * @return {string[]} keys
4342     */
4343    Common.keys = function(obj) {
4344        if (Object.keys)
4345            return Object.keys(obj);
4346
4347        // avoid hasOwnProperty for performance
4348        var keys = [];
4349        for (var key in obj)
4350            keys.push(key);
4351        return keys;
4352    };
4353
4354    /**
4355     * Returns the list of values for the given object.
4356     * @method values
4357     * @param {} obj
4358     * @return {array} Array of the objects property values
4359     */
4360    Common.values = function(obj) {
4361        var values = [];
4362        
4363        if (Object.keys) {
4364            var keys = Object.keys(obj);
4365            for (var i = 0; i < keys.length; i++) {
4366                values.push(obj[keys[i]]);
4367            }
4368            return values;
4369        }
4370        
4371        // avoid hasOwnProperty for performance
4372        for (var key in obj)
4373            values.push(obj[key]);
4374        return values;
4375    };
4376
4377    /**
4378     * Gets a value from `base` relative to the `path` string.
4379     * @method get
4380     * @param {} obj The base object
4381     * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
4382     * @param {number} [begin] Path slice begin
4383     * @param {number} [end] Path slice end
4384     * @return {} The object at the given path
4385     */
4386    Common.get = function(obj, path, begin, end) {
4387        path = path.split('.').slice(begin, end);
4388
4389        for (var i = 0; i < path.length; i += 1) {
4390            obj = obj[path[i]];
4391        }
4392
4393        return obj;
4394    };
4395
4396    /**
4397     * Sets a value on `base` relative to the given `path` string.
4398     * @method set
4399     * @param {} obj The base object
4400     * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
4401     * @param {} val The value to set
4402     * @param {number} [begin] Path slice begin
4403     * @param {number} [end] Path slice end
4404     * @return {} Pass through `val` for chaining
4405     */
4406    Common.set = function(obj, path, val, begin, end) {
4407        var parts = path.split('.').slice(begin, end);
4408        Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val;
4409        return val;
4410    };
4411
4412    /**
4413     * Shuffles the given array in-place.
4414     * The function uses a seeded random generator.
4415     * @method shuffle
4416     * @param {array} array
4417     * @return {array} array shuffled randomly
4418     */
4419    Common.shuffle = function(array) {
4420        for (var i = array.length - 1; i > 0; i--) {
4421            var j = Math.floor(Common.random() * (i + 1));
4422            var temp = array[i];
4423            array[i] = array[j];
4424            array[j] = temp;
4425        }
4426        return array;
4427    };
4428
4429    /**
4430     * Randomly chooses a value from a list with equal probability.
4431     * The function uses a seeded random generator.
4432     * @method choose
4433     * @param {array} choices
4434     * @return {object} A random choice object from the array
4435     */
4436    Common.choose = function(choices) {
4437        return choices[Math.floor(Common.random() * choices.length)];
4438    };
4439
4440    /**
4441     * Returns true if the object is a HTMLElement, otherwise false.
4442     * @method isElement
4443     * @param {object} obj
4444     * @return {boolean} True if the object is a HTMLElement, otherwise false
4445     */
4446    Common.isElement = function(obj) {
4447        if (typeof HTMLElement !== 'undefined') {
4448            return obj instanceof HTMLElement;
4449        }
4450
4451        return !!(obj && obj.nodeType && obj.nodeName);
4452    };
4453
4454    /**
4455     * Returns true if the object is an array.
4456     * @method isArray
4457     * @param {object} obj
4458     * @return {boolean} True if the object is an array, otherwise false
4459     */
4460    Common.isArray = function(obj) {
4461        return Object.prototype.toString.call(obj) === '[object Array]';
4462    };
4463
4464    /**
4465     * Returns true if the object is a function.
4466     * @method isFunction
4467     * @param {object} obj
4468     * @return {boolean} True if the object is a function, otherwise false
4469     */
4470    Common.isFunction = function(obj) {
4471        return typeof obj === "function";
4472    };
4473
4474    /**
4475     * Returns true if the object is a plain object.
4476     * @method isPlainObject
4477     * @param {object} obj
4478     * @return {boolean} True if the object is a plain object, otherwise false
4479     */
4480    Common.isPlainObject = function(obj) {
4481        return typeof obj === 'object' && obj.constructor === Object;
4482    };
4483
4484    /**
4485     * Returns true if the object is a string.
4486     * @method isString
4487     * @param {object} obj
4488     * @return {boolean} True if the object is a string, otherwise false
4489     */
4490    Common.isString = function(obj) {
4491        return toString.call(obj) === '[object String]';
4492    };
4493    
4494    /**
4495     * Returns the given value clamped between a minimum and maximum value.
4496     * @method clamp
4497     * @param {number} value
4498     * @param {number} min
4499     * @param {number} max
4500     * @return {number} The value clamped between min and max inclusive
4501     */
4502    Common.clamp = function(value, min, max) {
4503        if (value < min)
4504            return min;
4505        if (value > max)
4506            return max;
4507        return value;
4508    };
4509    
4510    /**
4511     * Returns the sign of the given value.
4512     * @method sign
4513     * @param {number} value
4514     * @return {number} -1 if negative, +1 if 0 or positive
4515     */
4516    Common.sign = function(value) {
4517        return value < 0 ? -1 : 1;
4518    };
4519    
4520    /**
4521     * Returns the current timestamp since the time origin (e.g. from page load).
4522     * The result will be high-resolution including decimal places if available.
4523     * @method now
4524     * @return {number} the current timestamp
4525     */
4526    Common.now = function() {
4527        if (window.performance) {
4528            if (window.performance.now) {
4529                return window.performance.now();
4530            } else if (window.performance.webkitNow) {
4531                return window.performance.webkitNow();
4532            }
4533        }
4534
4535        return (new Date()) - Common._nowStartTime;
4536    };
4537    
4538    /**
4539     * Returns a random value between a minimum and a maximum value inclusive.
4540     * The function uses a seeded random generator.
4541     * @method random
4542     * @param {number} min
4543     * @param {number} max
4544     * @return {number} A random number between min and max inclusive
4545     */
4546    Common.random = function(min, max) {
4547        min = (typeof min !== "undefined") ? min : 0;
4548        max = (typeof max !== "undefined") ? max : 1;
4549        return min + _seededRandom() * (max - min);
4550    };
4551
4552    var _seededRandom = function() {
4553        // https://en.wikipedia.org/wiki/Linear_congruential_generator
4554        Common._seed = (Common._seed * 9301 + 49297) % 233280;
4555        return Common._seed / 233280;
4556    };
4557
4558    /**
4559     * Converts a CSS hex colour string into an integer.
4560     * @method colorToNumber
4561     * @param {string} colorString
4562     * @return {number} An integer representing the CSS hex string
4563     */
4564    Common.colorToNumber = function(colorString) {
4565        colorString = colorString.replace('#','');
4566
4567        if (colorString.length == 3) {
4568            colorString = colorString.charAt(0) + colorString.charAt(0)
4569                        + colorString.charAt(1) + colorString.charAt(1)
4570                        + colorString.charAt(2) + colorString.charAt(2);
4571        }
4572
4573        return parseInt(colorString, 16);
4574    };
4575
4576    /**
4577     * The console logging level to use, where each level includes all levels above and excludes the levels below.
4578     * The default level is 'debug' which shows all console messages.  
4579     *
4580     * Possible level values are:
4581     * - 0 = None
4582     * - 1 = Debug
4583     * - 2 = Info
4584     * - 3 = Warn
4585     * - 4 = Error
4586     * @property Common.logLevel
4587     * @type {Number}
4588     * @default 1
4589     */
4590    Common.logLevel = 1;
4591
4592    /**
4593     * Shows a `console.log` message only if the current `Common.logLevel` allows it.
4594     * The message will be prefixed with 'matter-js' to make it easily identifiable.
4595     * @method log
4596     * @param ...objs {} The objects to log.
4597     */
4598    Common.log = function() {
4599        if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
4600            console.log.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
4601        }
4602    };
4603
4604    /**
4605     * Shows a `console.info` message only if the current `Common.logLevel` allows it.
4606     * The message will be prefixed with 'matter-js' to make it easily identifiable.
4607     * @method info
4608     * @param ...objs {} The objects to log.
4609     */
4610    Common.info = function() {
4611        if (console && Common.logLevel > 0 && Common.logLevel <= 2) {
4612            console.info.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
4613        }
4614    };
4615
4616    /**
4617     * Shows a `console.warn` message only if the current `Common.logLevel` allows it.
4618     * The message will be prefixed with 'matter-js' to make it easily identifiable.
4619     * @method warn
4620     * @param ...objs {} The objects to log.
4621     */
4622    Common.warn = function() {
4623        if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
4624            console.warn.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
4625        }
4626    };
4627
4628    /**
4629     * Returns the next unique sequential ID.
4630     * @method nextId
4631     * @return {Number} Unique sequential ID
4632     */
4633    Common.nextId = function() {
4634        return Common._nextId++;
4635    };
4636
4637    /**
4638     * A cross browser compatible indexOf implementation.
4639     * @method indexOf
4640     * @param {array} haystack
4641     * @param {object} needle
4642     * @return {number} The position of needle in haystack, otherwise -1.
4643     */
4644    Common.indexOf = function(haystack, needle) {
4645        if (haystack.indexOf)
4646            return haystack.indexOf(needle);
4647
4648        for (var i = 0; i < haystack.length; i++) {
4649            if (haystack[i] === needle)
4650                return i;
4651        }
4652
4653        return -1;
4654    };
4655
4656    /**
4657     * A cross browser compatible array map implementation.
4658     * @method map
4659     * @param {array} list
4660     * @param {function} func
4661     * @return {array} Values from list transformed by func.
4662     */
4663    Common.map = function(list, func) {
4664        if (list.map) {
4665            return list.map(func);
4666        }
4667
4668        var mapped = [];
4669
4670        for (var i = 0; i < list.length; i += 1) {
4671            mapped.push(func(list[i]));
4672        }
4673
4674        return mapped;
4675    };
4676
4677    /**
4678     * Takes a directed graph and returns the partially ordered set of vertices in topological order.
4679     * Circular dependencies are allowed.
4680     * @method topologicalSort
4681     * @param {object} graph
4682     * @return {array} Partially ordered set of vertices in topological order.
4683     */
4684    Common.topologicalSort = function(graph) {
4685        // https://github.com/mgechev/javascript-algorithms
4686        // Copyright (c) Minko Gechev (MIT license)
4687        // Modifications: tidy formatting and naming
4688        var result = [],
4689            visited = [],
4690            temp = [];
4691
4692        for (var node in graph) {
4693            if (!visited[node] && !temp[node]) {
4694                Common._topologicalSort(node, visited, temp, graph, result);
4695            }
4696        }
4697
4698        return result;
4699    };
4700
4701    Common._topologicalSort = function(node, visited, temp, graph, result) {
4702        var neighbors = graph[node] || [];
4703        temp[node] = true;
4704
4705        for (var i = 0; i < neighbors.length; i += 1) {
4706            var neighbor = neighbors[i];
4707
4708            if (temp[neighbor]) {
4709                // skip circular dependencies
4710                continue;
4711            }
4712
4713            if (!visited[neighbor]) {
4714                Common._topologicalSort(neighbor, visited, temp, graph, result);
4715            }
4716        }
4717
4718        temp[node] = false;
4719        visited[node] = true;
4720
4721        result.push(node);
4722    };
4723
4724    /**
4725     * Takes _n_ functions as arguments and returns a new function that calls them in order.
4726     * The arguments applied when calling the new function will also be applied to every function passed.
4727     * The value of `this` refers to the last value returned in the chain that was not `undefined`.
4728     * Therefore if a passed function does not return a value, the previously returned value is maintained.
4729     * After all passed functions have been called the new function returns the last returned value (if any).
4730     * If any of the passed functions are a chain, then the chain will be flattened.
4731     * @method chain
4732     * @param ...funcs {function} The functions to chain.
4733     * @return {function} A new function that calls the passed functions in order.
4734     */
4735    Common.chain = function() {
4736        var funcs = [];
4737
4738        for (var i = 0; i < arguments.length; i += 1) {
4739            var func = arguments[i];
4740
4741            if (func._chained) {
4742                // flatten already chained functions
4743                funcs.push.apply(funcs, func._chained);
4744            } else {
4745                funcs.push(func);
4746            }
4747        }
4748
4749        var chain = function() {
4750            // https://github.com/GoogleChrome/devtools-docs/issues/53#issuecomment-51941358
4751            var lastResult,
4752                args = new Array(arguments.length);
4753
4754            for (var i = 0, l = arguments.length; i < l; i++) {
4755                args[i] = arguments[i];
4756            }
4757
4758            for (i = 0; i < funcs.length; i += 1) {
4759                var result = funcs[i].apply(lastResult, args);
4760
4761                if (typeof result !== 'undefined') {
4762                    lastResult = result;
4763                }
4764            }
4765
4766            return lastResult;
4767        };
4768
4769        chain._chained = funcs;
4770
4771        return chain;
4772    };
4773
4774    /**
4775     * Chains a function to excute before the original function on the given `path` relative to `base`.
4776     * See also docs for `Common.chain`.
4777     * @method chainPathBefore
4778     * @param {} base The base object
4779     * @param {string} path The path relative to `base`
4780     * @param {function} func The function to chain before the original
4781     * @return {function} The chained function that replaced the original
4782     */
4783    Common.chainPathBefore = function(base, path, func) {
4784        return Common.set(base, path, Common.chain(
4785            func,
4786            Common.get(base, path)
4787        ));
4788    };
4789
4790    /**
4791     * Chains a function to excute after the original function on the given `path` relative to `base`.
4792     * See also docs for `Common.chain`.
4793     * @method chainPathAfter
4794     * @param {} base The base object
4795     * @param {string} path The path relative to `base`
4796     * @param {function} func The function to chain after the original
4797     * @return {function} The chained function that replaced the original
4798     */
4799    Common.chainPathAfter = function(base, path, func) {
4800        return Common.set(base, path, Common.chain(
4801            Common.get(base, path),
4802            func
4803        ));
4804    };
4805
4806    /**
4807     * Used to require external libraries outside of the bundle.
4808     * It first looks for the `globalName` on the environment's global namespace.
4809     * If the global is not found, it will fall back to using the standard `require` using the `moduleName`.
4810     * @private
4811     * @method _requireGlobal
4812     * @param {string} globalName The global module name
4813     * @param {string} moduleName The fallback CommonJS module name
4814     * @return {} The loaded module
4815     */
4816    Common._requireGlobal = function(globalName, moduleName) {
4817        var obj = (typeof window !== 'undefined' ? window[globalName] : typeof global !== 'undefined' ? global[globalName] : null);
4818        return obj || _dereq_(moduleName);
4819    };
4820})();
4821
4822}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4823},{}],15:[function(_dereq_,module,exports){
4824/**
4825* The `Matter.Engine` module contains methods for creating and manipulating engines.
4826* An engine is a controller that manages updating the simulation of the world.
4827* See `Matter.Runner` for an optional game loop utility.
4828*
4829* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
4830*
4831* @class Engine
4832*/
4833
4834var Engine = {};
4835
4836module.exports = Engine;
4837
4838var World = _dereq_('../body/World');
4839var Sleeping = _dereq_('./Sleeping');
4840var Resolver = _dereq_('../collision/Resolver');
4841var Render = _dereq_('../render/Render');
4842var Pairs = _dereq_('../collision/Pairs');
4843var Metrics = _dereq_('./Metrics');
4844var Grid = _dereq_('../collision/Grid');
4845var Events = _dereq_('./Events');
4846var Composite = _dereq_('../body/Composite');
4847var Constraint = _dereq_('../constraint/Constraint');
4848var Common = _dereq_('./Common');
4849var Body = _dereq_('../body/Body');
4850
4851(function() {
4852
4853    /**
4854     * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
4855     * All properties have default values, and many are pre-calculated automatically based on other properties.
4856     * See the properties section below for detailed information on what you can pass via the `options` object.
4857     * @method create
4858     * @param {object} [options]
4859     * @return {engine} engine
4860     */
4861    Engine.create = function(element, options) {
4862        // options may be passed as the first (and only) argument
4863        options = Common.isElement(element) ? options : element;
4864        element = Common.isElement(element) ? element : null;
4865        options = options || {};
4866
4867        if (element || options.render) {
4868            Common.warn('Engine.create: engine.render is deprecated (see docs)');
4869        }
4870
4871        var defaults = {
4872            positionIterations: 6,
4873            velocityIterations: 4,
4874            constraintIterations: 2,
4875            enableSleeping: false,
4876            events: [],
4877            plugin: {},
4878            timing: {
4879                timestamp: 0,
4880                timeScale: 1
4881            },
4882            broadphase: {
4883                controller: Grid
4884            }
4885        };
4886
4887        var engine = Common.extend(defaults, options);
4888
4889        // @deprecated
4890        if (element || engine.render) {
4891            var renderDefaults = {
4892                element: element,
4893                controller: Render
4894            };
4895            
4896            engine.render = Common.extend(renderDefaults, engine.render);
4897        }
4898
4899        // @deprecated
4900        if (engine.render && engine.render.controller) {
4901            engine.render = engine.render.controller.create(engine.render);
4902        }
4903
4904        // @deprecated
4905        if (engine.render) {
4906            engine.render.engine = engine;
4907        }
4908
4909        engine.world = options.world || World.create(engine.world);
4910        engine.pairs = Pairs.create();
4911        engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
4912        engine.metrics = engine.metrics || { extended: false };
4913
4914
4915        return engine;
4916    };
4917
4918    /**
4919     * Moves the simulation forward in time by `delta` ms.
4920     * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
4921     * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
4922     * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
4923     * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
4924     * See the paper on <a href="http://lonesock.net/article/verlet.html">
4924Time Corrected Verlet</a> for more information.
4925     *
4926     * Triggers `beforeUpdate` and `afterUpdate` events.
4927     * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
4928     * @method update
4929     * @param {engine} engine
4930     * @param {number} [delta=16.666]
4931     * @param {number} [correction=1]
4932     */
4933    Engine.update = function(engine, delta, correction) {
4934        delta = delta || 1000 / 60;
4935        correction = correction || 1;
4936
4937        var world = engine.world,
4938            timing = engine.timing,
4939            broadphase = engine.broadphase,
4940            broadphasePairs = [],
4941            i;
4942
4943        // increment timestamp
4944        timing.timestamp += delta * timing.timeScale;
4945
4946        // create an event object
4947        var event = {
4948            timestamp: timing.timestamp
4949        };
4950
4951        Events.trigger(engine, 'beforeUpdate', event);
4952
4953        // get lists of all bodies and constraints, no matter what composites they are in
4954        var allBodies = Composite.allBodies(world),
4955            allConstraints = Composite.allConstraints(world);
4956
4957
4958        // if sleeping enabled, call the sleeping controller
4959        if (engine.enableSleeping)
4960            Sleeping.update(allBodies, timing.timeScale);
4961
4962        // applies gravity to all bodies
4963        Engine._bodiesApplyGravity(allBodies, world.gravity);
4964
4965        // update all body position and rotation by integration
4966        Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
4967
4968        // update all constraints (first pass)
4969        Constraint.preSolveAll(allBodies);
4970        for (i = 0; i < engine.constraintIterations; i++) {
4971            Constraint.solveAll(allConstraints, timing.timeScale);
4972        }
4973        Constraint.postSolveAll(allBodies);
4974
4975        // broadphase pass: find potential collision pairs
4976        if (broadphase.controller) {
4977            // if world is dirty, we must flush the whole grid
4978            if (world.isModified)
4979                broadphase.controller.clear(broadphase);
4980
4981            // update the grid buckets based on current bodies
4982            broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
4983            broadphasePairs = broadphase.pairsList;
4984        } else {
4985            // if no broadphase set, we just pass all bodies
4986            broadphasePairs = allBodies;
4987        }
4988
4989        // clear all composite modified flags
4990        if (world.isModified) {
4991            Composite.setModified(world, false, false, true);
4992        }
4993
4994        // narrowphase pass: find actual collisions, then create or update collision pairs
4995        var collisions = broadphase.detector(broadphasePairs, engine);
4996
4997        // update collision pairs
4998        var pairs = engine.pairs,
4999            timestamp = timing.timestamp;
5000        Pairs.update(pairs, collisions, timestamp);
5001        Pairs.removeOld(pairs, timestamp);
5002
5003        // wake up bodies involved in collisions
5004        if (engine.enableSleeping)
5005            Sleeping.afterCollisions(pairs.list, timing.timeScale);
5006
5007        // trigger collision events
5008        if (pairs.collisionStart.length > 0)
5009            Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart });
5010
5011        // iteratively resolve position between collisions
5012        Resolver.preSolvePosition(pairs.list);
5013        for (i = 0; i < engine.positionIterations; i++) {
5014            Resolver.solvePosition(pairs.list, timing.timeScale);
5015        }
5016        Resolver.postSolvePosition(allBodies);
5017
5018        // update all constraints (second pass)
5019        Constraint.preSolveAll(allBodies);
5020        for (i = 0; i < engine.constraintIterations; i++) {
5021            Constraint.solveAll(allConstraints, timing.timeScale);
5022        }
5023        Constraint.postSolveAll(allBodies);
5024
5025        // iteratively resolve velocity between collisions
5026        Resolver.preSolveVelocity(pairs.list);
5027        for (i = 0; i < engine.velocityIterations; i++) {
5028            Resolver.solveVelocity(pairs.list, timing.timeScale);
5029        }
5030
5031        // trigger collision events
5032        if (pairs.collisionActive.length > 0)
5033            Events.trigger(engine, 'collisionActive', { pairs: pairs.c
5033ollisionActive });
5034
5035        if (pairs.collisionEnd.length > 0)
5036            Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
5037
5038
5039        // clear force buffers
5040        Engine._bodiesClearForces(allBodies);
5041
5042        Events.trigger(engine, 'afterUpdate', event);
5043
5044        return engine;
5045    };
5046    
5047    /**
5048     * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
5049     * @method merge
5050     * @param {engine} engineA
5051     * @param {engine} engineB
5052     */
5053    Engine.merge = function(engineA, engineB) {
5054        Common.extend(engineA, engineB);
5055        
5056        if (engineB.world) {
5057            engineA.world = engineB.world;
5058
5059            Engine.clear(engineA);
5060
5061            var bodies = Composite.allBodies(engineA.world);
5062
5063            for (var i = 0; i < bodies.length; i++) {
5064                var body = bodies[i];
5065                Sleeping.set(body, false);
5066                body.id = Common.nextId();
5067            }
5068        }
5069    };
5070
5071    /**
5072     * Clears the engine including the world, pairs and broadphase.
5073     * @method clear
5074     * @param {engine} engine
5075     */
5076    Engine.clear = function(engine) {
5077        var world = engine.world;
5078        
5079        Pairs.clear(engine.pairs);
5080
5081        var broadphase = engine.broadphase;
5082        if (broadphase.controller) {
5083            var bodies = Composite.allBodies(world);
5084            broadphase.controller.clear(broadphase);
5085            broadphase.controller.update(broadphase, bodies, engine, true);
5086        }
5087    };
5088
5089    /**
5090     * Zeroes the `body.force` and `body.torque` force buffers.
5091     * @method _bodiesClearForces
5092     * @private
5093     * @param {body[]} bodies
5094     */
5095    Engine._bodiesClearForces = function(bodies) {
5096        for (var i = 0; i < bodies.length; i++) {
5097            var body = bodies[i];
5098
5099            // reset force buffers
5100            body.force.x = 0;
5101            body.force.y = 0;
5102            body.torque = 0;
5103        }
5104    };
5105
5106    /**
5107     * Applys a mass dependant force to all given bodies.
5108     * @method _bodiesApplyGravity
5109     * @private
5110     * @param {body[]} bodies
5111     * @param {vector} gravity
5112     */
5113    Engine._bodiesApplyGravity = function(bodies, gravity) {
5114        var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;
5115
5116        if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
5117            return;
5118        }
5119        
5120        for (var i = 0; i < bodies.length; i++) {
5121            var body = bodies[i];
5122
5123            if (body.isStatic || body.isSleeping)
5124                continue;
5125
5126            // apply gravity
5127            body.force.y += body.mass * gravity.y * gravityScale;
5128            body.force.x += body.mass * gravity.x * gravityScale;
5129        }
5130    };
5131
5132    /**
5133     * Applys `Body.update` to all given `bodies`.
5134     * @method _bodiesUpdate
5135     * @private
5136     * @param {body[]} bodies
5137     * @param {number} deltaTime 
5138     * The amount of time elapsed between updates
5139     * @param {number} timeScale
5140     * @param {number} correction 
5141     * The Verlet correction factor (deltaTime / lastDeltaTime)
5142     * @param {bounds} worldBounds
5143     */
5144    Engine._bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) {
5145        for (var i = 0; i < bodies.length; i++) {
5146            var body = bodies[i];
5147
5148            if (body.isStatic || body.isSleeping)
5149                continue;
5150
5151            Body.update(body, deltaTime, timeScale, correction);
5152        }
5153    };
5154
5155    /**
5156     * An alias for `Runner.run`, see `Matter.Runner` for more information.
5157     * @method run
5158     * @param {engine} engine
5159     */
5160
5161    /**
5162    * Fired just before an update
5163    *
5164    * @event beforeUpdate
5165    * @param {} event An event object
5166    * @param {number} event.timestamp The engine.timing.timestamp of the event
5167    * @param {} event.source The source object of the event
5168    * @param {} event.name The name of the event
5169    */
5170
5171    /**
5172    * Fired after engine update and all collision events
5173    *
5174    * @event afterUpdate
5175    * @param {} event An event object
5176    * @param {number} event.timestamp The engine.timing.timestamp of the event
5177    * @param {} event.source The source object of the event
5178    * @param {} event.name The name of the event
5179    */
5180
5181    /**
5182    * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
5183    *
5184    * @event collisionStart
5185    * @param {} event An event object
5186    * @param {} event.pairs List of affected pairs
5187    * @param {number} event.timestamp The engine.timing.timestamp of the event
5188    * @param {} event.source The source object of the event
5189    * @param {} event.name The name of the event
5190    */
5191
5192    /**
5193    * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
5194    *
5195    * @event collisionActive
5196    * @param {} event An event object
5197    * @param {} event.pairs List of affected pairs
5198    * @param {number} event.timestamp The engine.timing.timestamp of the event
5199    * @param {} event.source The source object of the event
5200    * @param {} event.name The name of the event
5201    */
5202
5203    /**
5204    * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
5205    *
5206    * @event collisionEnd
5207    * @param {} event An event object
5208    * @param {} event.pairs List of affected pairs
5209    * @param {number} event.timestamp The engine.timing.timestamp of the event
5210    * @param {} event.source The source object of the event
5211    * @param {} event.name The name of the event
5212    */
5213
5214    /*
5215    *
5216    *  Properties Documentation
5217    *
5218    */
5219
5220    /**
5221     * An integer `Number` that specifies the number of position iterations to perform each update.
5222     * The higher the value, the higher quality the simulation will be at the expense of performance.
5223     *
5224     * @property positionIterations
5225     * @type number
5226     * @default 6
5227     */
5228
5229    /**
5230     * An integer `Number` that specifies the number of velocity iterations to perform each update.
5231     * The higher the value, the higher quality the simulation will be at the expense of performance.
5232     *
5233     * @property velocityIterations
5234     * @type number
5235     * @default 4
5236     */
5237
5238    /**
5239     * An integer `Number` that specifies the number of constraint iterations to perform each update.
5240     * The higher the value, the higher quality the simulation will be at the expense of performance.
5241     * The default value of `2` is usually very adequate.
5242     *
5243     * @property constraintIterations
5244     * @type number
5245     * @default 2
5246     */
5247
5248    /**
5249     * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module.
5250     * Sleeping can improve stability and performance, but often at the expense of accuracy.
5251     *
5252     * @property enableSleeping
5253     * @type boolean
5254     * @default false
5255     */
5256
5257    /**
5258     * An `Object` containing properties regarding the timing systems of the engine. 
5259     *
5260     * @property timing
5261     * @type object
5262     */
5263
5264    /**
5265     * A `Number` that specifies the global scaling factor of time for all bodies.
5266     * A value of `0` freezes the simulation.
5267     * A value of `0.1` gives a slow-motion effect.
5268     * A value of `1.2` gives a speed-up effect.
5269     *
5270     * @property timing.timeScale
5271     * @type number
5272     * @default 1
5273     */
5274
5275    /**
5276     * A `Number` that specifies the current simulation-time in milliseconds starting from `0`. 
5277     * It is incremented on every `Engine.update` by the given `delta` argument. 
5278     *
5279     * @property timing.timestamp
5280     * @type number
5281     * @default 0
5282     */
5283
5284    /**
5285     * An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
5286     * One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
5287     *
5288     * A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
5289     * It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
5290     *
5291     * @property render
5292     * @type render
5293     * @deprecated see Demo.js for an example of creating a renderer
5294     * @default a Matter.Render instance
5295     */
5296
5297    /**
5298     * An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
5299     *
5300     * @property broadphase
5301     * @type grid
5302     * @default a Matter.Grid instance
5303     */
5304
5305    /**
5306     * A `World` composite object that will contain all simulated bodies and constraints.
5307     *
5308     * @property world
5309     * @type world
5310     * @default a Matter.World instance
5311     */
5312
5313    /**
5314     * An object reserved for storing plugin-specific properties.
5315     *
5316     * @property plugin
5317     * @type {}
5318     */
5319
5320})();
5321
5322},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Grid":6,"../collision/Pairs":8,"../collision/Resolver":10,"../constraint/Constraint":12,"../render/Render":31,"./Common":14,"./Events":16,"./Metrics":18,"./Sleeping":22}],16:[function(_dereq_,module,exports){
5323/**
5324* The `Matter.Events` module contains methods to fire and listen to events on other objects.
5325*
5326* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
5327*
5328* @class Events
5329*/
5330
5331var Events = {};
5332
5333module.exports = Events;
5334
5335var Common = _dereq_('./Common');
5336
5337(function() {
5338
5339    /**
5340     * Subscribes a callback function to the given object's `eventName`.
5341     * @method on
5342     * @param {} object
5343     * @param {string} eventNames
5344     * @param {function} callback
5345     */
5346    Events.on = function(object, eventNames, callback) {
5347        var names = eventNames.split(' '),
5348            name;
5349
5350        for (var i = 0; i < names.length; i++) {
5351            name = names[i];
5352            object.events = object.events || {};
5353            object.events[name] = object.events[name] || [];
5354            object.events[name].push(callback);
5355        }
5356
5357        return callback;
5358    };
5359
5360    /**
5361     * Removes the given event callback. If no callback, clears all callbacks in `eventNames`. If no `eventNames`, clears all events.
5362     * @method off
5363     * @param {} object
5364     * @param {string} eventNames
5365     * @param {function} callback
5366     */
5367    Events.off = function(object, eventNames, callback) {
5368        if (!eventNames) {
5369            object.events = {};
5370            return;
5371        }
5372
5373        // handle Events.off(object, callback)
5374        if (typeof eventNames === 'function') {
5375            callback = eventNames;
5376            eventNames = Common.keys(object.events).join(' ');
5377        }
5378
5379        var names = eventNames.split(' ');
5380
5381        for (var i = 0; i < names.length; i++) {
5382            var callbacks = object.events[names[i]],
5383                newCallbacks = [];
5384
5385            if (callback && callbacks) {
5386                for (var j = 0; j < callbacks.length; j++) {
5387                    if (callbacks[j] !== callback)
5388                        newCallbacks.push(callbacks[j]);
5389                }
5390            }
5391
5392            object.events[names[i]] = newCallbacks;
5393        }
5394    };
5395
5396    /**
5397     * Fires all the callbacks subscribed to the given object's `eventName`, in the order they subscribed, if any.
5398     * @method trigger
5399     * @param {} object
5400     * @param {string} eventNames
5401     * @param {} event
5402     */
5403    Events.trigger = function(object, eventNames, event) {
5404        var names,
5405            name,
5406            callbacks,
5407            eventClone;
5408
5409        if (object.events) {
5410            if (!event)
5411                event = {};
5412
5413            names = eventNames.split(' ');
5414
5415            for (var i = 0; i < names.length; i++) {
5416                name = names[i];
5417                callbacks = object.events[name];
5418
5419                if (callbacks) {
5420                    eventClone = Common.clone(event, false);
5421                    eventClone.name = name;
5422                    eventClone.source = object;
5423
5424                    for (var j = 0; j < callbacks.length; j++) {
5425                        callbacks[j].apply(object, [eventClone]);
5426                    }
5427                }
5428            }
5429        }
5430    };
5431
5432})();
5433
5434},{"./Common":14}],17:[function(_dereq_,module,exports){
5435/**
5436* The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library.
5437*
5438* @class Matter
5439*/
5440
5441var Matter = {};
5442
5443module.exports = Matter;
5444
5445var Plugin = _dereq_('./Plugin');
5446var Common = _dereq_('./Common');
5447
5448(function() {
5449
5450    /**
5451     * The library name.
5452     * @property name
5453     * @readOnly
5454     * @type {String}
5455     */
5456    Matter.name = 'matter-js';
5457
5458    /**
5459     * The library version.
5460     * @property version
5461     * @readOnly
5462     * @type {String}
5463     */
5464    Matter.version = '0.14.2';
5465
5466    /**
5467     * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
5468     * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`.
5469     * @property uses
5470     * @type {Array}
5471     */
5472    Matter.uses = [];
5473
5474    /**
5475     * The plugins that have been installed through `Matter.Plugin.install`. Read only.
5476     * @property used
5477     * @readOnly
5478     * @type {Array}
5479     */
5480    Matter.used = [];
5481
5482    /**
5483     * Installs the given plugins on the `Matter` namespace.
5484     * This is a short-hand for `Plugin.use`, see it for more information.
5485     * Call this function once at the start of your code, with all of the plugins you wish to install as arguments.
5486     * Avoid calling this function multiple times unless you intend to manually control installation order.
5487     * @method use
5488     * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument).
5489     */
5490    Matter.use = function() {
5491        Plugin.use(Matter, Array.prototype.slice.call(arguments));
5492    };
5493
5494    /**
5495     * Chains a function to excute before the original function on the given `path` relative to `Matter`.
5496     * See also docs for `Common.chain`.
5497     * @method before
5498     * @param {string} path The path relative to `Matter`
5499     * @param {function} func The function to chain before the original
5500     * @return {function} The chained function that replaced the original
5501     */
5502    Matter.before = function(path, func) {
5503        path = path.replace(/^Matter./, '');
5504        return Common.chainPathBefore(Matter, path, func);
5505    };
5506
5507    /**
5508     * Chains a function to excute after the original function on the given `path` relative to `Matter`.
5509     * See also docs for `Common.chain`.
5510     * @method after
5511     * @param {string} path The path relative to `Matter`
5512     * @param {function} func The function to chain after the original
5513     * @return {function} The chained function that replaced the original
5514     */
5515    Matter.after = function(path, func) {
5516        path = path.replace(/^Matter./, '');
5517        return Common.chainPathAfter(Matter, path, func);
5518    };
5519
5520})();
5521
5522},{"./Common":14,"./Plugin":20}],18:[function(_dereq_,module,exports){
5523
5524},{"../body/Composite":2,"./Common":14}],19:[function(_dereq_,module,exports){
5525/**
5526* The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs.
5527*
5528* @class Mouse
5529*/
5530
5531var Mouse = {};
5532
5533module.exports = Mouse;
5534
5535var Common = _dereq_('../core/Common');
5536
5537(function() {
5538
5539    /**
5540     * Creates a mouse input.
5541     * @method create
5542     * @param {HTMLElement} element
5543     * @return {mouse} A new mouse
5544     */
5545    Mouse.create = function(element) {
5546        var mouse = {};
5547
5548        if (!element) {
5549            Common.log('Mouse.create: element was undefined, defaulting to document.body', 'warn');
5550        }
5551        
5552        mouse.element = element || document.body;
5553        mouse.absolute = { x: 0, y: 0 };
5554        mouse.position = { x: 0, y: 0 };
5555        mouse.mousedownPosition = { x: 0, y: 0 };
5556        mouse.mouseupPosition = { x: 0, y: 0 };
5557        mouse.offset = { x: 0, y: 0 };
5558        mouse.scale = { x: 1, y: 1 };
5559        mouse.wheelDelta = 0;
5560        mouse.button = -1;
5561        mouse.pixelRatio = mouse.element.getAttribute('data-pixel-ratio') || 1;
5562
5563        mouse.sourceEvents = {
5564            mousemove: null,
5565            mousedown: null,
5566            mouseup: null,
5567            mousewheel: null
5568        };
5569        
5570        mouse.mousemove = function(event) { 
5571            var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
5572                touches = event.changedTouches;
5573
5574            if (touches) {
5575                mouse.button = 0;
5576                event.preventDefault();
5577            }
5578
5579            mouse.absolute.x = position.x;
5580            mouse.absolute.y = position.y;
5581            mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
5582            mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
5583            mouse.sourceEvents.mousemove = event;
5584        };
5585        
5586        mouse.mousedown = function(event) {
5587            var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
5588                touches = event.changedTouches;
5589
5590            if (touches) {
5591                mouse.button = 0;
5592                event.preventDefault();
5593            } else {
5594                mouse.button = event.button;
5595            }
5596
5597            mouse.absolute.x = position.x;
5598            mouse.absolute.y = position.y;
5599            mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
5600            mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
5601            mouse.mousedownPosition.x = mouse.position.x;
5602            mouse.mousedownPosition.y = mouse.position.y;
5603            mouse.sourceEvents.mousedown = event;
5604        };
5605        
5606        mouse.mouseup = function(event) {
5607            var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
5608                touches = event.changedTouches;
5609
5610            if (touches) {
5611                event.preventDefault();
5612            }
5613            
5614            mouse.button = -1;
5615            mouse.absolute.x = position.x;
5616            mouse.absolute.y = position.y;
5617            mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
5618            mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
5619            mouse.mouseupPosition.x = mouse.position.x;
5620            mouse.mouseupPosition.y = mouse.position.y;
5621            mouse.sourceEvents.mouseup = event;
5622        };
5623
5624        mouse.mousewheel = function(event) {
5625            mouse.wheelDelta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail));
5626            event.preventDefault();
5627        };
5628
5629        Mouse.setElement(mouse, mouse.element);
5630
5631        return mouse;
5632    };
5633
5634    /**
5635     * Sets the element the mouse is bound to (and relative to).
5636     * @method setElement
5637     * @param {mouse} mouse
5638     * @param {HTMLElement} element
5639     */
5640    Mouse.setElement = function(mouse, element) {
5641        mouse.element = element;
5642
5643        element.addEventListener('mousemove', mouse.mousemove);
5644        element.addEventListener('mousedown', mouse.mousedown);
5645        element.addEventListener('mouseup', mouse.mouseup);
5646        
5647        element.addEventListener('mousewheel', mouse.mousewheel);
5648        element.addEventListener('DOMMouseScroll', mouse.mousewheel);
5649
5650        element.addEventListener('touchmove', mouse.mousemove);
vendor: 2,914 bytes, lines 5651-5738
5651        element.addEventListener('touchstart', mouse.mousedown);
5652        element.addEventListener('touchend', mouse.mouseup);
5653    };
5654
5655    /**
5656     * Clears all captured source events.
5657     * @method clearSourceEvents
5658     * @param {mouse} mouse
5659     */
5660    Mouse.clearSourceEvents = function(mouse) {
5661        mouse.sourceEvents.mousemove = null;
5662        mouse.sourceEvents.mousedown = null;
5663        mouse.sourceEvents.mouseup = null;
5664        mouse.sourceEvents.mousewheel = null;
5665        mouse.wheelDelta = 0;
5666    };
5667
5668    /**
5669     * Sets the mouse position offset.
5670     * @method setOffset
5671     * @param {mouse} mouse
5672     * @param {vector} offset
5673     */
5674    Mouse.setOffset = function(mouse, offset) {
5675        mouse.offset.x = offset.x;
5676        mouse.offset.y = offset.y;
5677        mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
5678        mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
5679    };
5680
5681    /**
5682     * Sets the mouse position scale.
5683     * @method setScale
5684     * @param {mouse} mouse
5685     * @param {vector} scale
5686     */
5687    Mouse.setScale = function(mouse, scale) {
5688        mouse.scale.x = scale.x;
5689        mouse.scale.y = scale.y;
5690        mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
5691        mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
5692    };
5693    
5694    /**
5695     * Gets the mouse position relative to an element given a screen pixel ratio.
5696     * @method _getRelativeMousePosition
5697     * @private
5698     * @param {} event
5699     * @param {} element
5700     * @param {number} pixelRatio
5701     * @return {}
5702     */
5703    Mouse._getRelativeMousePosition = function(event, element, pixelRatio) {
5704        var elementBounds = element.getBoundingClientRect(),
5705            rootNode = (document.documentElement || document.body.parentNode || document.body),
5706            scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : rootNode.scrollLeft,
5707            scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : rootNode.scrollTop,
5708            touches = event.changedTouches,
5709            x, y;
5710        
5711        if (touches) {
5712            x = touches[0].pageX - elementBounds.left - scrollX;
5713            y = touches[0].pageY - elementBounds.top - scrollY;
5714        } else {
5715            x = event.pageX - elementBounds.left - scrollX;
5716            y = event.pageY - elementBounds.top - scrollY;
5717        }
5718
5719        return { 
5720            x: x / (element.clientWidth / (element.width || element.clientWidth) * pixelRatio),
5721            y: y / (element.clientHeight / (element.height || element.clientHeight) * pixelRatio)
5722        };
5723    };
5724
5725})();
5726
5727},{"../core/Common":14}],20:[function(_dereq_,module,exports){
5728/**
5729* The `Matter.Plugin` module contains functions for registering and installing plugins on modules.
5730*
5731* @class Plugin
5732*/
5733
5734var Plugin = {};
5735
5736module.exports = Plugin;
5737
5738var Common = _dereq_('./Common'
vendor: 9,483 bytes, lines 5738-5970
5738);
5739
5740(function() {
5741
5742    Plugin._registry = {};
5743
5744    /**
5745     * Registers a plugin object so it can be resolved later by name.
5746     * @method register
5747     * @param plugin {} The plugin to register.
5748     * @return {object} The plugin.
5749     */
5750    Plugin.register = function(plugin) {
5751        if (!Plugin.isPlugin(plugin)) {
5752            Common.warn('Plugin.register:', Plugin.toString(plugin), 'does not implement all required fields.');
5753        }
5754
5755        if (plugin.name in Plugin._registry) {
5756            var registered = Plugin._registry[plugin.name],
5757                pluginVersion = Plugin.versionParse(plugin.version).number,
5758                registeredVersion = Plugin.versionParse(registered.version).number;
5759
5760            if (pluginVersion > registeredVersion) {
5761                Common.warn('Plugin.register:', Plugin.toString(registered), 'was upgraded to', Plugin.toString(plugin));
5762                Plugin._registry[plugin.name] = plugin;
5763            } else if (pluginVersion < registeredVersion) {
5764                Common.warn('Plugin.register:', Plugin.toString(registered), 'can not be downgraded to', Plugin.toString(plugin));
5765            } else if (plugin !== registered) {
5766                Common.warn('Plugin.register:', Plugin.toString(plugin), 'is already registered to different plugin object');
5767            }
5768        } else {
5769            Plugin._registry[plugin.name] = plugin;
5770        }
5771
5772        return plugin;
5773    };
5774
5775    /**
5776     * Resolves a dependency to a plugin object from the registry if it exists. 
5777     * The `dependency` may contain a version, but only the name matters when resolving.
5778     * @method resolve
5779     * @param dependency {string} The dependency.
5780     * @return {object} The plugin if resolved, otherwise `undefined`.
5781     */
5782    Plugin.resolve = function(dependency) {
5783        return Plugin._registry[Plugin.dependencyParse(dependency).name];
5784    };
5785
5786    /**
5787     * Returns a pretty printed plugin name and version.
5788     * @method toString
5789     * @param plugin {} The plugin.
5790     * @return {string} Pretty printed plugin name and version.
5791     */
5792    Plugin.toString = function(plugin) {
5793        return typeof plugin === 'string' ? plugin : (plugin.name || 'anonymous') + '@' + (plugin.version || plugin.range || '0.0.0');
5794    };
5795
5796    /**
5797     * Returns `true` if the object meets the minimum standard to be considered a plugin.
5798     * This means it must define the following properties:
5799     * - `name`
5800     * - `version`
5801     * - `install`
5802     * @method isPlugin
5803     * @param obj {} The obj to test.
5804     * @return {boolean} `true` if the object can be considered a plugin otherwise `false`.
5805     */
5806    Plugin.isPlugin = function(obj) {
5807        return obj && obj.name && obj.version && obj.install;
5808    };
5809
5810    /**
5811     * Returns `true` if a plugin with the given `name` been installed on `module`.
5812     * @method isUsed
5813     * @param module {} The module.
5814     * @param name {string} The plugin name.
5815     * @return {boolean} `true` if a plugin with the given `name` been installed on `module`, otherwise `false`.
5816     */
5817    Plugin.isUsed = function(module, name) {
5818        return module.used.indexOf(name) > -1;
5819    };
5820
5821    /**
5822     * Returns `true` if `plugin.for` is applicable to `module` by comparing against `module.name` and `module.version`.
5823     * If `plugin.for` is not specified then it is assumed to be applicable.
5824     * The value of `plugin.for` is a string of the format `'module-name'` or `'module-name@version'`.
5825     * @method isFor
5826     * @param plugin {} The plugin.
5827     * @param module {} The module.
5828     * @return {boolean} `true` if `plugin.for` is applicable to `module`, otherwise `false`.
5829     */
5830    Plugin.isFor = function(plugin, module) {
5831        var parsed = plugin.for && Plugin.dependencyParse(plugin.for);
5832        return !plugin.for || (module.name === parsed.name && Plugin.versionSatisfies(module.version, parsed.range));
5833    };
5834
5835    /**
5836     * Installs the plugins by calling `plugin.install` on each plugin specified in `plugins` if passed, otherwise `module.uses`.
5837     * For installing plugins on `Matter` see the convenience function `Matter.use`.
5838     * Plugins may be specified either by their name or a reference to the plugin object.
5839     * Plugins themselves may specify further dependencies, but each plugin is installed only once.
5840     * Order is important, a topological sort is performed to find the best resulting order of installation.
5841     * This sorting attempts to satisfy every dependency's requested ordering, but may not be exact in all cases.
5842     * This function logs the resulting status of each dependency in the console, along with any warnings.
5843     * - A green tick ✅ indicates a dependency was resolved and installed.
5844     * - An orange diamond 🔶 indicates a dependency was resolved but a warning was thrown for it or one if its dependencies.
5845     * - A red cross ❌ indicates a dependency could not be resolved.
5846     * Avoid calling this function multiple times on the same module unless you intend to manually control installation order.
5847     * @method use
5848     * @param module {} The module install plugins on.
5849     * @param [plugins=module.uses] {} The plugins to install on module (optional, defaults to `module.uses`).
5850     */
5851    Plugin.use = function(module, plugins) {
5852        module.uses = (module.uses || []).concat(plugins || []);
5853
5854        if (module.uses.length === 0) {
5855            Common.warn('Plugin.use:', Plugin.toString(module), 'does not specify any dependencies to install.');
5856            return;
5857        }
5858
5859        var dependencies = Plugin.dependencies(module),
5860            sortedDependencies = Common.topologicalSort(dependencies),
5861            status = [];
5862
5863        for (var i = 0; i < sortedDependencies.length; i += 1) {
5864            if (sortedDependencies[i] === module.name) {
5865                continue;
5866            }
5867
5868            var plugin = Plugin.resolve(sortedDependencies[i]);
5869
5870            if (!plugin) {
5871                status.push('❌ ' + sortedDependencies[i]);
5872                continue;
5873            }
5874
5875            if (Plugin.isUsed(module, plugin.name)) {
5876                continue;
5877            }
5878
5879            if (!Plugin.isFor(plugin, module)) {
5880                Common.warn('Plugin.use:', Plugin.toString(plugin), 'is for', plugin.for, 'but installed on', Plugin.toString(module) + '.');
5881                plugin._warned = true;
5882            }
5883
5884            if (plugin.install) {
5885                plugin.install(module);
5886            } else {
5887                Common.warn('Plugin.use:', Plugin.toString(plugin), 'does not specify an install function.');
5888                plugin._warned = true;
5889            }
5890
5891            if (plugin._warned) {
5892                status.push('🔶 ' + Plugin.toString(plugin));
5893                delete plugin._warned;
5894            } else {
5895                status.push('✅ ' + Plugin.toString(plugin));
5896            }
5897
5898            module.used.push(plugin.name);
5899        }
5900
5901        if (status.length > 0) {
5902            Common.info(status.join('  '));
5903        }
5904    };
5905
5906    /**
5907     * Recursively finds all of a module's dependencies and returns a flat dependency graph.
5908     * @method dependencies
5909     * @param module {} The module.
5910     * @return {object} A dependency graph.
5911     */
5912    Plugin.dependencies = function(module, tracked) {
5913        var parsedBase = Plugin.dependencyParse(module),
5914            name = parsedBase.name;
5915
5916        tracked = tracked || {};
5917
5918        if (name in tracked) {
5919            return;
5920        }
5921
5922        module = Plugin.resolve(module) || module;
5923
5924        tracked[name] = Common.map(module.uses || [], function(dependency) {
5925            if (Plugin.isPlugin(dependency)) {
5926                Plugin.register(dependency);
5927            }
5928
5929            var parsed = Plugin.dependencyParse(dependency),
5930                resolved = Plugin.resolve(dependency);
5931
5932            if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) {
5933                Common.warn(
5934                    'Plugin.dependencies:', Plugin.toString(resolved), 'does not satisfy',
5935                    Plugin.toString(parsed), 'used by', Plugin.toString(parsedBase) + '.'
5936                );
5937
5938                resolved._warned = true;
5939                module._warned = true;
5940            } else if (!resolved) {
5941                Common.warn(
5942                    'Plugin.dependencies:', Plugin.toString(dependency), 'used by',
5943                    Plugin.toString(parsedBase), 'could not be resolved.'
5944                );
5945
5946                module._warned = true;
5947            }
5948
5949            return parsed.name;
5950        });
5951
5952        for (var i = 0; i < tracked[name].length; i += 1) {
5953            Plugin.dependencies(tracked[name][i], tracked);
5954        }
5955
5956        return tracked;
5957    };
5958
5959    /**
5960     * Parses a dependency string into its components.
5961     * The `dependency` is a string of the format `'module-name'` or `'module-name@version'`.
5962     * See documentation for `Plugin.versionParse` for a description of the format.
5963     * This function can also handle dependencies that are already resolved (e.g. a module object).
5964     * @method dependencyParse
5965     * @param dependency {string} The dependency of the format `'module-name'` or `'module-name@version'`.
5966     * @return {object} The dependency parsed into its components.
5967     */
5968    Plugin.dependencyParse = function(dependency) {
5969        if (Common.isString(dependency)) {
5970            var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-
5970]+)?))?$/;
5971
5972            if (!pattern.test(dependency)) {
5973                Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.');
5974            }
5975
5976            return {
5977                name: dependency.split('@')[0],
5978                range: dependency.split('@')[1] || '*'
5979            };
5980        }
5981
5982        return {
5983            name: dependency.name,
5984            range: dependency.range || dependency.version
5985        };
5986    };
5987
5988    /**
5989     * Parses a version string into its components.  
5990     * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)).
5991     * Versions may optionally have a prerelease tag in the format `x.y.z-alpha`.
5992     * Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax).
5993     * Only the following range types are supported:
5994     * - Tilde ranges e.g. `~1.2.3`
5995     * - Caret ranges e.g. `^1.2.3`
5996     * - Exact version e.g. `1.2.3`
5997     * - Any version `*`
5998     * @method versionParse
5999     * @param range {string} The version string.
6000     * @return {object} The version range parsed into its components.
6001     */
6002    Plugin.versionParse = function(range) {
6003        var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/;
6004
6005        if (!pattern.test(range)) {
6006            Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
6007        }
6008
6009        var identifiers = range.split('-');
6010        range = identifiers[0];
6011
6012        var isRange = isNaN(Number(range[0])),
6013            version = isRange ? range.substr(1) : range,
6014            parts = Common.map(version.split('.'), function(part) {
6015                return Number(part);
6016            });
6017
6018        return {
6019            isRange: isRange,
6020            version: version,
6021            range: range,
6022            operator: isRange ? range[0] : '',
6023            parts: parts,
6024            prerelease: identifiers[1],
6025            number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2]
6026        };
6027    };
6028
6029    /**
6030     * Returns `true` if `version` satisfies the given `range`.
6031     * See documentation for `Plugin.versionParse` for a description of the format.
6032     * If a version or range is not specified, then any version (`*`) is assumed to satisfy.
6033     * @method versionSatisfies
6034     * @param version {string} The version string.
6035     * @param range {string} The range string.
6036     * @return {boolean} `true` if `version` satisfies `range`, otherwise `false`.
6037     */
6038    Plugin.versionSatisfies = function(version, range) {
6039        range = range || '*';
6040
6041        var rangeParsed = Plugin.versionParse(range),
6042            rangeParts = rangeParsed.parts,
6043            versionParsed = Plugin.versionParse(version),
6044            versionParts = versionParsed.parts;
6045
6046        if (rangeParsed.isRange) {
6047            if (rangeParsed.operator === '*' || version === '*') {
6048                return true;
6049            }
6050
6051            if (rangeParsed.operator === '~') {
6052                return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
6053            }
6054
6055            if (rangeParsed.operator === '^') {
6056                if (rangeParts[0] > 0) {
6057                    return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number;
6058                }
6059
6060                if (rangeParts[1] > 0) {
6061                    return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
6062                }
6063
6064                return versionParts[2] === rangeParts[2];
6065            }
6066        }
6067
6068        return version === range || version === '*';
6069    };
6070
6071})();
6072
6073},{"./Common":14}],21:[function(_dereq_,module,exports){
6074/**
6075* The `Matter.Runner` module is an optional utility which provides a game loop, 
6076* that handles continuously updating a `Matter.Engine` for you within a browser.
6077* It is intended for development and debugging purposes, but may also be suitable for simple games.
6078* If you are using your own game loop instead, then you do not need the `Matter.Runner` module.
6079* Instead just call `Engine.update(engine, delta)` in your own loop.
6080*
6081* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
6082*
6083* @class Runner
6084*/
6085
6086var Runner = {};
6087
6088module.exports = Runner;
6089
6090var Events = _dereq_('./Events');
6091var Engine = _dereq_('./Engine');
6092var Common = _dereq_('./Common');
6093
6094(function() {
6095
6096    var _requestAnimationFrame,
6097        _cancelAnimationFrame;
6098
6099    if (typeof window !== 'undefined') {
6100        _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
6101                                      || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
6102   
6103        _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame 
6104                                      || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
6105    }
6106
6107    if (!_requestAnimationFrame) {
6108        var _frameTimeout;
6109
6110        _requestAnimationFrame = function(callback){ 
6111            _frameTimeout = setTimeout(function() { 
6112                callback(Common.now()); 
6113            }, 1000 / 60);
6114        };
6115
6116        _cancelAnimationFrame = function() {
6117            clearTimeout(_frameTimeout);
6118        };
6119    }
6120
6121    /**
6122     * Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
6123     * @method create
6124     * @param {} options
6125     */
6126    Runner.create = function(options) {
6127        var defaults = {
6128            fps: 60,
6129            correction: 1,
6130            deltaSampleSize: 60,
6131            counterTimestamp: 0,
6132            frameCounter: 0,
6133            deltaHistory: [],
6134            timePrev: null,
6135            timeScalePrev: 1,
6136            frameRequestId: null,
6137            isFixed: false,
6138            enabled: true
6139        };
6140
6141        var runner = Common.extend(defaults, options);
6142
6143        runner.delta = runner.delta || 1000 / runner.fps;
6144        runner.deltaMin = runner.deltaMin || 1000 / runner.fps;
6145        runner.deltaMax = runner.deltaMax || 1000 / (runner.fps * 0.5);
6146        runner.fps = 1000 / runner.delta;
6147
6148        return runner;
6149    };
6150
6151    /**
6152     * Continuously ticks a `Matter.Engine` by calling `Runner.tick` on the `requestAnimationFrame` event.
6153     * @method run
6154     * @param {engine} engine
6155     */
6156    Runner.run = function(runner, engine) {
6157        // create runner if engine is first argument
6158        if (typeof runner.positionIterations !== 'undefined') {
6159            engine = runner;
6160            runner = Runner.create();
6161        }
6162
6163        (function render(time){
6164            runner.frameRequestId = _requestAnimationFrame(render);
6165
6166            if (time && runner.enabled) {
6167                Runner.tick(runner, engine, time);
6168            }
6169        })();
6170
6171        return runner;
6172    };
6173
6174    /**
6175     * A game loop utility that updates the engine and renderer by one step (a 'tick').
6176     * Features delta smoothing, time correction and fixed or dynamic timing.
6177     * Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
6178     * Consider just `Engine.update(engine, delta)` if you're using your own loop.
6179     * @method tick
6180     * @param {runner} runner
6181     * @param {engine} engine
6182     * @param {number} time
6183     */
6184    Runner.tick = function(runner, engine, time) {
6185        var timing = engine.timing,
6186            correction = 1,
6187            delta;
6188
6189        // create an event object
6190        var event = {
6191            timestamp: timing.timestamp
6192        };
6193
6194        Events.trigger(runner, 'beforeTick', event);
6195        Events.trigger(engine, 'beforeTick', event); // @deprecated
6196
6197        if (runner.isFixed) {
6198            // fixed timestep
6199            delta = runner.delta;
6200        } else {
6201            // dynamic timestep based on wall clock between calls
6202            delta = (time - runner.timePrev) || runner.delta;
6203            runner.timePrev = time;
6204
6205            // optimistically filter delta over a few frames, to improve stability
6206            runner.deltaHistory.push(delta);
6207            runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize);
6208            delta = Math.min.apply(null, runner.deltaHistory);
6209            
6210            // limit delta
6211            delta = delta < runner.deltaMin ? runner.deltaMin : delta;
6212            delta = delta > runner.deltaMax ? runner.deltaMax : delta;
6213
6214            // correction for delta
6215            correction = delta / runner.delta;
6216
6217            // update engine timing object
6218            runner.delta = delta;
6219        }
6220
6221        // time correction for time scaling
6222        if (runner.timeScalePrev !== 0)
6223            correction *= timing.timeScale / runner.timeScalePrev;
6224
6225        if (timing.timeScale === 0)
6226            correction = 0;
6227
6228        runner.timeScalePrev = timing.timeScale;
6229        runner.correction = correction;
6230
6231        // fps counter
6232        runner.frameCounter += 1;
6233        if (time - runner.counterTimestamp >= 1000) {
6234            runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000);
6235            runner.counterTimestamp = time;
6236            runner.frameCounter = 0;
6237        }
6238
6239        Events.trigger(runner, 'tick', event);
6240        Events.trigger(engine, 'tick', event); // @deprecated
6241
6242        // if world has been modified, clear the render scene graph
6243        if (engine.world.isModified 
6244            && engine.render
6245            && engine.render.controller
6246            && engine.render.controller.clear) {
6247            engine.render.controller.clear(engine.render); // @deprecated
6248        }
6249
6250        // update
6251        Events.trigger(runner, 'beforeUpdate', event);
6252        Engine.update(engine, delta, correction);
6253        Events.trigger(runner, 'afterUpdate', event);
6254
6255        // render
6256        // @deprecated
6257        if (engine.render && engine.render.controller) {
6258            Events.trigger(runner, 'beforeRender', event);
6259            Events.trigger(engine, 'beforeRender', event); // @deprecated
6260
6261            engine.render.controller.world(engine.render);
6262
6263            Events.trigger(runner, 'afterRender', event);
6264            Events.trigger(engine, 'afterRender', event); // @deprecated
6265        }
6266
6267        Events.trigger(runner, 'afterTick', event);
6268        Events.trigger(engine, 'afterTick', event); // @deprecated
6269    };
6270
6271    /**
6272     * Ends execution of `Runner.run` on the given `runner`, by canceling the animation frame request event loop.
6273     * If you wish to only temporarily pause the engine, see `engine.enabled` instead.
6274     * @method stop
6275     * @param {runner} runner
6276     */
6277    Runner.stop = function(runner) {
6278        _cancelAnimationFrame(runner.frameRequestId);
6279    };
6280
6281    /**
6282     * Alias for `Runner.run`.
6283     * @method start
6284     * @param {runner} runner
6285     * @param {engine} engine
6286     */
6287    Runner.start = function(runner, engine) {
6288        Runner.run(runner, engine);
6289    };
6290
6291    /*
6292    *
6293    *  Events Documentation
6294    *
6295    */
6296
6297    /**
6298    * Fired at the start of a tick, before any updates to the engine or timing
6299    *
6300    * @event beforeTick
6301    * @param {} event An event object
6302    * @param {number} event.timestamp The engine.timing.timestamp of the event
6303    * @param {} event.source The source object of the event
6304    * @param {} event.name The name of the event
6305    */
6306
6307    /**
6308    * Fired after engine timing updated, but just before update
6309    *
6310    * @event tick
6311    * @param {} event An event object
6312    * @param {number} event.timestamp The engine.timing.timestamp of the event
6313    * @param {} event.source The source object of the event
6314    * @param {} event.name The name of the event
6315    */
6316
6317    /**
6318    * Fired at the end of a tick, after engine update and after rendering
6319    *
6320    * @event afterTick
6321    * @param {} event An event object
6322    * @param {number} event.timestamp The engine.timing.timestamp of the event
6323    * @param {} event.source The source object of the event
6324    * @param {} event.name The name of the event
6325    */
6326
6327    /**
6328    * Fired before update
6329    *
6330    * @event beforeUpdate
6331    * @param {} event An event object
6332    * @param {number} event.timestamp The engine.timing.timestamp of the event
6333    * @param {} event.source The source object of the event
6334    * @param {} event.name The name of the event
6335    */
6336
6337    /**
6338    * Fired after update
6339    *
6340    * @event afterUpdate
6341    * @param {} event An event object
6342    * @param {number} event.timestamp The engine.timing.timestamp of the event
6343    * @param {} event.source The source object of the event
6344    * @param {} event.name The name of the event
6345    */
6346
6347    /**
6348    * Fired before rendering
6349    *
6350    * @event beforeRender
6351    * @param {} event An event object
6352    * @param {number} event.timestamp The engine.timing.timestamp of the event
6353    * @param {} event.source The source object of the event
6354    * @param {} event.name The name of the event
6355    * @deprecated
6356    */
6357
6358    /**
6359    * Fired after rendering
6360    *
6361    * @event afterRender
6362    * @param {} event An event object
6363    * @param {number} event.timestamp The engine.timing.timestamp of the event
6364    * @param {} event.source The source object of the event
6365    * @param {} event.name The name of the event
6366    * @deprecated
6367    */
6368
6369    /*
6370    *
6371    *  Properties Documentation
6372    *
6373    */
6374
6375    /**
6376     * A flag that specifies whether the runner is running or not.
6377     *
6378     * @property enabled
6379     * @type boolean
6380     * @default true
6381     */
6382
6383    /**
6384     * A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable).
6385     * If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
6386     * If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
6387     *
6388     * @property isFixed
6389     * @type boolean
6390     * @default false
6391     */
6392
6393    /**
6394     * A `Number` that specifies the time step between updates in milliseconds.
6395     * If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
6396     * If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
6397     *
6398     * @property delta
6399     * @type number
6400     * @default 1000 / 60
6401     */
6402
6403})();
6404
6405},{"./Common":14,"./Engine":15,"./Events":16}],22:[function(_dereq_,module,exports){
6406/**
6407* The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies.
6408*
6409* @class Sleeping
6410*/
6411
6412var Sleeping = {};
6413
6414module.exports = Sleeping;
6415
6416var Events = _dereq_('./Events');
6417
6418(function() {
6419
6420    Sleeping._motionWakeThreshold = 0.18;
6421    Sleeping._motionSleepThreshold = 0.08;
6422    Sleeping._minBias = 0.9;
6423
6424    /**
6425     * Puts bodies to sleep or wakes them up depending on their motion.
6426     * @method update
6427     * @param {body[]} bodies
6428     * @param {number} timeScale
6429     */
6430    Sleeping.update = function(bodies, timeScale) {
6431        var timeFactor = timeScale * timeScale * timeScale;
6432
6433        // update bodies sleeping status
6434        for (var i = 0; i < bodies.length; i++) {
6435            var body = bodies[i],
6436                motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed;
6437
6438            // wake up bodies if they have a force applied
6439            if (body.force.x !== 0 || body.force.y !== 0) {
6440                Sleeping.set(body, false);
6441                continue;
6442            }
6443
6444            var minMotion = Math.min(body.motion, motion),
6445                maxMotion = Math.max(body.motion, motion);
6446        
6447            // biased average motion estimation between frames
6448            body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion;
6449            
6450            if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) {
6451                body.sleepCounter += 1;
6452                
6453                if (body.sleepCounter >= body.sleepThreshold)
6454                    Sleeping.set(body, true);
6455            } else if (body.sleepCounter > 0) {
6456                body.sleepCounter -= 1;
6457            }
6458        }
6459    };
6460
6461    /**
6462     * Given a set of colliding pairs, wakes the sleeping bodies involved.
6463     * @method afterCollisions
6464     * @param {pair[]} pairs
6465     * @param {number} timeScale
6466     */
6467    Sleeping.afterCollisions = function(pairs, timeScale) {
6468        var timeFactor = timeScale * timeScale * timeScale;
6469
6470        // wake up bodies involved in collisions
6471        for (var i = 0; i < pairs.length; i++) {
6472            var pair = pairs[i];
6473            
6474            // don't wake inactive pairs
6475            if (!pair.isActive)
6476                continue;
6477
6478            var collision = pair.collision,
6479                bodyA = collision.bodyA.parent, 
6480                bodyB = collision.bodyB.parent;
6481        
6482            // don't wake if at least one body is static
6483            if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic)
6484                continue;
6485        
6486            if (bodyA.isSleeping || bodyB.isSleeping) {
6487                var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
6488                    movingBody = sleepingBody === bodyA ? bodyB : bodyA;
6489
6490                if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) {
6491                    Sleeping.set(sleepingBody, false);
6492                }
6493            }
6494        }
6495    };
6496  
6497    /**
6498     * Set a body as sleeping or awake.
6499     * @method set
6500     * @param {body} body
6501     * @param {boolean} isSleeping
6502     */
6503    Sleeping.set = function(body, isSleeping) {
6504        var wasSleeping = body.isSleeping;
6505
6506        if (isSleeping) {
6507            body.isSleeping = true;
6508            body.sleepCounter = body.sleepThreshold;
6509
6510            body.positionImpulse.x = 0;
6511            body.positionImpulse.y = 0;
6512
6513            body.positionPrev.x = body.position.x;
6514            body.positionPrev.y = body.position.y;
6515
6516            body.anglePrev = body.angle;
6517            body.speed = 0;
6518            body.angularSpeed = 0;
6519            body.motion = 0;
6520
6521            if (!wasSleeping) {
6522                Events.trigger(body, 'sleepStart');
6523            }
6524        } else {
6525            body.isSleeping = false;
6526            body.sleepCounter = 0;
6527
6528            if (wasSleeping) {
6529                Events.trigger(body, 'sleepEnd');
6530            }
6531        }
6532    };
6533
6534})();
6535
6536},{"./Events":16}],23:[function(_dereq_,module,exports){
6537/**
6538* The `Matter.Bodies` module contains factory methods for creating rigid body models 
6539* with commonly used body configurations (such as rectangles, circles and other polygons).
6540*
6541* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
6542*
6543* @class Bodies
6544*/
6545
6546// TODO: true circle bodies
6547
6548var Bodies = {};
6549
6550module.exports = Bodies;
6551
6552var Vertices = _dereq_('../geometry/Vertices');
6553var Common = _dereq_('../core/Common');
6554var Body = _dereq_('../body/Body');
6555var Bounds = _dereq_('../geometry/Bounds');
6556var Vector = _dereq_('../geometry/Vector');
6557var decomp;
6558
6559(function() {
6560
6561    /**
6562     * Creates a new rigid body model with a rectangle hull. 
6563     * The options parameter is an object that specifies any properties you wish to override the defaults.
6564     * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
6565     * @method rectangle
6566     * @param {number} x
6567     * @param {number} y
6568     * @param {number} width
6569     * @param {number} height
6570     * @param {object} [options]
6571     * @return {body} A new rectangle body
6572     */
6573    Bodies.rectangle = function(x, y, width, height, options) {
6574        options = options || {};
6575
6576        var rectangle = { 
6577            label: 'Rectangle Body',
6578            position: { x: x, y: y },
6579            vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height)
6580        };
6581
6582        if (options.chamfer) {
6583            var chamfer = options.chamfer;
6584            rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius, 
6585                                    chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
6586            delete options.chamfer;
6587        }
6588
6589        return Body.create(Common.extend({}, rectangle, options));
6590    };
6591    
6592    /**
6593     * Creates a new rigid body model with a trapezoid hull. 
6594     * The options parameter is an object that specifies any properties you wish to override the defaults.
6595     * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
6596     * @method trapezoid
6597     * @param {number} x
6598     * @param {number} y
6599     * @param {number} width
6600     * @param {number} height
6601     * @param {number} slope
6602     * @param {object} [options]
6603     * @return {body} A new trapezoid body
6604     */
6605    Bodies.trapezoid = function(x, y, width, height, slope, options) {
6606        options = options || {};
6607
6608        slope *= 0.5;
6609        var roof = (1 - (slope * 2)) * width;
6610        
6611        var x1 = width * slope,
6612            x2 = x1 + roof,
6613            x3 = x2 + x1,
6614            verticesPath;
6615
6616        if (slope < 0.5) {
6617            verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
6618        } else {
6619            verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
6620        }
6621
6622        var trapezoid = { 
6623            label: 'Trapezoid Body',
6624            position: { x: x, y: y },
6625            vertices: Vertices.fromPath(verticesPath)
6626        };
6627
6628        if (options.chamfer) {
6629            var chamfer = options.chamfer;
6630            trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius, 
6631                                    chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
6632            delete options.chamfer;
6633        }
6634
6635        return Body.create(Common.extend({}, trapezoid, options));
6636    };
6637
6638    /**
6639     * Creates a new rigid body model with a circle hull. 
6640     * The options parameter is an object that specifies any properties you wish to override the defaults.
6641     * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
6642     * @method circle
6643     * @param {number} x
6644     * @param {number} y
6645     * @param {number} radius
6646     * @param {object} [options]
6647     * @param {number} [maxSides]
6648     * @return {body} A new circle body
6649     */
6650    Bodies.circle = function(x, y, radius, options, maxSides) {
6651        options = options || {};
6652
6653        var circle = {
6654            label: 'Circle Body',
6655            circleRadius: radius
6656        };
6657        
6658        // approximate circles with polygons until true circles implemented in SAT
6659        maxSides = maxSides || 25;
6660        var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius)));
6661
6662        // optimisation: always use even number of sides (half the number of unique axes)
6663        if (sides % 2 === 1)
6664            sides += 1;
6665
vendor: 42,691 bytes, lines 6666-7939
6666        return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options));
6667    };
6668
6669    /**
6670     * Creates a new rigid body model with a regular polygon hull with the given number of sides. 
6671     * The options parameter is an object that specifies any properties you wish to override the defaults.
6672     * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
6673     * @method polygon
6674     * @param {number} x
6675     * @param {number} y
6676     * @param {number} sides
6677     * @param {number} radius
6678     * @param {object} [options]
6679     * @return {body} A new regular polygon body
6680     */
6681    Bodies.polygon = function(x, y, sides, radius, options) {
6682        options = options || {};
6683
6684        if (sides < 3)
6685            return Bodies.circle(x, y, radius, options);
6686
6687        var theta = 2 * Math.PI / sides,
6688            path = '',
6689            offset = theta * 0.5;
6690
6691        for (var i = 0; i < sides; i += 1) {
6692            var angle = offset + (i * theta),
6693                xx = Math.cos(angle) * radius,
6694                yy = Math.sin(angle) * radius;
6695
6696            path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' ';
6697        }
6698
6699        var polygon = { 
6700            label: 'Polygon Body',
6701            position: { x: x, y: y },
6702            vertices: Vertices.fromPath(path)
6703        };
6704
6705        if (options.chamfer) {
6706            var chamfer = options.chamfer;
6707            polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius, 
6708                                    chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
6709            delete options.chamfer;
6710        }
6711
6712        return Body.create(Common.extend({}, polygon, options));
6713    };
6714
6715    /**
6716     * Creates a body using the supplied vertices (or an array containing multiple sets of vertices).
6717     * If the vertices are convex, they will pass through as supplied.
6718     * Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available.
6719     * Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail).
6720     * By default the decomposition will discard collinear edges (to improve performance).
6721     * It can also optionally discard any parts that have an area less than `minimumArea`.
6722     * If the vertices can not be decomposed, the result will fall back to using the convex hull.
6723     * The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults.
6724     * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
6725     * @method fromVertices
6726     * @param {number} x
6727     * @param {number} y
6728     * @param [[vector]] vertexSets
6729     * @param {object} [options]
6730     * @param {bool} [flagInternal=false]
6731     * @param {number} [removeCollinear=0.01]
6732     * @param {number} [minimumArea=10]
6733     * @return {body}
6734     */
6735    Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
6736        if (!decomp) {
6737            decomp = Common._requireGlobal('decomp', 'poly-decomp');
6738        }
6739
6740        var body,
6741            parts,
6742            isConvex,
6743            vertices,
6744            i,
6745            j,
6746            k,
6747            v,
6748            z;
6749
6750        options = options || {};
6751        parts = [];
6752
6753        flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
6754        removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
6755        minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
6756
6757        if (!decomp) {
6758            Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
6759        }
6760
6761        // ensure vertexSets is an array of arrays
6762        if (!Common.isArray(vertexSets[0])) {
6763            vertexSets = [vertexSets];
6764        }
6765
6766        for (v = 0; v < vertexSets.length; v += 1) {
6767            vertices = vertexSets[v];
6768            isConvex = Vertices.isConvex(vertices);
6769
6770            if (isConvex || !decomp) {
6771                if (isConvex) {
6772                    vertices = Vertices.clockwiseSort(vertices);
6773                } else {
6774                    // fallback to convex hull when decomposition is not possible
6775                    vertices = Vertices.hull(vertices);
6776                }
6777
6778                parts.push({
6779                    position: { x: x, y: y },
6780                    vertices: vertices
6781                });
6782            } else {
6783                // initialise a decomposition
6784                var concave = vertices.map(function(vertex) {
6785                    return [vertex.x, vertex.y];
6786                });
6787
6788                // vertices are concave and simple, we can decompose into parts
6789                decomp.makeCCW(concave);
6790                if (removeCollinear !== false)
6791                    decomp.removeCollinearPoints(concave, removeCollinear);
6792
6793                // use the quick decomposition algorithm (Bayazit)
6794                var decomposed = decomp.quickDecomp(concave);
6795
6796                // for each decomposed chunk
6797                for (i = 0; i < decomposed.length; i++) {
6798                    var chunk = decomposed[i];
6799
6800                    // convert vertices into the correct structure
6801                    var chunkVertices = chunk.map(function(vertices) {
6802                        return {
6803                            x: vertices[0],
6804                            y: vertices[1]
6805                        };
6806                    });
6807
6808                    // skip small chunks
6809                    if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea)
6810                        continue;
6811
6812                    // create a compound part
6813                    parts.push({
6814                        position: Vertices.centre(chunkVertices),
6815                        vertices: chunkVertices
6816                    });
6817                }
6818            }
6819        }
6820
6821        // create body parts
6822        for (i = 0; i < parts.length; i++) {
6823            parts[i] = Body.create(Common.extend(parts[i], options));
6824        }
6825
6826        // flag internal edges (coincident part edges)
6827        if (flagInternal) {
6828            var coincident_max_dist = 5;
6829
6830            for (i = 0; i < parts.length; i++) {
6831                var partA = parts[i];
6832
6833                for (j = i + 1; j < parts.length; j++) {
6834                    var partB = parts[j];
6835
6836                    if (Bounds.overlaps(partA.bounds, partB.bounds)) {
6837                        var pav = partA.vertices,
6838                            pbv = partB.vertices;
6839
6840                        // iterate vertices of both parts
6841                        for (k = 0; k < partA.vertices.length; k++) {
6842                            for (z = 0; z < partB.vertices.length; z++) {
6843                                // find distances between the vertices
6844                                var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])),
6845                                    db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
6846
6847                                // if both vertices are very close, consider the edge concident (internal)
6848                                if (da < coincident_max_dist && db < coincident_max_dist) {
6849                                    pav[k].isInternal = true;
6850                                    pbv[z].isInternal = true;
6851                                }
6852                            }
6853                        }
6854
6855                    }
6856                }
6857            }
6858        }
6859
6860        if (parts.length > 1) {
6861            // create the parent body to be returned, that contains generated compound parts
6862            body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
6863            Body.setPosition(body, { x: x, y: y });
6864
6865            return body;
6866        } else {
6867            return parts[0];
6868        }
6869    };
6870
6871})();
6872
6873},{"../body/Body":1,"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],24:[function(_dereq_,module,exports){
6874/**
6875* The `Matter.Composites` module contains factory methods for creating composite bodies
6876* with commonly used configurations (such as stacks and chains).
6877*
6878* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
6879*
6880* @class Composites
6881*/
6882
6883var Composites = {};
6884
6885module.exports = Composites;
6886
6887var Composite = _dereq_('../body/Composite');
6888var Constraint = _dereq_('../constraint/Constraint');
6889var Common = _dereq_('../core/Common');
6890var Body = _dereq_('../body/Body');
6891var Bodies = _dereq_('./Bodies');
6892
6893(function() {
6894
6895    /**
6896     * Create a new composite containing bodies created in the callback in a grid arrangement.
6897     * This function uses the body's bounds to prevent overlaps.
6898     * @method stack
6899     * @param {number} xx
6900     * @param {number} yy
6901     * @param {number} columns
6902     * @param {number} rows
6903     * @param {number} columnGap
6904     * @param {number} rowGap
6905     * @param {function} callback
6906     * @return {composite} A new composite containing objects created in the callback
6907     */
6908    Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
6909        var stack = Composite.create({ label: 'Stack' }),
6910            x = xx,
6911            y = yy,
6912            lastBody,
6913            i = 0;
6914
6915        for (var row = 0; row < rows; row++) {
6916            var maxHeight = 0;
6917            
6918            for (var column = 0; column < columns; column++) {
6919                var body = callback(x, y, column, row, lastBody, i);
6920                    
6921                if (body) {
6922                    var bodyHeight = body.bounds.max.y - body.bounds.min.y,
6923                        bodyWidth = body.bounds.max.x - body.bounds.min.x; 
6924
6925                    if (bodyHeight > maxHeight)
6926                        maxHeight = bodyHeight;
6927                    
6928                    Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 });
6929
6930                    x = body.bounds.max.x + columnGap;
6931
6932                    Composite.addBody(stack, body);
6933                    
6934                    lastBody = body;
6935                    i += 1;
6936                } else {
6937                    x += columnGap;
6938                }
6939            }
6940            
6941            y += maxHeight + rowGap;
6942            x = xx;
6943        }
6944
6945        return stack;
6946    };
6947    
6948    /**
6949     * Chains all bodies in the given composite together using constraints.
6950     * @method chain
6951     * @param {composite} composite
6952     * @param {number} xOffsetA
6953     * @param {number} yOffsetA
6954     * @param {number} xOffsetB
6955     * @param {number} yOffsetB
6956     * @param {object} options
6957     * @return {composite} A new composite containing objects chained together with constraints
6958     */
6959    Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) {
6960        var bodies = composite.bodies;
6961        
6962        for (var i = 1; i < bodies.length; i++) {
6963            var bodyA = bodies[i - 1],
6964                bodyB = bodies[i],
6965                bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y,
6966                bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, 
6967                bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y,
6968                bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x;
6969        
6970            var defaults = {
6971                bodyA: bodyA,
6972                pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA },
6973                bodyB: bodyB,
6974                pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB }
6975            };
6976            
6977            var constraint = Common.extend(defaults, options);
6978        
6979            Composite.addConstraint(composite, Constraint.create(constraint));
6980        }
6981
6982        composite.label += ' Chain';
6983        
6984        return composite;
6985    };
6986
6987    /**
6988     * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces.
6989     * @method mesh
6990     * @param {composite} composite
6991     * @param {number} columns
6992     * @param {number} rows
6993     * @param {boolean} crossBrace
6994     * @param {object} options
6995     * @return {composite} The composite containing objects meshed together with constraints
6996     */
6997    Composites.mesh = function(composite, columns, rows, crossBrace, options) {
6998        var bodies = composite.bodies,
6999            row,
7000            col,
7001            bodyA,
7002            bodyB,
7003            bodyC;
7004        
7005        for (row = 0; row < rows; row++) {
7006            for (col = 1; col < columns; col++) {
7007                bodyA = bodies[(col - 1) + (row * columns)];
7008                bodyB = bodies[col + (row * columns)];
7009                Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
7010            }
7011
7012            if (row > 0) {
7013                for (col = 0; col < columns; col++) {
7014                    bodyA = bodies[col + ((row - 1) * columns)];
7015                    bodyB = bodies[col + (row * columns)];
7016                    Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
7017
7018                    if (crossBrace && col > 0) {
7019                        bodyC = bodies[(col - 1) + ((row - 1) * columns)];
7020                        Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
7021                    }
7022
7023                    if (crossBrace && col < columns - 1) {
7024                        bodyC = bodies[(col + 1) + ((row - 1) * columns)];
7025                        Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
7026                    }
7027                }
7028            }
7029        }
7030
7031        composite.label += ' Mesh';
7032        
7033        return composite;
7034    };
7035    
7036    /**
7037     * Create a new composite containing bodies created in the callback in a pyramid arrangement.
7038     * This function uses the body's bounds to prevent overlaps.
7039     * @method pyramid
7040     * @param {number} xx
7041     * @param {number} yy
7042     * @param {number} columns
7043     * @param {number} rows
7044     * @param {number} columnGap
7045     * @param {number} rowGap
7046     * @param {function} callback
7047     * @return {composite} A new composite containing objects created in the callback
7048     */
7049    Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
7050        return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) {
7051            var actualRows = Math.min(rows, Math.ceil(columns / 2)),
7052                lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0;
7053            
7054            if (row > actualRows)
7055                return;
7056            
7057            // reverse row order
7058            row = actualRows - row;
7059            
7060            var start = row,
7061                end = columns - 1 - row;
7062
7063            if (column < start || column > end)
7064                return;
7065            
7066            // retroactively fix the first body's position, since width was unknown
7067            if (i === 1) {
7068                Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 });
7069            }
7070
7071            var xOffset = lastBody ? column * lastBodyWidth : 0;
7072            
7073            return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i);
7074        });
7075    };
7076
7077    /**
7078     * Creates a composite with a Newton's Cradle setup of bodies and constraints.
7079     * @method newtonsCradle
7080     * @param {number} xx
7081     * @param {number} yy
7082     * @param {number} number
7083     * @param {number} size
7084     * @param {number} length
7085     * @return {composite} A new composite newtonsCradle body
7086     */
7087    Composites.newtonsCradle = function(xx, yy, number, size, length) {
7088        var newtonsCradle = Composite.create({ label: 'Newtons Cradle' });
7089
7090        for (var i = 0; i < number; i++) {
7091            var separation = 1.9,
7092                circle = Bodies.circle(xx + i * (size * separation), yy + length, size, 
7093                            { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }),
7094                constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle });
7095
7096            Composite.addBody(newtonsCradle, circle);
7097            Composite.addConstraint(newtonsCradle, constraint);
7098        }
7099
7100        return newtonsCradle;
7101    };
7102    
7103    /**
7104     * Creates a composite with simple car setup of bodies and constraints.
7105     * @method car
7106     * @param {number} xx
7107     * @param {number} yy
7108     * @param {number} width
7109     * @param {number} height
7110     * @param {number} wheelSize
7111     * @return {composite} A new composite car body
7112     */
7113    Composites.car = function(xx, yy, width, height, wheelSize) {
7114        var group = Body.nextGroup(true),
7115            wheelBase = 20,
7116            wheelAOffset = -width * 0.5 + wheelBase,
7117            wheelBOffset = width * 0.5 - wheelBase,
7118            wheelYOffset = 0;
7119    
7120        var car = Composite.create({ label: 'Car' }),
7121            body = Bodies.rectangle(xx, yy, width, height, { 
7122                collisionFilter: {
7123                    group: group
7124                },
7125                chamfer: {
7126                    radius: height * 0.5
7127                },
7128                density: 0.0002
7129            });
7130    
7131        var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { 
7132            collisionFilter: {
7133                group: group
7134            },
7135            friction: 0.8
7136        });
7137                    
7138        var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { 
7139            collisionFilter: {
7140                group: group
7141            },
7142            friction: 0.8
7143        });
7144                    
7145        var axelA = Constraint.create({
7146            bodyB: body,
7147            pointB: { x: wheelAOffset, y: wheelYOffset },
7148            bodyA: wheelA,
7149            stiffness: 1,
7150            length: 0
7151        });
7152                        
7153        var axelB = Constraint.create({
7154            bodyB: body,
7155            pointB: { x: wheelBOffset, y: wheelYOffset },
7156            bodyA: wheelB,
7157            stiffness: 1,
7158            length: 0
7159        });
7160        
7161        Composite.addBody(car, body);
7162        Composite.addBody(car, wheelA);
7163        Composite.addBody(car, wheelB);
7164        Composite.addConstraint(car, axelA);
7165        Composite.addConstraint(car, axelB);
7166
7167        return car;
7168    };
7169
7170    /**
7171     * Creates a simple soft body like object.
7172     * @method softBody
7173     * @param {number} xx
7174     * @param {number} yy
7175     * @param {number} columns
7176     * @param {number} rows
7177     * @param {number} columnGap
7178     * @param {number} rowGap
7179     * @param {boolean} crossBrace
7180     * @param {number} particleRadius
7181     * @param {} particleOptions
7182     * @param {} constraintOptions
7183     * @return {composite} A new composite softBody
7184     */
7185    Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
7186        particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
7187        constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions);
7188
7189        var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
7190            return Bodies.circle(x, y, particleRadius, particleOptions);
7191        });
7192
7193        Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
7194
7195        softBody.label = 'Soft Body';
7196
7197        return softBody;
7198    };
7199
7200})();
7201
7202},{"../body/Body":1,"../body/Composite":2,"../constraint/Constraint":12,"../core/Common":14,"./Bodies":23}],25:[function(_dereq_,module,exports){
7203/**
7204* The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
7205*
7206* @class Axes
7207*/
7208
7209var Axes = {};
7210
7211module.exports = Axes;
7212
7213var Vector = _dereq_('../geometry/Vector');
7214var Common = _dereq_('../core/Common');
7215
7216(function() {
7217
7218    /**
7219     * Creates a new set of axes from the given vertices.
7220     * @method fromVertices
7221     * @param {vertices} vertices
7222     * @return {axes} A new axes from the given vertices
7223     */
7224    Axes.fromVertices = function(vertices) {
7225        var axes = {};
7226
7227        // find the unique axes, using edge normal gradients
7228        for (var i = 0; i < vertices.length; i++) {
7229            var j = (i + 1) % vertices.length, 
7230                normal = Vector.normalise({ 
7231                    x: vertices[j].y - vertices[i].y, 
7232                    y: vertices[i].x - vertices[j].x
7233                }),
7234                gradient = (normal.y === 0) ? Infinity : (normal.x / normal.y);
7235            
7236            // limit precision
7237            gradient = gradient.toFixed(3).toString();
7238            axes[gradient] = normal;
7239        }
7240
7241        return Common.values(axes);
7242    };
7243
7244    /**
7245     * Rotates a set of axes by the given angle.
7246     * @method rotate
7247     * @param {axes} axes
7248     * @param {number} angle
7249     */
7250    Axes.rotate = function(axes, angle) {
7251        if (angle === 0)
7252            return;
7253        
7254        var cos = Math.cos(angle),
7255            sin = Math.sin(angle);
7256
7257        for (var i = 0; i < axes.length; i++) {
7258            var axis = axes[i],
7259                xx;
7260            xx = axis.x * cos - axis.y * sin;
7261            axis.y = axis.x * sin + axis.y * cos;
7262            axis.x = xx;
7263        }
7264    };
7265
7266})();
7267
7268},{"../core/Common":14,"../geometry/Vector":28}],26:[function(_dereq_,module,exports){
7269/**
7270* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
7271*
7272* @class Bounds
7273*/
7274
7275var Bounds = {};
7276
7277module.exports = Bounds;
7278
7279(function() {
7280
7281    /**
7282     * Creates a new axis-aligned bounding box (AABB) for the given vertices.
7283     * @method create
7284     * @param {vertices} vertices
7285     * @return {bounds} A new bounds object
7286     */
7287    Bounds.create = function(vertices) {
7288        var bounds = { 
7289            min: { x: 0, y: 0 }, 
7290            max: { x: 0, y: 0 }
7291        };
7292
7293        if (vertices)
7294            Bounds.update(bounds, vertices);
7295        
7296        return bounds;
7297    };
7298
7299    /**
7300     * Updates bounds using the given vertices and extends the bounds given a velocity.
7301     * @method update
7302     * @param {bounds} bounds
7303     * @param {vertices} vertices
7304     * @param {vector} velocity
7305     */
7306    Bounds.update = function(bounds, vertices, velocity) {
7307        bounds.min.x = Infinity;
7308        bounds.max.x = -Infinity;
7309        bounds.min.y = Infinity;
7310        bounds.max.y = -Infinity;
7311
7312        for (var i = 0; i < vertices.length; i++) {
7313            var vertex = vertices[i];
7314            if (vertex.x > bounds.max.x) bounds.max.x = vertex.x;
7315            if (vertex.x < bounds.min.x) bounds.min.x = vertex.x;
7316            if (vertex.y > bounds.max.y) bounds.max.y = vertex.y;
7317            if (vertex.y < bounds.min.y) bounds.min.y = vertex.y;
7318        }
7319        
7320        if (velocity) {
7321            if (velocity.x > 0) {
7322                bounds.max.x += velocity.x;
7323            } else {
7324                bounds.min.x += velocity.x;
7325            }
7326            
7327            if (velocity.y > 0) {
7328                bounds.max.y += velocity.y;
7329            } else {
7330                bounds.min.y += velocity.y;
7331            }
7332        }
7333    };
7334
7335    /**
7336     * Returns true if the bounds contains the given point.
7337     * @method contains
7338     * @param {bounds} bounds
7339     * @param {vector} point
7340     * @return {boolean} True if the bounds contain the point, otherwise false
7341     */
7342    Bounds.contains = function(bounds, point) {
7343        return point.x >= bounds.min.x && point.x <= bounds.max.x 
7344               && point.y >= bounds.min.y && point.y <= bounds.max.y;
7345    };
7346
7347    /**
7348     * Returns true if the two bounds intersect.
7349     * @method overlaps
7350     * @param {bounds} boundsA
7351     * @param {bounds} boundsB
7352     * @return {boolean} True if the bounds overlap, otherwise false
7353     */
7354    Bounds.overlaps = function(boundsA, boundsB) {
7355        return (boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x
7356                && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y);
7357    };
7358
7359    /**
7360     * Translates the bounds by the given vector.
7361     * @method translate
7362     * @param {bounds} bounds
7363     * @param {vector} vector
7364     */
7365    Bounds.translate = function(bounds, vector) {
7366        bounds.min.x += vector.x;
7367        bounds.max.x += vector.x;
7368        bounds.min.y += vector.y;
7369        bounds.max.y += vector.y;
7370    };
7371
7372    /**
7373     * Shifts the bounds to the given position.
7374     * @method shift
7375     * @param {bounds} bounds
7376     * @param {vector} position
7377     */
7378    Bounds.shift = function(bounds, position) {
7379        var deltaX = bounds.max.x - bounds.min.x,
7380            deltaY = bounds.max.y - bounds.min.y;
7381            
7382        bounds.min.x = position.x;
7383        bounds.max.x = position.x + deltaX;
7384        bounds.min.y = position.y;
7385        bounds.max.y = position.y + deltaY;
7386    };
7387    
7388})();
7389
7390},{}],27:[function(_dereq_,module,exports){
7391/**
7392* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
7393*
7394* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
7395*
7396* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
7397*
7398* @class Svg
7399*/
7400
7401var Svg = {};
7402
7403module.exports = Svg;
7404
7405var Bounds = _dereq_('../geometry/Bounds');
7406var Common = _dereq_('../core/Common');
7407
7408(function() {
7409
7410    /**
7411     * Converts an SVG path into an array of vector points.
7412     * If the input path forms a concave shape, you must decompose the result into convex parts before use.
7413     * See `Bodies.fromVertices` which provides support for this.
7414     * Note that this function is not guaranteed to support complex paths (such as those with holes).
7415     * You must load the `pathseg.js` polyfill on newer browsers.
7416     * @method pathToVertices
7417     * @param {SVGPathElement} path
7418     * @param {Number} [sampleLength=15]
7419     * @return {Vector[]} points
7420     */
7421    Svg.pathToVertices = function(path, sampleLength) {
7422        if (typeof window !== 'undefined' && !('SVGPathSeg' in window)) {
7423            Common.warn('Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.');
7424        }
7425
7426        // https://github.com/wout/svg.topoly.js/blob/master/svg.topoly.js
7427        var i, il, total, point, segment, segments, 
7428            segmentsQueue, lastSegment, 
7429            lastPoint, segmentIndex, points = [],
7430            lx, ly, length = 0, x = 0, y = 0;
7431
7432        sampleLength = sampleLength || 15;
7433
7434        var addPoint = function(px, py, pathSegType) {
7435            // all odd-numbered path types are relative except PATHSEG_CLOSEPATH (1)
7436            var isRelative = pathSegType % 2 === 1 && pathSegType > 1;
7437
7438            // when the last point doesn't equal the current point add the current point
7439            if (!lastPoint || px != lastPoint.x || py != lastPoint.y) {
7440                if (lastPoint && isRelative) {
7441                    lx = lastPoint.x;
7442                    ly = lastPoint.y;
7443                } else {
7444                    lx = 0;
7445                    ly = 0;
7446                }
7447
7448                var point = {
7449                    x: lx + px,
7450                    y: ly + py
7451                };
7452
7453                // set last point
7454                if (isRelative || !lastPoint) {
7455                    lastPoint = point;
7456                }
7457
7458                points.push(point);
7459
7460                x = lx + px;
7461                y = ly + py;
7462            }
7463        };
7464
7465        var addSegmentPoint = function(segment) {
7466            var segType = segment.pathSegTypeAsLetter.toUpperCase();
7467
7468            // skip path ends
7469            if (segType === 'Z') 
7470                return;
7471
7472            // map segment to x and y
7473            switch (segType) {
7474
7475            case 'M':
7476            case 'L':
7477            case 'T':
7478            case 'C':
7479            case 'S':
7480            case 'Q':
7481                x = segment.x;
7482                y = segment.y;
7483                break;
7484            case 'H':
7485                x = segment.x;
7486                break;
7487            case 'V':
7488                y = segment.y;
7489                break;
7490            }
7491
7492            addPoint(x, y, segment.pathSegType);
7493        };
7494
7495        // ensure path is absolute
7496        Svg._svgPathToAbsolute(path);
7497
7498        // get total length
7499        total = path.getTotalLength();
7500
7501        // queue segments
7502        segments = [];
7503        for (i = 0; i < path.pathSegList.numberOfItems; i += 1)
7504            segments.push(path.pathSegList.getItem(i));
7505
7506        segmentsQueue = segments.concat();
7507
7508        // sample through path
7509        while (length < total) {
7510            // get segment at position
7511            segmentIndex = path.getPathSegAtLength(length);
7512            segment = segments[segmentIndex];
7513
7514            // new segment
7515            if (segment != lastSegment) {
7516                while (segmentsQueue.length && segmentsQueue[0] != segment)
7517                    addSegmentPoint(segmentsQueue.shift());
7518
7519                lastSegment = segment;
7520            }
7521
7522            // add points in between when curving
7523            // TODO: adaptive sampling
7524            switch (segment.pathSegTypeAsLetter.toUpperCase()) {
7525
7526            case 'C':
7527            case 'T':
7528            case 'S':
7529            case 'Q':
7530            case 'A':
7531                point = path.getPointAtLength(length);
7532                addPoint(point.x, point.y, 0);
7533                break;
7534
7535            }
7536
7537            // increment by sample value
7538            length += sampleLength;
7539        }
7540
7541        // add remaining segments not passed by sampling
7542        for (i = 0, il = segmentsQueue.length; i < il; ++i)
7543            addSegmentPoint(segmentsQueue[i]);
7544
7545        return points;
7546    };
7547
7548    Svg._svgPathToAbsolute = function(path) {
7549        // http://phrogz.net/convert-svg-path-to-all-absolute-commands
7550        // Copyright (c) Gavin Kistner
7551        // http://phrogz.net/js/_ReuseLicense.txt
7552        // Modifications: tidy formatting and naming
7553        var x0, y0, x1, y1, x2, y2, segs = path.pathSegList,
7554            x = 0, y = 0, len = segs.numberOfItems;
7555
7556        for (var i = 0; i < len; ++i) {
7557            var seg = segs.getItem(i),
7558                segType = seg.pathSegTypeAsLetter;
7559
7560            if (/[MLHVCSQTA]/.test(segType)) {
7561                if ('x' in seg) x = seg.x;
7562                if ('y' in seg) y = seg.y;
7563            } else {
7564                if ('x1' in seg) x1 = x + seg.x1;
7565                if ('x2' in seg) x2 = x + seg.x2;
7566                if ('y1' in seg) y1 = y + seg.y1;
7567                if ('y2' in seg) y2 = y + seg.y2;
7568                if ('x' in seg) x += seg.x;
7569                if ('y' in seg) y += seg.y;
7570
7571                switch (segType) {
7572
7573                case 'm':
7574                    segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i);
7575                    break;
7576                case 'l':
7577                    segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i);
7578                    break;
7579                case 'h':
7580                    segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i);
7581                    break;
7582                case 'v':
7583                    segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i);
7584                    break;
7585                case 'c':
7586                    segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i);
7587                    break;
7588                case 's':
7589                    segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i);
7590                    break;
7591                case 'q':
7592                    segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i);
7593                    break;
7594                case 't':
7595                    segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i);
7596                    break;
7597                case 'a':
7598                    segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i);
7599                    break;
7600                case 'z':
7601                case 'Z':
7602                    x = x0;
7603                    y = y0;
7604                    break;
7605
7606                }
7607            }
7608
7609            if (segType == 'M' || segType == 'm') {
7610                x0 = x;
7611                y0 = y;
7612            }
7613        }
7614    };
7615
7616})();
7617},{"../core/Common":14,"../geometry/Bounds":26}],28:[function(_dereq_,module,exports){
7618/**
7619* The `Matter.Vector` module contains methods for creating and manipulating vectors.
7620* Vectors are the basis of all the geometry related operations in the engine.
7621* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
7622*
7623* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
7624*
7625* @class Vector
7626*/
7627
7628// TODO: consider params for reusing vector objects
7629
7630var Vector = {};
7631
7632module.exports = Vector;
7633
7634(function() {
7635
7636    /**
7637     * Creates a new vector.
7638     * @method create
7639     * @param {number} x
7640     * @param {number} y
7641     * @return {vector} A new vector
7642     */
7643    Vector.create = function(x, y) {
7644        return { x: x || 0, y: y || 0 };
7645    };
7646
7647    /**
7648     * Returns a new vector with `x` and `y` copied from the given `vector`.
7649     * @method clone
7650     * @param {vector} vector
7651     * @return {vector} A new cloned vector
7652     */
7653    Vector.clone = function(vector) {
7654        return { x: vector.x, y: vector.y };
7655    };
7656
7657    /**
7658     * Returns the magnitude (length) of a vector.
7659     * @method magnitude
7660     * @param {vector} vector
7661     * @return {number} The magnitude of the vector
7662     */
7663    Vector.magnitude = function(vector) {
7664        return Math.sqrt((vector.x * vector.x) + (vector.y * vector.y));
7665    };
7666
7667    /**
7668     * Returns the magnitude (length) of a vector (therefore saving a `sqrt` operation).
7669     * @method magnitudeSquared
7670     * @param {vector} vector
7671     * @return {number} The squared magnitude of the vector
7672     */
7673    Vector.magnitudeSquared = function(vector) {
7674        return (vector.x * vector.x) + (vector.y * vector.y);
7675    };
7676
7677    /**
7678     * Rotates the vector about (0, 0) by specified angle.
7679     * @method rotate
7680     * @param {vector} vector
7681     * @param {number} angle
7682     * @param {vector} [output]
7683     * @return {vector} The vector rotated about (0, 0)
7684     */
7685    Vector.rotate = function(vector, angle, output) {
7686        var cos = Math.cos(angle), sin = Math.sin(angle);
7687        if (!output) output = {};
7688        var x = vector.x * cos - vector.y * sin;
7689        output.y = vector.x * sin + vector.y * cos;
7690        output.x = x;
7691        return output;
7692    };
7693
7694    /**
7695     * Rotates the vector about a specified point by specified angle.
7696     * @method rotateAbout
7697     * @param {vector} vector
7698     * @param {number} angle
7699     * @param {vector} point
7700     * @param {vector} [output]
7701     * @return {vector} A new vector rotated about the point
7702     */
7703    Vector.rotateAbout = function(vector, angle, point, output) {
7704        var cos = Math.cos(angle), sin = Math.sin(angle);
7705        if (!output) output = {};
7706        var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin);
7707        output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos);
7708        output.x = x;
7709        return output;
7710    };
7711
7712    /**
7713     * Normalises a vector (such that its magnitude is `1`).
7714     * @method normalise
7715     * @param {vector} vector
7716     * @return {vector} A new vector normalised
7717     */
7718    Vector.normalise = function(vector) {
7719        var magnitude = Vector.magnitude(vector);
7720        if (magnitude === 0)
7721            return { x: 0, y: 0 };
7722        return { x: vector.x / magnitude, y: vector.y / magnitude };
7723    };
7724
7725    /**
7726     * Returns the dot-product of two vectors.
7727     * @method dot
7728     * @param {vector} vectorA
7729     * @param {vector} vectorB
7730     * @return {number} The dot product of the two vectors
7731     */
7732    Vector.dot = function(vectorA, vectorB) {
7733        return (vectorA.x * vectorB.x) + (vectorA.y * vectorB.y);
7734    };
7735
7736    /**
7737     * Returns the cross-product of two vectors.
7738     * @method cross
7739     * @param {vector} vectorA
7740     * @param {vector} vectorB
7741     * @return {number} The cross product of the two vectors
7742     */
7743    Vector.cross = function(vectorA, vectorB) {
7744        return (vectorA.x * vectorB.y) - (vectorA.y * vectorB.x);
7745    };
7746
7747    /**
7748     * Returns the cross-product of three vectors.
7749     * @method cross3
7750     * @param {vector} vectorA
7751     * @param {vector} vectorB
7752     * @param {vector} vectorC
7753     * @return {number} The cross product of the three vectors
7754     */
7755    Vector.cross3 = function(vectorA, vectorB, vectorC) {
7756        return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x);
7757    };
7758
7759    /**
7760     * Adds the two vectors.
7761     * @method add
7762     * @param {vector} vectorA
7763     * @param {vector} vectorB
7764     * @param {vector} [output]
7765     * @return {vector} A new vector of vectorA and vectorB added
7766     */
7767    Vector.add = function(vectorA, vectorB, output) {
7768        if (!output) output = {};
7769        output.x = vectorA.x + vectorB.x;
7770        output.y = vectorA.y + vectorB.y;
7771        return output;
7772    };
7773
7774    /**
7775     * Subtracts the two vectors.
7776     * @method sub
7777     * @param {vector} vectorA
7778     * @param {vector} vectorB
7779     * @param {vector} [output]
7780     * @return {vector} A new vector of vectorA and vectorB subtracted
7781     */
7782    Vector.sub = function(vectorA, vectorB, output) {
7783        if (!output) output = {};
7784        output.x = vectorA.x - vectorB.x;
7785        output.y = vectorA.y - vectorB.y;
7786        return output;
7787    };
7788
7789    /**
7790     * Multiplies a vector and a scalar.
7791     * @method mult
7792     * @param {vector} vector
7793     * @param {number} scalar
7794     * @return {vector} A new vector multiplied by scalar
7795     */
7796    Vector.mult = function(vector, scalar) {
7797        return { x: vector.x * scalar, y: vector.y * scalar };
7798    };
7799
7800    /**
7801     * Divides a vector and a scalar.
7802     * @method div
7803     * @param {vector} vector
7804     * @param {number} scalar
7805     * @return {vector} A new vector divided by scalar
7806     */
7807    Vector.div = function(vector, scalar) {
7808        return { x: vector.x / scalar, y: vector.y / scalar };
7809    };
7810
7811    /**
7812     * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction.
7813     * @method perp
7814     * @param {vector} vector
7815     * @param {bool} [negate=false]
7816     * @return {vector} The perpendicular vector
7817     */
7818    Vector.perp = function(vector, negate) {
7819        negate = negate === true ? -1 : 1;
7820        return { x: negate * -vector.y, y: negate * vector.x };
7821    };
7822
7823    /**
7824     * Negates both components of a vector such that it points in the opposite direction.
7825     * @method neg
7826     * @param {vector} vector
7827     * @return {vector} The negated vector
7828     */
7829    Vector.neg = function(vector) {
7830        return { x: -vector.x, y: -vector.y };
7831    };
7832
7833    /**
7834     * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians.
7835     * @method angle
7836     * @param {vector} vectorA
7837     * @param {vector} vectorB
7838     * @return {number} The angle in radians
7839     */
7840    Vector.angle = function(vectorA, vectorB) {
7841        return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x);
7842    };
7843
7844    /**
7845     * Temporary vector pool (not thread-safe).
7846     * @property _temp
7847     * @type {vector[]}
7848     * @private
7849     */
7850    Vector._temp = [
7851        Vector.create(), Vector.create(), 
7852        Vector.create(), Vector.create(), 
7853        Vector.create(), Vector.create()
7854    ];
7855
7856})();
7857},{}],29:[function(_dereq_,module,exports){
7858/**
7859* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
7860* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
7861* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
7862*
7863* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
7864*
7865* @class Vertices
7866*/
7867
7868var Vertices = {};
7869
7870module.exports = Vertices;
7871
7872var Vector = _dereq_('../geometry/Vector');
7873var Common = _dereq_('../core/Common');
7874
7875(function() {
7876
7877    /**
7878     * Creates a new set of `Matter.Body` compatible vertices.
7879     * The `points` argument accepts an array of `Matter.Vector` points orientated around the origin `(0, 0)`, for example:
7880     *
7881     *     [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
7882     *
7883     * The `Vertices.create` method returns a new array of vertices, which are similar to Matter.Vector objects,
7884     * but with some additional references required for efficient collision detection routines.
7885     *
7886     * Vertices must be specified in clockwise order.
7887     *
7888     * Note that the `body` argument is not optional, a `Matter.Body` reference must be provided.
7889     *
7890     * @method create
7891     * @param {vector[]} points
7892     * @param {body} body
7893     */
7894    Vertices.create = function(points, body) {
7895        var vertices = [];
7896
7897        for (var i = 0; i < points.length; i++) {
7898            var point = points[i],
7899                vertex = {
7900                    x: point.x,
7901                    y: point.y,
7902                    index: i,
7903                    body: body,
7904                    isInternal: false
7905                };
7906
7907            vertices.push(vertex);
7908        }
7909
7910        return vertices;
7911    };
7912
7913    /**
7914     * Parses a string containing ordered x y pairs separated by spaces (and optionally commas), 
7915     * into a `Matter.Vertices` object for the given `Matter.Body`.
7916     * For parsing SVG paths, see `Svg.pathToVertices`.
7917     * @method fromPath
7918     * @param {string} path
7919     * @param {body} body
7920     * @return {vertices} vertices
7921     */
7922    Vertices.fromPath = function(path, body) {
7923        var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
7924            points = [];
7925
7926        path.replace(pathPattern, function(match, x, y) {
7927            points.push({ x: parseFloat(x), y: parseFloat(y) });
7928        });
7929
7930        return Vertices.create(points, body);
7931    };
7932
7933    /**
7934     * Returns the centre (centroid) of the set of vertices.
7935     * @method centre
7936     * @param {vertices} vertices
7937     * @return {vector} The centre point
7938     */
7939    Vertices.centre = function(vertices) {
7940        var area = Vertices.area(vertices, true),
7941            centre = { x: 0, y: 0 },
7942            cross,
7943            temp,
7944            j;
7945
7946        for (var i = 0; i < vertices.length; i++) {
7947            j = (i + 1) % vertices.length;
7948            cross = Vector.cross(vertices[i], vertices[j]);
7949            temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross);
7950            centre = Vector.add(centre, temp);
7951        }
7952
7953        return Vector.div(centre, 6 * area);
7954    };
7955
7956    /**
7957     * Returns the average (mean) of the set of vertices.
7958     * @method mean
7959     * @param {vertices} vertices
7960     * @return {vector} The average point
7961     */
7962    Vertices.mean = function(vertices) {
7963        var average = { x: 0, y: 0 };
7964
7965        for (var i = 0; i < vertices.length; i++) {
7966            average.x += vertices[i].x;
7967            average.y += vertices[i].y;
7968        }
7969
7970        return Vector.div(average, vertices.length);
7971    };
7972
7973    /**
7974     * Returns the area of the set of vertices.
7975     * @method area
7976     * @param {vertices} vertices
7977     * @param {bool} signed
7978     * @return {number} The area
7979     */
7980    Vertices.area = function(vertices, signed) {
7981        var area = 0,
7982            j = vertices.length - 1;
7983
7984        for (var i = 0; i < vertices.length; i++) {
7985            area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y);
7986            j = i;
7987        }
7988
7989        if (signed)
7990            return area / 2;
7991
7992        return Math.abs(area) / 2;
7993    };
7994
7995    /**
7996     * Returns the moment of inertia (second moment of area) of the set of vertices given the total mass.
7997     * @method inertia
7998     * @param {vertices} vertices
7999     * @param {number} mass
8000     * @return {number} The polygon's moment of inertia
8001     */
8002    Vertices.inertia = function(vertices, mass) {
8003        var numerator = 0,
8004            denominator = 0,
8005            v = vertices,
8006            cross,
8007            j;
8008
8009        // find the polygon's moment of inertia, using second moment of area
8010        // from equations at http://www.physicsforums.com/showthread.php?t=25293
8011        for (var n = 0; n < v.length; n++) {
8012            j = (n + 1) % v.length;
8013            cross = Math.abs(Vector.cross(v[j], v[n]));
8014            numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n]));
8015            denominator += cross;
8016        }
8017
8018        return (mass / 6) * (numerator / denominator);
8019    };
8020
8021    /**
8022     * Translates the set of vertices in-place.
8023     * @method translate
8024     * @param {vertices} vertices
8025     * @param {vector} vector
8026     * @param {number} scalar
8027     */
8028    Vertices.translate = function(vertices, vector, scalar) {
8029        var i;
8030        if (scalar) {
8031            for (i = 0; i < vertices.length; i++) {
8032                vertices[i].x += vector.x * scalar;
8033                vertices[i].y += vector.y * scalar;
8034            }
8035        } else {
8036            for (i = 0; i < vertices.length; i++) {
8037                vertices[i].x += vector.x;
8038                vertices[i].y += vector.y;
8039            }
8040        }
8041
8042        return vertices;
8043    };
8044
8045    /**
8046     * Rotates the set of vertices in-place.
8047     * @method rotate
8048     * @param {vertices} vertices
8049     * @param {number} angle
8050     * @param {vector} point
8051     */
8052    Vertices.rotate = function(vertices, angle, point) {
8053        if (angle === 0)
8054            return;
8055
8056        var cos = Math.cos(angle),
8057            sin = Math.sin(angle);
8058
8059        for (var i = 0; i < vertices.length; i++) {
8060            var vertice = vertices[i],
8061                dx = vertice.x - point.x,
8062                dy = vertice.y - point.y;
8063                
8064            vertice.x = point.x + (dx * cos - dy * sin);
8065            vertice.y = point.y + (dx * sin + dy * cos);
8066        }
8067
8068        return vertices;
8069    };
8070
8071    /**
8072     * Returns `true` if the `point` is inside the set of `vertices`.
8073     * @method contains
8074     * @param {vertices} vertices
8075     * @param {vector} point
8076     * @return {boolean} True if the vertices contains point, otherwise false
8077     */
8078    Vertices.contains = function(vertices, point) {
8079        for (var i = 0; i < vertices.length; i++) {
8080            var vertice = vertices[i],
8081                nextVertice = vertices[(i + 1) % vertices.length];
8082            if ((point.x - vertice.x) * (nextVertice.y - vertice.y) + (point.y - vertice.y) * (vertice.x - nextVertice.x) > 0) {
8083                return false;
vendor: 5,007 bytes, lines 8084-8240
8084            }
8085        }
8086
8087        return true;
8088    };
8089
8090    /**
8091     * Scales the vertices from a point (default is centre) in-place.
8092     * @method scale
8093     * @param {vertices} vertices
8094     * @param {number} scaleX
8095     * @param {number} scaleY
8096     * @param {vector} point
8097     */
8098    Vertices.scale = function(vertices, scaleX, scaleY, point) {
8099        if (scaleX === 1 && scaleY === 1)
8100            return vertices;
8101
8102        point = point || Vertices.centre(vertices);
8103
8104        var vertex,
8105            delta;
8106
8107        for (var i = 0; i < vertices.length; i++) {
8108            vertex = vertices[i];
8109            delta = Vector.sub(vertex, point);
8110            vertices[i].x = point.x + delta.x * scaleX;
8111            vertices[i].y = point.y + delta.y * scaleY;
8112        }
8113
8114        return vertices;
8115    };
8116
8117    /**
8118     * Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices.
8119     * The radius parameter is a single number or an array to specify the radius for each vertex.
8120     * @method chamfer
8121     * @param {vertices} vertices
8122     * @param {number[]} radius
8123     * @param {number} quality
8124     * @param {number} qualityMin
8125     * @param {number} qualityMax
8126     */
8127    Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) {
8128        if (typeof radius === 'number') {
8129            radius = [radius];
8130        } else {
8131            radius = radius || [8];
8132        }
8133
8134        // quality defaults to -1, which is auto
8135        quality = (typeof quality !== 'undefined') ? quality : -1;
8136        qualityMin = qualityMin || 2;
8137        qualityMax = qualityMax || 14;
8138
8139        var newVertices = [];
8140
8141        for (var i = 0; i < vertices.length; i++) {
8142            var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1],
8143                vertex = vertices[i],
8144                nextVertex = vertices[(i + 1) % vertices.length],
8145                currentRadius = radius[i < radius.length ? i : radius.length - 1];
8146
8147            if (currentRadius === 0) {
8148                newVertices.push(vertex);
8149                continue;
8150            }
8151
8152            var prevNormal = Vector.normalise({ 
8153                x: vertex.y - prevVertex.y, 
8154                y: prevVertex.x - vertex.x
8155            });
8156
8157            var nextNormal = Vector.normalise({ 
8158                x: nextVertex.y - vertex.y, 
8159                y: vertex.x - nextVertex.x
8160            });
8161
8162            var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)),
8163                radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius),
8164                midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)),
8165                scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius));
8166
8167            var precision = quality;
8168
8169            if (quality === -1) {
8170                // automatically decide precision
8171                precision = Math.pow(currentRadius, 0.32) * 1.75;
8172            }
8173
8174            precision = Common.clamp(precision, qualityMin, qualityMax);
8175
8176            // use an even value for precision, more likely to reduce axes by using symmetry
8177            if (precision % 2 === 1)
8178                precision += 1;
8179
8180            var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)),
8181                theta = alpha / precision;
8182
8183            for (var j = 0; j < precision; j++) {
8184                newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex));
8185            }
8186        }
8187
8188        return newVertices;
8189    };
8190
8191    /**
8192     * Sorts the input vertices into clockwise order in place.
8193     * @method clockwiseSort
8194     * @param {vertices} vertices
8195     * @return {vertices} vertices
8196     */
8197    Vertices.clockwiseSort = function(vertices) {
8198        var centre = Vertices.mean(vertices);
8199
8200        vertices.sort(function(vertexA, vertexB) {
8201            return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB);
8202        });
8203
8204        return vertices;
8205    };
8206
8207    /**
8208     * Returns true if the vertices form a convex shape (vertices must be in clockwise order).
8209     * @method isConvex
8210     * @param {vertices} vertices
8211     * @return {bool} `true` if the `vertices` are convex, `false` if not (or `null` if not computable).
8212     */
8213    Vertices.isConvex = function(vertices) {
8214        // http://paulbourke.net/geometry/polygonmesh/
8215        // Copyright (c) Paul Bourke (use permitted)
8216
8217        var flag = 0,
8218            n = vertices.length,
8219            i,
8220            j,
8221            k,
8222            z;
8223
8224        if (n < 3)
8225            return null;
8226
8227        for (i = 0; i < n; i++) {
8228            j = (i + 1) % n;
8229            k = (i + 2) % n;
8230            z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y);
8231            z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x);
8232
8233            if (z < 0) {
8234                flag |= 1;
8235            } else if (z > 0) {
8236                flag |= 2;
8237            }
8238
8239            if (flag === 3) {
8240                return false;
8241            }
8242        }
8243
8244        if (flag !== 0){
8245            return true;
8246        } else {
8247            return null;
8248        }
8249    };
8250
8251    /**
8252     * Returns the convex hull of the input vertices as a new array of points.
8253     * @method hull
8254     * @param {vertices} vertices
8255     * @return [vertex] vertices
8256     */
8257    Vertices.hull = function(vertices) {
8258        // http://geomalgorithms.com/a10-_hull-1.html
8259
8260        var upper = [],
8261            lower = [], 
8262            vertex,
8263            i;
8264
8265        // sort vertices on x-axis (y-axis for ties)
8266        vertices = vertices.slice(0);
8267        vertices.sort(function(vertexA, vertexB) {
8268            var dx = vertexA.x - vertexB.x;
8269            return dx !== 0 ? dx : vertexA.y - vertexB.y;
8270        });
8271
8272        // build lower hull
8273        for (i = 0; i < vertices.length; i += 1) {
8274            vertex = vertices[i];
8275
8276            while (lower.length >= 2 
8277                   && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) {
8278                lower.pop();
8279            }
8280
8281            lower.push(vertex);
8282        }
8283
8284        // build upper hull
8285        for (i = vertices.length - 1; i >= 0; i -= 1) {
8286            vertex = vertices[i];
8287
8288            while (upper.length >= 2 
8289                   && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) {
8290                upper.pop();
8291            }
8292
8293            upper.push(vertex);
8294        }
8295
8296        // concatenation of the lower and upper hulls gives the convex hull
8297        // omit last points because they are repeated at the beginning of the other list
8298        upper.pop();
8299        lower.pop();
8300
8301        return upper.concat(lower);
8302    };
8303
8304})();
8305
8306},{"../core/Common":14,"../geometry/Vector":28}],30:[function(_dereq_,module,exports){
8307var Matter = module.exports = _dereq_('../core/Matter');
8308
8309Matter.Body = _dereq_('../body/Body');
8310Matter.Composite = _dereq_('../body/Composite');
8311Matter.World = _dereq_('../body/World');
8312
8313Matter.Contact = _dereq_('../collision/Contact');
8314Matter.Detector = _dereq_('../collision/Detector');
8315Matter.Grid = _dereq_('../collision/Grid');
8316Matter.Pairs = _dereq_('../collision/Pairs');
8317Matter.Pair = _dereq_('../collision/Pair');
8318Matter.Query = _dereq_('../collision/Query');
8319Matter.Resolver = _dereq_('../collision/Resolver');
8320Matter.SAT = _dereq_('../collision/SAT');
8321
8322Matter.Constraint = _dereq_('../constraint/Constraint');
8323Matter.MouseConstraint = _dereq_('../constraint/MouseConstraint');
8324
8325Matter.Common = _dereq_('../core/Common');
8326Matter.Engine = _dereq_('../core/Engine');
8327Matter.Events = _dereq_('../core/Events');
8328Matter.Mouse = _dereq_('../core/Mouse');
8329Matter.Runner = _dereq_('../core/Runner');
8330Matter.Sleeping = _dereq_('../core/Sleeping');
8331Matter.Plugin = _dereq_('../core/Plugin');
8332
8333
8334Matter.Bodies = _dereq_('../factory/Bodies');
8335Matter.Composites = _dereq_('../factory/Composites');
8336
8337Matter.Axes = _dereq_('../geometry/Axes');
8338Matter.Bounds = _dereq_('../geometry/Bounds');
8339Matter.Svg = _dereq_('../geometry/Svg');
8340Matter.Vector = _dereq_('../geometry/Vector');
8341Matter.Vertices = _dereq_('../geometry/Vertices');
8342
8343Matter.Render = _dereq_('../render/Render');
8344Matter.RenderPixi = _dereq_('../render/RenderPixi');
8345
8346// aliases
8347
8348Matter.World.add = Matter.Composite.add;
8349Matter.World.remove = Matter.Composite.remove;
8350Matter.World.addComposite = Matter.Composite.addComposite;
8351Matter.World.addBody = Matter.Composite.addBody;
8352Matter.World.addConstraint = Matter.Composite.addConstraint;
8353Matter.World.clear = Matter.Composite.clear;
8354Matter.Engine.run = Matter.Runner.run;
8355
8356},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Contact":4,"../collision/Detector":5,"../collision/Grid":6,"../collision/Pair":7,"../collision/Pairs":8,"../collision/Query":9,"../collision/Resolver":10,"../collision/SAT":11,"../constraint/Constraint":12,"../constraint/MouseConstraint":13,"../core/Common":14,"../core/Engine":15,"../core/Events":16,"../core/Matter":17,"../core/Metrics":18,"../core/Mouse":19,"../core/Plugin":20,"../core/Runner":21,"../core/Sleeping":22,"../factory/Bodies":23,"../factory/Composites":24,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Svg":27,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31,"../render/RenderPixi":32}],31:[function(_dereq_,module,exports){
8357/**
8358* The `Matter.Render` module is a simple HTML5 canvas based renderer for visualising instances of `Matter.Engine`.
8359* It is intended for development and debugging purposes, but may also be suitable for simple games.
8360* It includes a number of drawing options including wireframe, vector with support for sprites and viewports.
8361*
8362* @class Render
8363*/
8364
8365var Render = {};
8366
8367module.exports = Render;
8368
8369var Common = _dereq_('../core/Common');
8370var Composite = _dereq_('../body/Composite');
8371var Bounds = _dereq_('../geometry/Bounds');
8372var Events = _dereq_('../core/Events');
8373var Grid = _dereq_('../collision/Grid');
8374var Vector = _dereq_('../geometry/Vector');
8375var Mouse = _dereq_('../core/Mouse');
8376
8377(function() {
8378
8379    var _requestAnimationFrame,
8380        _cancelAnimationFrame;
8381
8382    if (typeof window !== 'undefined') {
8383        _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
8384                                      || window.mozRequestAnimationFrame || window.msRequestAnimationFrame
8385                                      || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
8386
8387        _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
8388                                      || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
8389    }
8390
8391    /**
8392     * Creates a new renderer. The options parameter is an object that specifies any properties you wish to override the defaults.
8393     * All properties have default values, and many are pre-calculated automatically based on other properties.
8394     * See the properties section below for detailed information on what you can pass via the `options` object.
8395     * @method create
8396     * @param {object} [options]
8397     * @return {render} A new renderer
8398     */
8399    Render.create = function(options) {
8400        var defaults = {
8401            controller: Render,
8402            engine: null,
8403            element: null,
8404            canvas: null,
8405            mouse: null,
8406            frameRequestId: null,
8407            options: {
8408                width: 800,
8409                height: 600,
8410                pixelRatio: 1,
8411                background: '#18181d',
vendor: 12,501 bytes, lines 8412-8768
8412                wireframeBackground: '#0f0f13',
8413                hasBounds: !!options.bounds,
8414                enabled: true,
8415                wireframes: true,
8416                showSleeping: true,
8417                showDebug: false,
8418                showBroadphase: false,
8419                showBounds: false,
8420                showVelocity: false,
8421                showCollisions: false,
8422                showSeparations: false,
8423                showAxes: false,
8424                showPositions: false,
8425                showAngleIndicator: false,
8426                showIds: false,
8427                showShadows: false,
8428                showVertexNumbers: false,
8429                showConvexHulls: false,
8430                showInternalEdges: false,
8431                showMousePosition: false
8432            }
8433        };
8434
8435        var render = Common.extend(defaults, options);
8436
8437        if (render.canvas) {
8438            render.canvas.width = render.options.width || render.canvas.width;
8439            render.canvas.height = render.options.height || render.canvas.height;
8440        }
8441
8442        render.mouse = options.mouse;
8443        render.engine = options.engine;
8444        render.canvas = render.canvas || _createCanvas(render.options.width, render.options.height);
8445        render.context = render.canvas.getContext('2d');
8446        render.textures = {};
8447
8448        render.bounds = render.bounds || {
8449            min: {
8450                x: 0,
8451                y: 0
8452            },
8453            max: {
8454                x: render.canvas.width,
8455                y: render.canvas.height
8456            }
8457        };
8458
8459        if (render.options.pixelRatio !== 1) {
8460            Render.setPixelRatio(render, render.options.pixelRatio);
8461        }
8462
8463        if (Common.isElement(render.element)) {
8464            render.element.appendChild(render.canvas);
8465        } else if (!render.canvas.parentNode) {
8466            Common.log('Render.create: options.element was undefined, render.canvas was created but not appended', 'warn');
8467        }
8468
8469        return render;
8470    };
8471
8472    /**
8473     * Continuously updates the render canvas on the `requestAnimationFrame` event.
8474     * @method run
8475     * @param {render} render
8476     */
8477    Render.run = function(render) {
8478        (function loop(time){
8479            render.frameRequestId = _requestAnimationFrame(loop);
8480            Render.world(render);
8481        })();
8482    };
8483
8484    /**
8485     * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
8486     * @method stop
8487     * @param {render} render
8488     */
8489    Render.stop = function(render) {
8490        _cancelAnimationFrame(render.frameRequestId);
8491    };
8492
8493    /**
8494     * Sets the pixel ratio of the renderer and updates the canvas.
8495     * To automatically detect the correct ratio, pass the string `'auto'` for `pixelRatio`.
8496     * @method setPixelRatio
8497     * @param {render} render
8498     * @param {number} pixelRatio
8499     */
8500    Render.setPixelRatio = function(render, pixelRatio) {
8501        var options = render.options,
8502            canvas = render.canvas;
8503
8504        if (pixelRatio === 'auto') {
8505            pixelRatio = _getPixelRatio(canvas);
8506        }
8507
8508        options.pixelRatio = pixelRatio;
8509        canvas.setAttribute('data-pixel-ratio', pixelRatio);
8510        canvas.width = options.width * pixelRatio;
8511        canvas.height = options.height * pixelRatio;
8512        canvas.style.width = options.width + 'px';
8513        canvas.style.height = options.height + 'px';
8514        render.context.scale(pixelRatio, pixelRatio);
8515    };
8516
8517    /**
8518     * Positions and sizes the viewport around the given object bounds.
8519     * Objects must have at least one of the following properties:
8520     * - `object.bounds`
8521     * - `object.position`
8522     * - `object.min` and `object.max`
8523     * - `object.x` and `object.y`
8524     * @method lookAt
8525     * @param {render} render
8526     * @param {object[]} objects
8527     * @param {vector} [padding]
8528     * @param {bool} [center=true]
8529     */
8530    Render.lookAt = function(render, objects, padding, center) {
8531        center = typeof center !== 'undefined' ? center : true;
8532        objects = Common.isArray(objects) ? objects : [objects];
8533        padding = padding || {
8534            x: 0,
8535            y: 0
8536        };
8537
8538        // find bounds of all objects
8539        var bounds = {
8540            min: { x: Infinity, y: Infinity },
8541            max: { x: -Infinity, y: -Infinity }
8542        };
8543
8544        for (var i = 0; i < objects.length; i += 1) {
8545            var object = objects[i],
8546                min = object.bounds ? object.bounds.min : (object.min || object.position || object),
8547                max = object.bounds ? object.bounds.max : (object.max || object.position || object);
8548
8549            if (min && max) {
8550                if (min.x < bounds.min.x)
8551                    bounds.min.x = min.x;
8552
8553                if (max.x > bounds.max.x)
8554                    bounds.max.x = max.x;
8555
8556                if (min.y < bounds.min.y)
8557                    bounds.min.y = min.y;
8558
8559                if (max.y > bounds.max.y)
8560                    bounds.max.y = max.y;
8561            }
8562        }
8563
8564        // find ratios
8565        var width = (bounds.max.x - bounds.min.x) + 2 * padding.x,
8566            height = (bounds.max.y - bounds.min.y) + 2 * padding.y,
8567            viewHeight = render.canvas.height,
8568            viewWidth = render.canvas.width,
8569            outerRatio = viewWidth / viewHeight,
8570            innerRatio = width / height,
8571            scaleX = 1,
8572            scaleY = 1;
8573
8574        // find scale factor
8575        if (innerRatio > outerRatio) {
8576            scaleY = innerRatio / outerRatio;
8577        } else {
8578            scaleX = outerRatio / innerRatio;
8579        }
8580
8581        // enable bounds
8582        render.options.hasBounds = true;
8583
8584        // position and size
8585        render.bounds.min.x = bounds.min.x;
8586        render.bounds.max.x = bounds.min.x + width * scaleX;
8587        render.bounds.min.y = bounds.min.y;
8588        render.bounds.max.y = bounds.min.y + height * scaleY;
8589
8590        // center
8591        if (center) {
8592            render.bounds.min.x += width * 0.5 - (width * scaleX) * 0.5;
8593            render.bounds.max.x += width * 0.5 - (width * scaleX) * 0.5;
8594            render.bounds.min.y += height * 0.5 - (height * scaleY) * 0.5;
8595            render.bounds.max.y += height * 0.5 - (height * scaleY) * 0.5;
8596        }
8597
8598        // padding
8599        render.bounds.min.x -= padding.x;
8600        render.bounds.max.x -= padding.x;
8601        render.bounds.min.y -= padding.y;
8602        render.bounds.max.y -= padding.y;
8603
8604        // update mouse
8605        if (render.mouse) {
8606            Mouse.setScale(render.mouse, {
8607                x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
8608                y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
8609            });
8610
8611            Mouse.setOffset(render.mouse, render.bounds.min);
8612        }
8613    };
8614
8615    /**
8616     * Applies viewport transforms based on `render.bounds` to a render context.
8617     * @method startViewTransform
8618     * @param {render} render
8619     */
8620    Render.startViewTransform = function(render) {
8621        var boundsWidth = render.bounds.max.x - render.bounds.min.x,
8622            boundsHeight = render.bounds.max.y - render.bounds.min.y,
8623            boundsScaleX = boundsWidth / render.options.width,
8624            boundsScaleY = boundsHeight / render.options.height;
8625
8626        render.context.scale(1 / boundsScaleX, 1 / boundsScaleY);
8627        render.context.translate(-render.bounds.min.x, -render.bounds.min.y);
8628    };
8629
8630    /**
8631     * Resets all transforms on the render context.
8632     * @method endViewTransform
8633     * @param {render} render
8634     */
8635    Render.endViewTransform = function(render) {
8636        render.context.setTransform(render.options.pixelRatio, 0, 0, render.options.pixelRatio, 0, 0);
8637    };
8638
8639    /**
8640     * Renders the given `engine`'s `Matter.World` object.
8641     * This is the entry point for all rendering and should be called every time the scene changes.
8642     * @method world
8643     * @param {render} render
8644     */
8645    Render.world = function(render) {
8646        var engine = render.engine,
8647            world = engine.world,
8648            canvas = render.canvas,
8649            context = render.context,
8650            options = render.options,
8651            allBodies = Composite.allBodies(world),
8652            allConstraints = Composite.allConstraints(world),
8653            background = options.wireframes ? options.wireframeBackground : options.background,
8654            bodies = [],
8655            constraints = [],
8656            i;
8657
8658        var event = {
8659            timestamp: engine.timing.timestamp
8660        };
8661
8662        Events.trigger(render, 'beforeRender', event);
8663
8664        // apply background if it has changed
8665        if (render.currentBackground !== background)
8666            _applyBackground(render, background);
8667
8668        // clear the canvas with a transparent fill, to allow the canvas background to show
8669        context.globalCompositeOperation = 'source-in';
8670        context.fillStyle = "transparent";
8671        context.fillRect(0, 0, canvas.width, canvas.height);
8672        context.globalCompositeOperation = 'source-over';
8673
8674        // handle bounds
8675        if (options.hasBounds) {
8676            // filter out bodies that are not in view
8677            for (i = 0; i < allBodies.length; i++) {
8678                var body = allBodies[i];
8679                if (Bounds.overlaps(body.bounds, render.bounds))
8680                    bodies.push(body);
8681            }
8682
8683            // filter out constraints that are not in view
8684            for (i = 0; i < allConstraints.length; i++) {
8685                var constraint = allConstraints[i],
8686                    bodyA = constraint.bodyA,
8687                    bodyB = constraint.bodyB,
8688                    pointAWorld = constraint.pointA,
8689                    pointBWorld = constraint.pointB;
8690
8691                if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
8692                if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
8693
8694                if (!pointAWorld || !pointBWorld)
8695                    continue;
8696
8697                if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
8698                    constraints.push(constraint);
8699            }
8700
8701            // transform the view
8702            Render.startViewTransform(render);
8703
8704            // update mouse
8705            if (render.mouse) {
8706                Mouse.setScale(render.mouse, {
8707                    x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
8708                    y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
8709                });
8710
8711                Mouse.setOffset(render.mouse, render.bounds.min);
8712            }
8713        } else {
8714            constraints = allConstraints;
8715            bodies = allBodies;
8716        }
8717
8718        if (!options.wireframes || (engine.enableSleeping && options.showSleeping)) {
8719            // fully featured rendering of bodies
8720            Render.bodies(render, bodies, context);
8721        } else {
8722            if (options.showConvexHulls)
8723                Render.bodyConvexHulls(render, bodies, context);
8724
8725            // optimised method for wireframes only
8726            Render.bodyWireframes(render, bodies, context);
8727        }
8728
8729        if (options.showBounds)
8730            Render.bodyBounds(render, bodies, context);
8731
8732        if (options.showAxes || options.showAngleIndicator)
8733            Render.bodyAxes(render, bodies, context);
8734
8735        if (options.showPositions)
8736            Render.bodyPositions(render, bodies, context);
8737
8738        if (options.showVelocity)
8739            Render.bodyVelocity(render, bodies, context);
8740
8741        if (options.showIds)
8742            Render.bodyIds(render, bodies, context);
8743
8744        if (options.showSeparations)
8745            Render.separations(render, engine.pairs.list, context);
8746
8747        if (options.showCollisions)
8748            Render.collisions(render, engine.pairs.list, context);
8749
8750        if (options.showVertexNumbers)
8751            Render.vertexNumbers(render, bodies, context);
8752
8753        if (options.showMousePosition)
8754            Render.mousePosition(render, render.mouse, context);
8755
8756        Render.constraints(constraints, context);
8757
8758        if (options.showBroadphase && engine.broadphase.controller === Grid)
8759            Render.grid(render, engine.broadphase, context);
8760
8761        if (options.showDebug)
8762            Render.debug(render, context);
8763
8764        if (options.hasBounds) {
8765            // revert view transforms
8766            Render.endViewTransform(render);
8767        }
8768
8769        Events.trigger(render, 'afterRender', event);
8770    };
8771
8772    /**
8773     * Description
8774     * @private
8775     * @method debug
8776     * @param {render} render
8777     * @param {RenderingContext} context
8778     */
8779    Render.debug = function(render, context) {
8780        var c = context,
8781            engine = render.engine,
8782            world = engine.world,
8783            metrics = engine.metrics,
8784            options = render.options,
8785            bodies = Composite.allBodies(world),
8786            space = "    ";
8787
8788        if (engine.timing.timestamp - (render.debugTimestamp || 0) >= 500) {
8789            var text = "";
8790
8791            if (metrics.timing) {
8792                text += "fps: " + Math.round(metrics.timing.fps) + space;
8793            }
8794
8795
8796            render.debugString = text;
8797            render.debugTimestamp = engine.timing.timestamp;
8798        }
8799
8800        if (render.debugString) {
8801            c.font = "12px Arial";
8802
8803            if (options.wireframes) {
8804                c.fillStyle = 'rgba(255,255,255,0.5)';
8805            } else {
8806                c.fillStyle = 'rgba(0,0,0,0.5)';
8807            }
8808
8809            var split = render.debugString.split('\n');
8810
8811            for (var i = 0; i < split.length; i++) {
8812                c.fillText(split[i], 50, 50 + i * 18);
8813            }
8814        }
8815    };
8816
8817    /**
8818     * Description
8819     * @private
8820     * @method constraints
8821     * @param {constraint[]} constraints
8822     * @param {RenderingContext} context
8823     */
8824    Render.constraints = function(constraints, context) {
8825        var c = context;
8826
8827        for (var i = 0; i < constraints.length; i++) {
8828            var constraint = constraints[i];
8829
8830            if (!constraint.render.visible || !constraint.pointA || !constraint.pointB)
8831                continue;
8832
8833            var bodyA = constraint.bodyA,
8834                bodyB = constraint.bodyB,
8835                start,
8836                end;
8837
8838            if (bodyA) {
8839                start = Vector.add(bodyA.position, constraint.pointA);
8840            } else {
8841                start = constraint.pointA;
8842            }
8843
8844            if (constraint.render.type === 'pin') {
8845                c.beginPath();
8846                c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
8847                c.closePath();
8848            } else {
8849                if (bodyB) {
8850                    end = Vector.add(bodyB.position, constraint.pointB);
8851                } else {
8852                    end = constraint.pointB;
8853                }
8854
8855                c.beginPath();
8856                c.moveTo(start.x, start.y);
8857
8858                if (constraint.render.type === 'spring') {
8859                    var delta = Vector.sub(end, start),
8860                        normal = Vector.perp(Vector.normalise(delta)),
8861                        coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20)),
8862                        offset;
8863
8864                    for (var j = 1; j < coils; j += 1) {
8865                        offset = j % 2 === 0 ? 1 : -1;
8866
8867                        c.lineTo(
8868                            start.x + delta.x * (j / coils) + normal.x * offset * 4,
8869                            start.y + delta.y * (j / coils) + normal.y * offset * 4
8870                        );
8871                    }
8872                }
8873
8874                c.lineTo(end.x, end.y);
8875            }
8876
8877            if (constraint.render.lineWidth) {
8878                c.lineWidth = constraint.render.lineWidth;
8879                c.strokeStyle = constraint.render.strokeStyle;
8880                c.stroke();
8881            }
8882
8883            if (constraint.render.anchors) {
8884                c.fillStyle = constraint.render.strokeStyle;
8885                c.beginPath();
8886                c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
8887                c.arc(end.x, end.y, 3, 0, 2 * Math.PI);
8888                c.closePath();
8889                c.fill();
8890            }
8891        }
8892    };
8893
8894    /**
8895     * Description
8896     * @private
8897     * @method bodyShadows
8898     * @param {render} render
8899     * @param {body[]} bodies
8900     * @param {RenderingContext} context
8901     */
8902    Render.bodyShadows = function(render, bodies, context) {
8903        var c = context,
8904            engine = render.engine;
8905
8906        for (var i = 0; i < bodies.length; i++) {
8907            var body = bodies[i];
8908
8909            if (!body.render.visible)
8910                continue;
8911
8912            if (body.circleRadius) {
8913                c.beginPath();
8914                c.arc(body.position.x, body.position.y, body.circleRadius, 0, 2 * Math.PI);
8915                c.closePath();
8916            } else {
8917                c.beginPath();
8918                c.moveTo(body.vertices[0].x, body.vertices[0].y);
8919                for (var j = 1; j < body.vertices.length; j++) {
8920                    c.lineTo(body.vertices[j].x, body.vertices[j].y);
8921                }
8922                c.closePath();
8923            }
8924
8925            var distanceX = body.position.x - render.options.width * 0.5,
8926                distanceY = body.position.y - render.options.height * 0.2,
8927                distance = Math.abs(distanceX) + Math.abs(distanceY);
8928
8929            c.shadowColor = 'rgba(0,0,0,0.15)';
8930            c.shadowOffsetX = 0.05 * distanceX;
8931            c.shadowOffsetY = 0.05 * distanceY;
8932            c.shadowBlur = 1 + 12 * Math.min(1, distance / 1000);
8933
8934            c.fill();
8935
8936            c.shadowColor = null;
8937            c.shadowOffsetX = null;
8938            c.shadowOffsetY = null;
8939            c.shadowBlur = null;
8940        }
8941    };
8942
8943    /**
8944     * Description
8945     * @private
8946     * @method bodies
8947     * @param {render} render
8948     * @param {body[]} bodies
vendor: 23,379 bytes, lines 8949-9707
8949     * @param {RenderingContext} context
8950     */
8951    Render.bodies = function(render, bodies, context) {
8952        var c = context,
8953            engine = render.engine,
8954            options = render.options,
8955            showInternalEdges = options.showInternalEdges || !options.wireframes,
8956            body,
8957            part,
8958            i,
8959            k;
8960
8961        for (i = 0; i < bodies.length; i++) {
8962            body = bodies[i];
8963
8964            if (!body.render.visible)
8965                continue;
8966
8967            // handle compound parts
8968            for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
8969                part = body.parts[k];
8970
8971                if (!part.render.visible)
8972                    continue;
8973
8974                if (options.showSleeping && body.isSleeping) {
8975                    c.globalAlpha = 0.5 * part.render.opacity;
8976                } else if (part.render.opacity !== 1) {
8977                    c.globalAlpha = part.render.opacity;
8978                }
8979
8980                if (part.render.sprite && part.render.sprite.texture && !options.wireframes) {
8981                    // part sprite
8982                    var sprite = part.render.sprite,
8983                        texture = _getTexture(render, sprite.texture);
8984
8985                    c.translate(part.position.x, part.position.y);
8986                    c.rotate(part.angle);
8987
8988                    c.drawImage(
8989                        texture,
8990                        texture.width * -sprite.xOffset * sprite.xScale,
8991                        texture.height * -sprite.yOffset * sprite.yScale,
8992                        texture.width * sprite.xScale,
8993                        texture.height * sprite.yScale
8994                    );
8995
8996                    // revert translation, hopefully faster than save / restore
8997                    c.rotate(-part.angle);
8998                    c.translate(-part.position.x, -part.position.y);
8999                } else {
9000                    // part polygon
9001                    if (part.circleRadius) {
9002                        c.beginPath();
9003                        c.arc(part.position.x, part.position.y, part.circleRadius, 0, 2 * Math.PI);
9004                    } else {
9005                        c.beginPath();
9006                        c.moveTo(part.vertices[0].x, part.vertices[0].y);
9007
9008                        for (var j = 1; j < part.vertices.length; j++) {
9009                            if (!part.vertices[j - 1].isInternal || showInternalEdges) {
9010                                c.lineTo(part.vertices[j].x, part.vertices[j].y);
9011                            } else {
9012                                c.moveTo(part.vertices[j].x, part.vertices[j].y);
9013                            }
9014
9015                            if (part.vertices[j].isInternal && !showInternalEdges) {
9016                                c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
9017                            }
9018                        }
9019
9020                        c.lineTo(part.vertices[0].x, part.vertices[0].y);
9021                        c.closePath();
9022                    }
9023
9024                    if (!options.wireframes) {
9025                        c.fillStyle = part.render.fillStyle;
9026
9027                        if (part.render.lineWidth) {
9028                            c.lineWidth = part.render.lineWidth;
9029                            c.strokeStyle = part.render.strokeStyle;
9030                            c.stroke();
9031                        }
9032
9033                        c.fill();
9034                    } else {
9035                        c.lineWidth = 1;
9036                        c.strokeStyle = '#bbb';
9037                        c.stroke();
9038                    }
9039                }
9040
9041                c.globalAlpha = 1;
9042            }
9043        }
9044    };
9045
9046    /**
9047     * Optimised method for drawing body wireframes in one pass
9048     * @private
9049     * @method bodyWireframes
9050     * @param {render} render
9051     * @param {body[]} bodies
9052     * @param {RenderingContext} context
9053     */
9054    Render.bodyWireframes = function(render, bodies, context) {
9055        var c = context,
9056            showInternalEdges = render.options.showInternalEdges,
9057            body,
9058            part,
9059            i,
9060            j,
9061            k;
9062
9063        c.beginPath();
9064
9065        // render all bodies
9066        for (i = 0; i < bodies.length; i++) {
9067            body = bodies[i];
9068
9069            if (!body.render.visible)
9070                continue;
9071
9072            // handle compound parts
9073            for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
9074                part = body.parts[k];
9075
9076                c.moveTo(part.vertices[0].x, part.vertices[0].y);
9077
9078                for (j = 1; j < part.vertices.length; j++) {
9079                    if (!part.vertices[j - 1].isInternal || showInternalEdges) {
9080                        c.lineTo(part.vertices[j].x, part.vertices[j].y);
9081                    } else {
9082                        c.moveTo(part.vertices[j].x, part.vertices[j].y);
9083                    }
9084
9085                    if (part.vertices[j].isInternal && !showInternalEdges) {
9086                        c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
9087                    }
9088                }
9089
9090                c.lineTo(part.vertices[0].x, part.vertices[0].y);
9091            }
9092        }
9093
9094        c.lineWidth = 1;
9095        c.strokeStyle = '#bbb';
9096        c.stroke();
9097    };
9098
9099    /**
9100     * Optimised method for drawing body convex hull wireframes in one pass
9101     * @private
9102     * @method bodyConvexHulls
9103     * @param {render} render
9104     * @param {body[]} bodies
9105     * @param {RenderingContext} context
9106     */
9107    Render.bodyConvexHulls = function(render, bodies, context) {
9108        var c = context,
9109            body,
9110            part,
9111            i,
9112            j,
9113            k;
9114
9115        c.beginPath();
9116
9117        // render convex hulls
9118        for (i = 0; i < bodies.length; i++) {
9119            body = bodies[i];
9120
9121            if (!body.render.visible || body.parts.length === 1)
9122                continue;
9123
9124            c.moveTo(body.vertices[0].x, body.vertices[0].y);
9125
9126            for (j = 1; j < body.vertices.length; j++) {
9127                c.lineTo(body.vertices[j].x, body.vertices[j].y);
9128            }
9129
9130            c.lineTo(body.vertices[0].x, body.vertices[0].y);
9131        }
9132
9133        c.lineWidth = 1;
9134        c.strokeStyle = 'rgba(255,255,255,0.2)';
9135        c.stroke();
9136    };
9137
9138    /**
9139     * Renders body vertex numbers.
9140     * @private
9141     * @method vertexNumbers
9142     * @param {render} render
9143     * @param {body[]} bodies
9144     * @param {RenderingContext} context
9145     */
9146    Render.vertexNumbers = function(render, bodies, context) {
9147        var c = context,
9148            i,
9149            j,
9150            k;
9151
9152        for (i = 0; i < bodies.length; i++) {
9153            var parts = bodies[i].parts;
9154            for (k = parts.length > 1 ? 1 : 0; k < parts.length; k++) {
9155                var part = parts[k];
9156                for (j = 0; j < part.vertices.length; j++) {
9157                    c.fillStyle = 'rgba(255,255,255,0.2)';
9158                    c.fillText(i + '_' + j, part.position.x + (part.vertices[j].x - part.position.x) * 0.8, part.position.y + (part.vertices[j].y - part.position.y) * 0.8);
9159                }
9160            }
9161        }
9162    };
9163
9164    /**
9165     * Renders mouse position.
9166     * @private
9167     * @method mousePosition
9168     * @param {render} render
9169     * @param {mouse} mouse
9170     * @param {RenderingContext} context
9171     */
9172    Render.mousePosition = function(render, mouse, context) {
9173        var c = context;
9174        c.fillStyle = 'rgba(255,255,255,0.8)';
9175        c.fillText(mouse.position.x + '  ' + mouse.position.y, mouse.position.x + 5, mouse.position.y - 5);
9176    };
9177
9178    /**
9179     * Draws body bounds
9180     * @private
9181     * @method bodyBounds
9182     * @param {render} render
9183     * @param {body[]} bodies
9184     * @param {RenderingContext} context
9185     */
9186    Render.bodyBounds = function(render, bodies, context) {
9187        var c = context,
9188            engine = render.engine,
9189            options = render.options;
9190
9191        c.beginPath();
9192
9193        for (var i = 0; i < bodies.length; i++) {
9194            var body = bodies[i];
9195
9196            if (body.render.visible) {
9197                var parts = bodies[i].parts;
9198                for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
9199                    var part = parts[j];
9200                    c.rect(part.bounds.min.x, part.bounds.min.y, part.bounds.max.x - part.bounds.min.x, part.bounds.max.y - part.bounds.min.y);
9201                }
9202            }
9203        }
9204
9205        if (options.wireframes) {
9206            c.strokeStyle = 'rgba(255,255,255,0.08)';
9207        } else {
9208            c.strokeStyle = 'rgba(0,0,0,0.1)';
9209        }
9210
9211        c.lineWidth = 1;
9212        c.stroke();
9213    };
9214
9215    /**
9216     * Draws body angle indicators and axes
9217     * @private
9218     * @method bodyAxes
9219     * @param {render} render
9220     * @param {body[]} bodies
9221     * @param {RenderingContext} context
9222     */
9223    Render.bodyAxes = function(render, bodies, context) {
9224        var c = context,
9225            engine = render.engine,
9226            options = render.options,
9227            part,
9228            i,
9229            j,
9230            k;
9231
9232        c.beginPath();
9233
9234        for (i = 0; i < bodies.length; i++) {
9235            var body = bodies[i],
9236                parts = body.parts;
9237
9238            if (!body.render.visible)
9239                continue;
9240
9241            if (options.showAxes) {
9242                // render all axes
9243                for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
9244                    part = parts[j];
9245                    for (k = 0; k < part.axes.length; k++) {
9246                        var axis = part.axes[k];
9247                        c.moveTo(part.position.x, part.position.y);
9248                        c.lineTo(part.position.x + axis.x * 20, part.position.y + axis.y * 20);
9249                    }
9250                }
9251            } else {
9252                for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
9253                    part = parts[j];
9254                    for (k = 0; k < part.axes.length; k++) {
9255                        // render a single axis indicator
9256                        c.moveTo(part.position.x, part.position.y);
9257                        c.lineTo((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2,
9258                                 (part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2);
9259                    }
9260                }
9261            }
9262        }
9263
9264        if (options.wireframes) {
9265            c.strokeStyle = 'indianred';
9266            c.lineWidth = 1;
9267        } else {
9268            c.strokeStyle = 'rgba(255, 255, 255, 0.4)';
9269            c.globalCompositeOperation = 'overlay';
9270            c.lineWidth = 2;
9271        }
9272
9273        c.stroke();
9274        c.globalCompositeOperation = 'source-over';
9275    };
9276
9277    /**
9278     * Draws body positions
9279     * @private
9280     * @method bodyPositions
9281     * @param {render} render
9282     * @param {body[]} bodies
9283     * @param {RenderingContext} context
9284     */
9285    Render.bodyPositions = function(render, bodies, context) {
9286        var c = context,
9287            engine = render.engine,
9288            options = render.options,
9289            body,
9290            part,
9291            i,
9292            k;
9293
9294        c.beginPath();
9295
9296        // render current positions
9297        for (i = 0; i < bodies.length; i++) {
9298            body = bodies[i];
9299
9300            if (!body.render.visible)
9301                continue;
9302
9303            // handle compound parts
9304            for (k = 0; k < body.parts.length; k++) {
9305                part = body.parts[k];
9306                c.arc(part.position.x, part.position.y, 3, 0, 2 * Math.PI, false);
9307                c.closePath();
9308            }
9309        }
9310
9311        if (options.wireframes) {
9312            c.fillStyle = 'indianred';
9313        } else {
9314            c.fillStyle = 'rgba(0,0,0,0.5)';
9315        }
9316        c.fill();
9317
9318        c.beginPath();
9319
9320        // render previous positions
9321        for (i = 0; i < bodies.length; i++) {
9322            body = bodies[i];
9323            if (body.render.visible) {
9324                c.arc(body.positionPrev.x, body.positionPrev.y, 2, 0, 2 * Math.PI, false);
9325                c.closePath();
9326            }
9327        }
9328
9329        c.fillStyle = 'rgba(255,165,0,0.8)';
9330        c.fill();
9331    };
9332
9333    /**
9334     * Draws body velocity
9335     * @private
9336     * @method bodyVelocity
9337     * @param {render} render
9338     * @param {body[]} bodies
9339     * @param {RenderingContext} context
9340     */
9341    Render.bodyVelocity = function(render, bodies, context) {
9342        var c = context;
9343
9344        c.beginPath();
9345
9346        for (var i = 0; i < bodies.length; i++) {
9347            var body = bodies[i];
9348
9349            if (!body.render.visible)
9350                continue;
9351
9352            c.moveTo(body.position.x, body.position.y);
9353            c.lineTo(body.position.x + (body.position.x - body.positionPrev.x) * 2, body.position.y + (body.position.y - body.positionPrev.y) * 2);
9354        }
9355
9356        c.lineWidth = 3;
9357        c.strokeStyle = 'cornflowerblue';
9358        c.stroke();
9359    };
9360
9361    /**
9362     * Draws body ids
9363     * @private
9364     * @method bodyIds
9365     * @param {render} render
9366     * @param {body[]} bodies
9367     * @param {RenderingContext} context
9368     */
9369    Render.bodyIds = function(render, bodies, context) {
9370        var c = context,
9371            i,
9372            j;
9373
9374        for (i = 0; i < bodies.length; i++) {
9375            if (!bodies[i].render.visible)
9376                continue;
9377
9378            var parts = bodies[i].parts;
9379            for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
9380                var part = parts[j];
9381                c.font = "12px Arial";
9382                c.fillStyle = 'rgba(255,255,255,0.5)';
9383                c.fillText(part.id, part.position.x + 10, part.position.y - 10);
9384            }
9385        }
9386    };
9387
9388    /**
9389     * Description
9390     * @private
9391     * @method collisions
9392     * @param {render} render
9393     * @param {pair[]} pairs
9394     * @param {RenderingContext} context
9395     */
9396    Render.collisions = function(render, pairs, context) {
9397        var c = context,
9398            options = render.options,
9399            pair,
9400            collision,
9401            corrected,
9402            bodyA,
9403            bodyB,
9404            i,
9405            j;
9406
9407        c.beginPath();
9408
9409        // render collision positions
9410        for (i = 0; i < pairs.length; i++) {
9411            pair = pairs[i];
9412
9413            if (!pair.isActive)
9414                continue;
9415
9416            collision = pair.collision;
9417            for (j = 0; j < pair.activeContacts.length; j++) {
9418                var contact = pair.activeContacts[j],
9419                    vertex = contact.vertex;
9420                c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5);
9421            }
9422        }
9423
9424        if (options.wireframes) {
9425            c.fillStyle = 'rgba(255,255,255,0.7)';
9426        } else {
9427            c.fillStyle = 'orange';
9428        }
9429        c.fill();
9430
9431        c.beginPath();
9432
9433        // render collision normals
9434        for (i = 0; i < pairs.length; i++) {
9435            pair = pairs[i];
9436
9437            if (!pair.isActive)
9438                continue;
9439
9440            collision = pair.collision;
9441
9442            if (pair.activeContacts.length > 0) {
9443                var normalPosX = pair.activeContacts[0].vertex.x,
9444                    normalPosY = pair.activeContacts[0].vertex.y;
9445
9446                if (pair.activeContacts.length === 2) {
9447                    normalPosX = (pair.activeContacts[0].vertex.x + pair.activeContacts[1].vertex.x) / 2;
9448                    normalPosY = (pair.activeContacts[0].vertex.y + pair.activeContacts[1].vertex.y) / 2;
9449                }
9450
9451                if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic === true) {
9452                    c.moveTo(normalPosX - collision.normal.x * 8, normalPosY - collision.normal.y * 8);
9453                } else {
9454                    c.moveTo(normalPosX + collision.normal.x * 8, normalPosY + collision.normal.y * 8);
9455                }
9456
9457                c.lineTo(normalPosX, normalPosY);
9458            }
9459        }
9460
9461        if (options.wireframes) {
9462            c.strokeStyle = 'rgba(255,165,0,0.7)';
9463        } else {
9464            c.strokeStyle = 'orange';
9465        }
9466
9467        c.lineWidth = 1;
9468        c.stroke();
9469    };
9470
9471    /**
9472     * Description
9473     * @private
9474     * @method separations
9475     * @param {render} render
9476     * @param {pair[]} pairs
9477     * @param {RenderingContext} context
9478     */
9479    Render.separations = function(render, pairs, context) {
9480        var c = context,
9481            options = render.options,
9482            pair,
9483            collision,
9484            corrected,
9485            bodyA,
9486            bodyB,
9487            i,
9488            j;
9489
9490        c.beginPath();
9491
9492        // render separations
9493        for (i = 0; i < pairs.length; i++) {
9494            pair = pairs[i];
9495
9496            if (!pair.isActive)
9497                continue;
9498
9499            collision = pair.collision;
9500            bodyA = collision.bodyA;
9501            bodyB = collision.bodyB;
9502
9503            var k = 1;
9504
9505            if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
9506            if (bodyB.isStatic) k = 0;
9507
9508            c.moveTo(bodyB.position.x, bodyB.position.y);
9509            c.lineTo(bodyB.position.x - collision.penetration.x * k, bodyB.position.y - collision.penetration.y * k);
9510
9511            k = 1;
9512
9513            if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
9514            if (bodyA.isStatic) k = 0;
9515
9516            c.moveTo(bodyA.position.x, bodyA.position.y);
9517            c.lineTo(bodyA.position.x + collision.penetration.x * k, bodyA.position.y + collision.penetration.y * k);
9518        }
9519
9520        if (options.wireframes) {
9521            c.strokeStyle = 'rgba(255,165,0,0.5)';
9522        } else {
9523            c.strokeStyle = 'orange';
9524        }
9525        c.stroke();
9526    };
9527
9528    /**
9529     * Description
9530     * @private
9531     * @method grid
9532     * @param {render} render
9533     * @param {grid} grid
9534     * @param {RenderingContext} context
9535     */
9536    Render.grid = function(render, grid, context) {
9537        var c = context,
9538            options = render.options;
9539
9540        if (options.wireframes) {
9541            c.strokeStyle = 'rgba(255,180,0,0.1)';
9542        } else {
9543            c.strokeStyle = 'rgba(255,180,0,0.5)';
9544        }
9545
9546        c.beginPath();
9547
9548        var bucketKeys = Common.keys(grid.buckets);
9549
9550        for (var i = 0; i < bucketKeys.length; i++) {
9551            var bucketId = bucketKeys[i];
9552
9553            if (grid.buckets[bucketId].length < 2)
9554                continue;
9555
9556            var region = bucketId.split(/C|R/);
9557            c.rect(0.5 + parseInt(region[1], 10) * grid.bucketWidth,
9558                    0.5 + parseInt(region[2], 10) * grid.bucketHeight,
9559                    grid.bucketWidth,
9560                    grid.bucketHeight);
9561        }
9562
9563        c.lineWidth = 1;
9564        c.stroke();
9565    };
9566
9567    /**
9568     * Description
9569     * @private
9570     * @method inspector
9571     * @param {inspector} inspector
9572     * @param {RenderingContext} context
9573     */
9574    Render.inspector = function(inspector, context) {
9575        var engine = inspector.engine,
9576            selected = inspector.selected,
9577            render = inspector.render,
9578            options = render.options,
9579            bounds;
9580
9581        if (options.hasBounds) {
9582            var boundsWidth = render.bounds.max.x - render.bounds.min.x,
9583                boundsHeight = render.bounds.max.y - render.bounds.min.y,
9584                boundsScaleX = boundsWidth / render.options.width,
9585                boundsScaleY = boundsHeight / render.options.height;
9586
9587            context.scale(1 / boundsScaleX, 1 / boundsScaleY);
9588            context.translate(-render.bounds.min.x, -render.bounds.min.y);
9589        }
9590
9591        for (var i = 0; i < selected.length; i++) {
9592            var item = selected[i].data;
9593
9594            context.translate(0.5, 0.5);
9595            context.lineWidth = 1;
9596            context.strokeStyle = 'rgba(255,165,0,0.9)';
9597            context.setLineDash([1,2]);
9598
9599            switch (item.type) {
9600
9601            case 'body':
9602
9603                // render body selections
9604                bounds = item.bounds;
9605                context.beginPath();
9606                context.rect(Math.floor(bounds.min.x - 3), Math.floor(bounds.min.y - 3),
9607                             Math.floor(bounds.max.x - bounds.min.x + 6), Math.floor(bounds.max.y - bounds.min.y + 6));
9608                context.closePath();
9609                context.stroke();
9610
9611                break;
9612
9613            case 'constraint':
9614
9615                // render constraint selections
9616                var point = item.pointA;
9617                if (item.bodyA)
9618                    point = item.pointB;
9619                context.beginPath();
9620                context.arc(point.x, point.y, 10, 0, 2 * Math.PI);
9621                context.closePath();
9622                context.stroke();
9623
9624                break;
9625
9626            }
9627
9628            context.setLineDash([]);
9629            context.translate(-0.5, -0.5);
9630        }
9631
9632        // render selection region
9633        if (inspector.selectStart !== null) {
9634            context.translate(0.5, 0.5);
9635            context.lineWidth = 1;
9636            context.strokeStyle = 'rgba(255,165,0,0.6)';
9637            context.fillStyle = 'rgba(255,165,0,0.1)';
9638            bounds = inspector.selectBounds;
9639            context.beginPath();
9640            context.rect(Math.floor(bounds.min.x), Math.floor(bounds.min.y),
9641                         Math.floor(bounds.max.x - bounds.min.x), Math.floor(bounds.max.y - bounds.min.y));
9642            context.closePath();
9643            context.stroke();
9644            context.fill();
9645            context.translate(-0.5, -0.5);
9646        }
9647
9648        if (options.hasBounds)
9649            context.setTransform(1, 0, 0, 1, 0, 0);
9650    };
9651
9652    /**
9653     * Description
9654     * @method _createCanvas
9655     * @private
9656     * @param {} width
9657     * @param {} height
9658     * @return canvas
9659     */
9660    var _createCanvas = function(width, height) {
9661        var canvas = document.createElement('canvas');
9662        canvas.width = width;
9663        canvas.height = height;
9664        canvas.oncontextmenu = function() { return false; };
9665        canvas.onselectstart = function() { return false; };
9666        return canvas;
9667    };
9668
9669    /**
9670     * Gets the pixel ratio of the canvas.
9671     * @method _getPixelRatio
9672     * @private
9673     * @param {HTMLElement} canvas
9674     * @return {Number} pixel ratio
9675     */
9676    var _getPixelRatio = function(canvas) {
9677        var context = canvas.getContext('2d'),
9678            devicePixelRatio = window.devicePixelRatio || 1,
9679            backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio
9680                                      || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio
9681                                      || context.backingStorePixelRatio || 1;
9682
9683        return devicePixelRatio / backingStorePixelRatio;
9684    };
9685
9686    /**
9687     * Gets the requested texture (an Image) via its path
9688     * @method _getTexture
9689     * @private
9690     * @param {render} render
9691     * @param {string} imagePath
9692     * @return {Image} texture
9693     */
9694    var _getTexture = function(render, imagePath) {
9695        var image = render.textures[imagePath];
9696
9697        if (image)
9698            return image;
9699
9700        image = render.textures[imagePath] = new Image();
9701        image.src = imagePath;
9702
9703        return image;
9704    };
9705
9706    /**
9707     * Applies the background to the canvas using CSS.
9708     * @method applyBackground
9709     * @private
9710     * @param {render} render
9711     * @param {string} background
9712     */
9713    var _applyBackground = function(render, background) {
9714        var cssBackground = background;
9715
9716        if (/(jpg|gif|png)$/.test(background))
9717            cssBackground = 'url(' + background + ')';
9718
9719        render.canvas.style.background = cssBackground;
9720        render.canvas.style.backgroundSize = "contain";
9721        render.currentBackground = background;
9722    };
9723
9724    /*
9725    *
9726    *  Events Documentation
9727    *
9728    */
9729
9730    /**
9731    * Fired before rendering
9732    *
9733    * @event beforeRender
9734    * @param {} event An event object
9735    * @param {number} event.timestamp The engine.timing.timestamp of the event
9736    * @param {} event.source The source object of the event
9737    * @param {} event.name The name of the event
9738    */
9739
9740    /**
9741    * Fired after rendering
9742    *
9743    * @event afterRender
9744    * @param {} event An event object
9745    * @param {number} event.timestamp The engine.timing.timestamp of the event
9746    * @param {} event.source The source object of the event
9747    * @param {} event.name The name of the event
9748    */
9749
9750    /*
9751    *
9752    *  Properties Documentation
9753    *
9754    */
9755
9756    /**
9757     * A back-reference to the `Matter.Render` module.
9758     *
9759     * @property controller
9760     * @type render
9761     */
9762
9763    /**
9764     * A reference to the `Matter.Engine` instance to be used.
9765     *
9766     * @property engine
9767     * @type engine
9768     */
9769
9770    /**
9771     * A reference to the element where the canvas is to be inserted (if `render.canvas` has not been specified)
9772     *
9773     * @property element
9774     * @type HTMLElement
9775     * @default null
9776     */
9777
9778    /**
9779     * The canvas element to render to. If not specified, one will be created if `render.element` has been specified.
9780     *
9781     * @property canvas
9782     * @type HTMLCanvasElement
9783     * @default null
9784     */
9785
9786    /**
9787     * The configuration options of the renderer.
9788     *
9789     * @property options
9790     * @type {}
9791     */
9792
9793    /**
9794     * The target width in pixels of the `render.canvas` to be created.
9795     *
9796     * @property options.width
9797     * @type number
9798     * @default 800
9799     */
9800
9801    /**
9802     * The target height in pixels of the `render.canvas` to be created.
9803     *
9804     * @property options.height
9805     * @type number
9806     * @default 600
9807     */
9808
9809    /**
9810     * A flag that specifies if `render.bounds` should be used when rendering.
9811     *
9812     * @property options.hasBounds
9813     * @type boolean
9814     * @default false
9815     */
9816
9817    /**
9818     * A `Bounds` object that specifies the drawing view region.
9819     * Rendering will be automatically transformed and scaled to fit within the canvas size (`render.options.width` and `render.options.height`).
9820     * This allows for creating views that can pan or zoom around the scene.
9821     * You must also set `render.options.hasBounds` to `true` to enable bounded rendering.
9822     *
9823     * @property bounds
9824     * @type bounds
9825     */
9826
9827    /**
9828     * The 2d rendering context from the `render.canvas` element.
9829     *
9830     * @property context
9831     * @type CanvasRenderingContext2D
9832     */
9833
9834    /**
9835     * The sprite texture cache.
9836     *
9837     * @property textures
9838     * @type {}
9839     */
9840
9841})();
9842
9843},{"../body/Composite":2,"../collision/Grid":6,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../geometry/Bounds":26,"../geometry/Vector":28}],32:[function(_dereq_,module,exports){
9844/**
9845* The `Matter.RenderPixi` module is an example renderer using pixi.js.
9846* See also `Matter.Render` for a canvas based renderer.
9847*
9848* @class RenderPixi
9849* @deprecated the Matter.RenderPixi module will soon be removed from the Matter.js core.
9850* It will likely be moved to its own repository (but maintenance will be limited).
9851*/
9852
9853var RenderPixi = {};
9854
9855module.exports = RenderPixi;
9856
9857var Bounds = _dereq_('../geometry/Bounds');
9858var Composite = _dereq_('../body/Composite');
9859var Common = _dereq_('../core/Common');
9860var Events = _dereq_('../core/Events');
9861var Vector = _dereq_('../geometry/Vector');
9862
9863(function() {
9864
9865    var _requestAnimationFrame,
9866        _cancelAnimationFrame;
9867
9868    if (typeof window !== 'undefined') {
9869        _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
9870                                      || window.mozRequestAnimationFrame || window.msRequestAnimationFrame 
9871                                      || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
9872   
9873        _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame 
9874                                      || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
9875    }
9876    
9877    /**
9878     * Creates a new Pixi.js WebGL renderer
9879     * @method create
9880     * @param {object} options
9881     * @return {RenderPixi} A new renderer
9882     * @deprecated
9883     */
9884    RenderPixi.create = function(options) {
9885        Common.warn('RenderPixi.create: Matter.RenderPixi is deprecated (see docs)');
9886
9887        var defaults = {
9888            controller: RenderPixi,
9889            engine: null,
9890            element: null,
9891            frameRequestId: null,
9892            canvas: null,
9893            renderer: null,
9894            container: null,
9895            spriteContainer: null,
9896            pixiOptions: null,
9897            options: {
9898                width: 800,
9899                height: 600,
9900                background: '#fafafa',
9901                wireframeBackground: '#222',
9902                hasBounds: false,
9903                enabled: true,
9904                wireframes: true,
9905                showSleeping: true,
9906                showDebug: false,
9907                showBroadphase: false,
9908                showBounds: false,
9909                showVelocity: false,
9910                showCollisions: false,
9911                showAxes: false,
9912                showPositions: false,
9913                showAngleIndicator: false,
9914                showIds: false,
9915                showShadows: false
9916            }
9917        };
9918
9919        var render = Common.extend(defaults, options),
9920            transparent = !render.options.wireframes && render.options.background === 'transparent';
9921
9922        // init pixi
9923        render.pixiOptions = render.pixiOptions || {
9924            view: render.canvas,
9925            transparent: transparent,
9926            antialias: true,
9927            backgroundColor: options.background
9928        };
9929
9930        render.mouse = options.mouse;
9931        render.engine = options.engine;
9932        render.renderer = render.renderer || new PIXI.WebGLRenderer(render.options.width, render.options.height, render.pixiOptions);
9933        render.container = render.container || new PIXI.Container();
9934        render.spriteContainer = render.spriteContainer || new PIXI.Container();
9935        render.canvas = render.canvas || render.renderer.view;
9936        render.bounds = render.bounds || { 
9937            min: {
9938                x: 0,
9939                y: 0
9940            }, 
9941            max: { 
9942                x: render.options.width,
9943                y: render.options.height
9944            }
9945        };
9946
9947        // event listeners
9948        Events.on(render.engine, 'beforeUpdate', function() {
9949            RenderPixi.clear(render);
9950        });
9951
9952        // caches
9953        render.textures = {};
9954        render.sprites = {};
9955        render.primitives = {};
9956
9957        // use a sprite batch for performance
9958        render.container.addChild(render.spriteContainer);
9959
9960        // insert canvas
9961        if (Common.isElement(render.element)) {
9962            render.element.appendChild(render.canvas);
9963        } else {
9964            Common.warn('No "render.element" passed, "render.canvas" was not inserted into document.');
9965        }
9966
9967        // prevent menus on canvas
9968        render.canvas.oncontextmenu = function() { return false; };
9969        render.canvas.onselectstart = function() { return false; };
9970
9971        return render;
9972    };
9973
9974    /**
9975     * Continuously updates the render canvas on the `requestAnimationFrame` event.
9976     * @method run
9977     * @param {render} render
9978     * @deprecated
9979     */
9980    RenderPixi.run = function(render) {
9981        (function loop(time){
9982            render.frameRequestId = _requestAnimationFrame(loop);
9983            RenderPixi.world(render);
9984        })();
9985    };
9986
9987    /**
9988     * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
9989     * @method stop
9990     * @param {render} render
9991     * @deprecated
9992     */
9993    RenderPixi.stop = function(render) {
9994        _cancelAnimationFrame(render.frameRequestId);
9995    };
9996
9997    /**
9998     * Clears the scene graph
9999     * @method clear
10000     * @param {RenderPixi} render
10001     * @deprecated
10002     */
10003    RenderPixi.clear = function(render) {
10004        var container = render.container,
10005            spriteContainer = render.spriteContainer;
10006
10007        // clear stage container
10008        while (container.children[0]) { 
10009            container.removeChild(container.children[0]); 
10010        }
10011
10012        // clear sprite batch
10013        while (spriteContainer.children[0]) { 
10014            spriteContainer.removeChild(spriteContainer.children[0]); 
10015        }
10016
10017        var bgSprite = render.sprites['bg-0'];
10018
10019        // clear caches
10020        render.textures = {};
10021        render.sprites = {};
10022        render.primitives = {};
10023
10024        // set background sprite
10025        render.sprites['bg-0'] = bgSprite;
10026        if (bgSprite)
10027            container.addChildAt(bgSprite, 0);
10028
10029        // add sprite batch back into container
10030        render.container.addChild(render.spriteContainer);
10031
10032        // reset background state
10033        render.currentBackground = null;
10034
10035        // reset bounds transforms
10036        container.scale.set(1, 1);
10037        container.position.set(0, 0);
10038    };
10039
10040    /**
10041     * Sets the background of the canvas 
10042     * @method setBackground
10043     * @param {RenderPixi} render
10044     * @param {string} background
10045     * @deprecated
10046     */
10047    RenderPixi.setBackground = function(render, background) {
10048        if (render.currentBackground !== background) {
10049            var isColor = background.indexOf && background.indexOf('#') !== -1,
10050                bgSprite = render.sprites['bg-0'];
10051
10052            if (isColor) {
10053                // if solid background color
10054                var color = Common.colorToNumber(background);
10055                render.renderer.backgroundColor = color;
10056
10057                // remove background sprite if existing
10058                if (bgSprite)
10059                    render.container.removeChild(bgSprite); 
10060            } else {
10061                // initialise background sprite if needed
10062                if (!bgSprite) {
10063                    var texture = _getTexture(render, background);
10064
10065                    bgSprite = render.sprites['bg-0'] = new PIXI.Sprite(texture);
10066                    bgSprite.position.x = 0;
10067                    bgSprite.position.y = 0;
10068                    render.container.addChildAt(bgSprite, 0);
10069                }
10070            }
10071
10072            render.currentBackground = background;
10073        }
10074    };
10075
10076    /**
10077     * Description
10078     * @method world
10079     * @param {engine} engine
10080     * @deprecated
10081     */
10082    RenderPixi.world = function(render) {
10083        var engine = render.engine,
10084            world = engine.world,
10085            renderer = render.renderer,
10086            container = render.container,
10087            options = render.options,
10088            bodies = Composite.allBodies(world),
10089            allConstraints = Composite.allConstraints(world),
10090            constraints = [],
10091            i;
10092
10093        if (options.wireframes) {
10094            RenderPixi.setBackground(render, options.wireframeBackground);
10095        } else {
10096            RenderPixi.setBackground(render, options.background);
10097        }
10098
10099        // handle bounds
10100        var boundsWidth = render.bounds.max.x - render.bounds.min.x,
10101            boundsHeight = render.bounds.max.y - render.bounds.min.y,
10102            boundsScaleX = boundsWidth / render.options.width,
10103            boundsScaleY = boundsHeight / render.options.height;
10104
10105        if (options.hasBounds) {
10106            // Hide bodies that are not in view
10107            for (i = 0; i < bodies.length; i++) {
10108                var body = bodies[i];
10109                body.render.sprite.visible = Bounds.overlaps(body.bounds, render.bounds);
10110            }
10111
10112            // filter out constraints that are not in view
10113            for (i = 0; i < allConstraints.length; i++) {
10114                var constraint = allConstraints[i],
10115                    bodyA = constraint.bodyA,
10116                    bodyB = constraint.bodyB,
10117                    pointAWorld = constraint.pointA,
10118                    pointBWorld = constraint.pointB;
10119
10120                if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
10121                if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
10122
10123                if (!pointAWorld || !pointBWorld)
10124                    continue;
10125
10126                if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
10127                    constraints.push(constraint);
10128            }
10129
10130            // transform the view
10131            container.scale.set(1 / boundsScaleX, 1 / boundsScaleY);
10132            container.position.set(-render.bounds.min.x * (1 / boundsScaleX), -render.bounds.min.y * (1 / boundsScaleY));
10133        } else {
10134            constraints = allConstraints;
10135        }
10136
10137        for (i = 0; i < bodies.length; i++)
10138            RenderPixi.body(render, bodies[i]);
10139
10140        for (i = 0; i < constraints.length; i++)
10141            RenderPixi.constraint(render, constraints[i]);
10142
10143        renderer.render(container);
10144    };
10145
10146
10147    /**
10148     * Description
10149     * @method constraint
10150     * @param {engine} engine
10151     * @param {constraint} constraint
10152     * @deprecated
10153     */
10154    RenderPixi.constraint = function(render, constraint) {
10155        var engine = render.engine,
10156            bodyA = constraint.bodyA,
10157            bodyB = constraint.bodyB,
10158            pointA = constraint.pointA,
10159            pointB = constraint.pointB,
10160            container = render.container,
10161            constraintRender = constraint.render,
10162            primitiveId = 'c-' + constraint.id,
10163            primitive = render.primitives[primitiveId];
10164
10165        // initialise constraint primitive if not existing
10166        if (!primitive)
10167            primitive = render.primitives[primitiveId] = new PIXI.Graphics();
10168
10169        // don't render if constraint does not have two end points
10170        if (!constraintRender.visible || !constraint.pointA || !constraint.pointB) {
10171            primitive.clear();
10172            return;
10173        }
10174
10175        // add to scene graph if not already there
10176        if (Common.indexOf(container.children, primitive) === -1)
10177            container.addChild(primitive);
10178
10179        // render the constraint on every update, since they can change dynamically
10180        primitive.clear();
10181        primitive.beginFill(0, 0);
10182        primitive.lineStyle(constraintRender.lineWidth, Common.colorToNumber(constraintRender.strokeStyle), 1);
10183        
10184        if (bodyA) {
10185            primitive.moveTo(bodyA.position.x + pointA.x, bodyA.position.y + pointA.y);
10186        } else {
10187            primitive.moveTo(pointA.x, pointA.y);
10188        }
10189
10190        if (bodyB) {
10191            primitive.lineTo(bodyB.position.x + pointB.x, bodyB.position.y + pointB.y);
10192        } else {
10193            primitive.lineTo(pointB.x, pointB.y);
10194        }
10195
10196        primitive.endFill();
10197    };
10198    
10199    /**
10200     * Description
10201     * @method body
10202     * @param {engine} engine
10203     * @param {body} body
10204     * @deprecated
10205     */
10206    RenderPixi.body = function(render, body) {
10207        var engine = render.engine,
10208            bodyRender = body.render;
10209
10210        if (!bodyRender.visible)
10211            return;
10212
10213        if (bodyRender.sprite && bodyRender.sprite.texture) {
10214            var spriteId = 'b-' + body.id,
10215                sprite = render.sprites[spriteId],
10216                spriteContainer = render.spriteContainer;
10217
10218            // initialise body sprite if not existing
10219            if (!sprite)
10220                sprite = render.sprites[spriteId] = _createBodySprite(render, body);
10221
10222            // add to scene graph if not already there
10223            if (Common.indexOf(spriteContainer.children, sprite) === -1)
10224                spriteContainer.addChild(sprite);
10225
10226            // update body sprite
10227            sprite.position.x = body.position.x;
10228            sprite.position.y = body.position.y;
10229            sprite.rotation = body.angle;
10230            sprite.scale.x = bodyRender.sprite.xScale || 1;
10231            sprite.scale.y = bodyRender.sprite.yScale || 1;
10232        } else {
10233            var primitiveId = 'b-' + body.id,
10234                primitive = render.primitives[primitiveId],
10235                container = render.container;
10236
10237            // initialise body primitive if not existing
10238            if (!primitive) {
10239                primitive = render.primitives[primitiveId] = _createBodyPrimitive(render, body);
10240                primitive.initialAngle = body.angle;
10241            }
10242
10243            // add to scene graph if not already there
10244            if (Common.indexOf(container.children, primitive) === -1)
10245                container.addChild(primitive);
10246
10247            // update body primitive
10248            primitive.position.x = body.position.x;
10249            primitive.position.y = body.position.y;
10250            primitive.rotation = body.angle - primitive.initialAngle;
10251        }
10252    };
10253
10254    /**
10255     * Creates a body sprite
10256     * @method _createBodySprite
10257     * @private
10258     * @param {RenderPixi} render
10259     * @param {body} body
10260     * @return {PIXI.Sprite} sprite
10261     * @deprecated
10262     */
10263    var _createBodySprite = function(render, body) {
10264        var bodyRender = body.render,
10265            texturePath = bodyRender.sprite.texture,
10266            texture = _getTexture(render, texturePath),
10267            sprite = new PIXI.Sprite(texture);
10268
10269        sprite.anchor.x = body.render.sprite.xOffset;
10270        sprite.anchor.y = body.render.sprite.yOffset;
10271
10272        return sprite;
10273    };
10274
10275    /**
10276     * Creates a body primitive
10277     * @method _createBodyPrimitive
10278     * @private
10279     * @param {RenderPixi} render
10280     * @param {body} body
10281     * @return {PIXI.Graphics} graphics
10282     * @deprecated
10283     */
10284    var _createBodyPrimitive = function(render, body) {
10285        var bodyRender = body.render,
10286            options = render.options,
10287            primitive = new PIXI.Graphics(),
10288            fillStyle = Common.colorToNumber(bodyRender.fillStyle),
10289            strokeStyle = Common.colorToNumber(bodyRender.strokeStyle),
10290            strokeStyleIndicator = Common.colorToNumber(bodyRender.strokeStyle),
10291            strokeStyleWireframe = Common.colorToNumber('#bbb'),
10292            strokeStyleWireframeIndicator = Common.colorToNumber('#CD5C5C'),
10293            part;
10294
10295        primitive.clear();
10296
10297        // handle compound parts
10298        for (var k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
10299            part = body.parts[k];
10300
10301            if (!options.wireframes) {
10302                primitive.beginFill(fillStyle, 1);
10303                primitive.lineStyle(bodyRender.lineWidth, strokeStyle, 1);
10304            } else {
10305                primitive.beginFill(0, 0);
10306                primitive.lineStyle(1, strokeStyleWireframe, 1);
10307            }
10308
10309            primitive.moveTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
10310
10311            for (var j = 1; j < part.vertices.length; j++) {
10312                primitive.lineTo(part.vertices[j].x - body.position.x, part.vertices[j].y - body.position.y);
10313            }
10314
10315            primitive.lineTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
10316
10317            primitive.endFill();
10318
10319            // angle indicator
10320            if (options.showAngleIndicator || options.showAxes) {
10321                primitive.beginFill(0, 0);
10322
10323                if (options.wireframes) {
10324                    primitive.lineStyle(1, strokeStyleWireframeIndicator, 1);
10325                } else {
10326                    primitive.lineStyle(1, strokeStyleIndicator);
10327                }
10328
10329                primitive.moveTo(part.position.x - body.position.x, part.position.y - body.position.y);
10330                primitive.lineTo(((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2 - body.position.x), 
10331                                 ((part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2 - body.position.y));
10332
10333                primitive.endFill();
10334            }
10335        }
10336
10337        return primitive;
10338    };
10339
10340    /**
10341     * Gets the requested texture (a PIXI.Texture) via its path
10342     * @method _getTexture
10343     * @private
10344     * @param {RenderPixi} render
10345     * @param {string} imagePath
10346     * @return {PIXI.Texture} texture
10347     * @deprecated
10348     */
10349    var _getTexture = function(render, imagePath) {
10350        var texture = render.textures[imagePath];
10351
10352        if (!texture)
10353            texture = render.textures[imagePath] = PIXI.Texture.fromImage(imagePath);
10354
10355        return texture;
10356    };
10357
10358})();
10359
10360},{"../body/Composite":2,"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"../geometry/Vector":28}]},{},[30])(30)
10361});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.