diff --git a/client.js b/client.js
index e69de29..dcdf2f4 100644
--- a/client.js
+++ b/client.js
@@ -0,0 +1,8 @@
+requirejs.config({
+ baseUrl: 'lib'
+});
+
+
+requirejs(["Chuck/Chuck"], function(Chuck) {
+ Chuck.init();
+});
\ No newline at end of file
diff --git a/index.html b/index.html
index e69de29..d9458ca 100644
--- a/index.html
+++ b/index.html
@@ -0,0 +1,32 @@
+
+
+
+ Chuck
+
+
+
+
+
+ hello chuck
+
+
+
+
diff --git a/lib/Box2D/Box2D.js b/lib/Box2D/Box2D.js
new file mode 100644
index 0000000..b9af97f
--- /dev/null
+++ b/lib/Box2D/Box2D.js
@@ -0,0 +1,10867 @@
+define(function(){
+
+/*
+* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+var Box2D = {};
+
+(function (a2j, undefined) {
+
+ function emptyFn() {};
+ a2j.inherit = function(cls, base) {
+ var tmpCtr = cls;
+ emptyFn.prototype = base.prototype;
+ cls.prototype = new emptyFn;
+ cls.prototype.constructor = tmpCtr;
+ };
+
+ a2j.generateCallback = function generateCallback(context, cb) {
+ return function () {
+ cb.apply(context, arguments);
+ };
+ };
+
+ a2j.NVector = function NVector(length) {
+ if (length === undefined) length = 0;
+ var tmp = new Array(length || 0);
+ for (var i = 0; i < length; ++i)
+ tmp[i] = 0;
+ return tmp;
+ };
+
+ a2j.is = function is(o1, o2) {
+ if (o1 === null) return false;
+ if ((o2 instanceof Function) && (o1 instanceof o2)) return true;
+ if ((o1.constructor.__implements != undefined) && (o1.constructor.__implements[o2])) return true;
+ return false;
+ };
+
+ a2j.parseUInt = function(v) {
+ return Math.abs(parseInt(v));
+ }
+
+})(Box2D);
+
+//#TODO remove assignments from global namespace
+var Vector = Array;
+var Vector_a2j_Number = Box2D.NVector;
+//package structure
+if (typeof(Box2D) === "undefined") Box2D = {};
+if (typeof(Box2D.Collision) === "undefined") Box2D.Collision = {};
+if (typeof(Box2D.Collision.Shapes) === "undefined") Box2D.Collision.Shapes = {};
+if (typeof(Box2D.Common) === "undefined") Box2D.Common = {};
+if (typeof(Box2D.Common.Math) === "undefined") Box2D.Common.Math = {};
+if (typeof(Box2D.Dynamics) === "undefined") Box2D.Dynamics = {};
+if (typeof(Box2D.Dynamics.Contacts) === "undefined") Box2D.Dynamics.Contacts = {};
+if (typeof(Box2D.Dynamics.Controllers) === "undefined") Box2D.Dynamics.Controllers = {};
+if (typeof(Box2D.Dynamics.Joints) === "undefined") Box2D.Dynamics.Joints = {};
+//pre-definitions
+(function () {
+ Box2D.Collision.IBroadPhase = 'Box2D.Collision.IBroadPhase';
+
+ function b2AABB() {
+ b2AABB.b2AABB.apply(this, arguments);
+ };
+ Box2D.Collision.b2AABB = b2AABB;
+
+ function b2Bound() {
+ b2Bound.b2Bound.apply(this, arguments);
+ };
+ Box2D.Collision.b2Bound = b2Bound;
+
+ function b2BoundValues() {
+ b2BoundValues.b2BoundValues.apply(this, arguments);
+ if (this.constructor === b2BoundValues) this.b2BoundValues.apply(this, arguments);
+ };
+ Box2D.Collision.b2BoundValues = b2BoundValues;
+
+ function b2Collision() {
+ b2Collision.b2Collision.apply(this, arguments);
+ };
+ Box2D.Collision.b2Collision = b2Collision;
+
+ function b2ContactID() {
+ b2ContactID.b2ContactID.apply(this, arguments);
+ if (this.constructor === b2ContactID) this.b2ContactID.apply(this, arguments);
+ };
+ Box2D.Collision.b2ContactID = b2ContactID;
+
+ function b2ContactPoint() {
+ b2ContactPoint.b2ContactPoint.apply(this, arguments);
+ };
+ Box2D.Collision.b2ContactPoint = b2ContactPoint;
+
+ function b2Distance() {
+ b2Distance.b2Distance.apply(this, arguments);
+ };
+ Box2D.Collision.b2Distance = b2Distance;
+
+ function b2DistanceInput() {
+ b2DistanceInput.b2DistanceInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceInput = b2DistanceInput;
+
+ function b2DistanceOutput() {
+ b2DistanceOutput.b2DistanceOutput.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceOutput = b2DistanceOutput;
+
+ function b2DistanceProxy() {
+ b2DistanceProxy.b2DistanceProxy.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceProxy = b2DistanceProxy;
+
+ function b2DynamicTree() {
+ b2DynamicTree.b2DynamicTree.apply(this, arguments);
+ if (this.constructor === b2DynamicTree) this.b2DynamicTree.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTree = b2DynamicTree;
+
+ function b2DynamicTreeBroadPhase() {
+ b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase;
+
+ function b2DynamicTreeNode() {
+ b2DynamicTreeNode.b2DynamicTreeNode.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreeNode = b2DynamicTreeNode;
+
+ function b2DynamicTreePair() {
+ b2DynamicTreePair.b2DynamicTreePair.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreePair = b2DynamicTreePair;
+
+ function b2Manifold() {
+ b2Manifold.b2Manifold.apply(this, arguments);
+ if (this.constructor === b2Manifold) this.b2Manifold.apply(this, arguments);
+ };
+ Box2D.Collision.b2Manifold = b2Manifold;
+
+ function b2ManifoldPoint() {
+ b2ManifoldPoint.b2ManifoldPoint.apply(this, arguments);
+ if (this.constructor === b2ManifoldPoint) this.b2ManifoldPoint.apply(this, arguments);
+ };
+ Box2D.Collision.b2ManifoldPoint = b2ManifoldPoint;
+
+ function b2Point() {
+ b2Point.b2Point.apply(this, arguments);
+ };
+ Box2D.Collision.b2Point = b2Point;
+
+ function b2RayCastInput() {
+ b2RayCastInput.b2RayCastInput.apply(this, arguments);
+ if (this.constructor === b2RayCastInput) this.b2RayCastInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2RayCastInput = b2RayCastInput;
+
+ function b2RayCastOutput() {
+ b2RayCastOutput.b2RayCastOutput.apply(this, arguments);
+ };
+ Box2D.Collision.b2RayCastOutput = b2RayCastOutput;
+
+ function b2Segment() {
+ b2Segment.b2Segment.apply(this, arguments);
+ };
+ Box2D.Collision.b2Segment = b2Segment;
+
+ function b2SeparationFunction() {
+ b2SeparationFunction.b2SeparationFunction.apply(this, arguments);
+ };
+ Box2D.Collision.b2SeparationFunction = b2SeparationFunction;
+
+ function b2Simplex() {
+ b2Simplex.b2Simplex.apply(this, arguments);
+ if (this.constructor === b2Simplex) this.b2Simplex.apply(this, arguments);
+ };
+ Box2D.Collision.b2Simplex = b2Simplex;
+
+ function b2SimplexCache() {
+ b2SimplexCache.b2SimplexCache.apply(this, arguments);
+ };
+ Box2D.Collision.b2SimplexCache = b2SimplexCache;
+
+ function b2SimplexVertex() {
+ b2SimplexVertex.b2SimplexVertex.apply(this, arguments);
+ };
+ Box2D.Collision.b2SimplexVertex = b2SimplexVertex;
+
+ function b2TimeOfImpact() {
+ b2TimeOfImpact.b2TimeOfImpact.apply(this, arguments);
+ };
+ Box2D.Collision.b2TimeOfImpact = b2TimeOfImpact;
+
+ function b2TOIInput() {
+ b2TOIInput.b2TOIInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2TOIInput = b2TOIInput;
+
+ function b2WorldManifold() {
+ b2WorldManifold.b2WorldManifold.apply(this, arguments);
+ if (this.constructor === b2WorldManifold) this.b2WorldManifold.apply(this, arguments);
+ };
+ Box2D.Collision.b2WorldManifold = b2WorldManifold;
+
+ function ClipVertex() {
+ ClipVertex.ClipVertex.apply(this, arguments);
+ };
+ Box2D.Collision.ClipVertex = ClipVertex;
+
+ function Features() {
+ Features.Features.apply(this, arguments);
+ };
+ Box2D.Collision.Features = Features;
+
+ function b2CircleShape() {
+ b2CircleShape.b2CircleShape.apply(this, arguments);
+ if (this.constructor === b2CircleShape) this.b2CircleShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2CircleShape = b2CircleShape;
+
+ function b2EdgeChainDef() {
+ b2EdgeChainDef.b2EdgeChainDef.apply(this, arguments);
+ if (this.constructor === b2EdgeChainDef) this.b2EdgeChainDef.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2EdgeChainDef = b2EdgeChainDef;
+
+ function b2EdgeShape() {
+ b2EdgeShape.b2EdgeShape.apply(this, arguments);
+ if (this.constructor === b2EdgeShape) this.b2EdgeShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2EdgeShape = b2EdgeShape;
+
+ function b2MassData() {
+ b2MassData.b2MassData.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2MassData = b2MassData;
+
+ function b2PolygonShape() {
+ b2PolygonShape.b2PolygonShape.apply(this, arguments);
+ if (this.constructor === b2PolygonShape) this.b2PolygonShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2PolygonShape = b2PolygonShape;
+
+ function b2Shape() {
+ b2Shape.b2Shape.apply(this, arguments);
+ if (this.constructor === b2Shape) this.b2Shape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2Shape = b2Shape;
+ Box2D.Common.b2internal = 'Box2D.Common.b2internal';
+
+ function b2Color() {
+ b2Color.b2Color.apply(this, arguments);
+ if (this.constructor === b2Color) this.b2Color.apply(this, arguments);
+ };
+ Box2D.Common.b2Color = b2Color;
+
+ function b2Settings() {
+ b2Settings.b2Settings.apply(this, arguments);
+ };
+ Box2D.Common.b2Settings = b2Settings;
+
+ function b2Mat22() {
+ b2Mat22.b2Mat22.apply(this, arguments);
+ if (this.constructor === b2Mat22) this.b2Mat22.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Mat22 = b2Mat22;
+
+ function b2Mat33() {
+ b2Mat33.b2Mat33.apply(this, arguments);
+ if (this.constructor === b2Mat33) this.b2Mat33.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Mat33 = b2Mat33;
+
+ function b2Math() {
+ b2Math.b2Math.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Math = b2Math;
+
+ function b2Sweep() {
+ b2Sweep.b2Sweep.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Sweep = b2Sweep;
+
+ function b2Transform() {
+ b2Transform.b2Transform.apply(this, arguments);
+ if (this.constructor === b2Transform) this.b2Transform.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Transform = b2Transform;
+
+ function b2Vec2() {
+ b2Vec2.b2Vec2.apply(this, arguments);
+ if (this.constructor === b2Vec2) this.b2Vec2.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Vec2 = b2Vec2;
+
+ function b2Vec3() {
+ b2Vec3.b2Vec3.apply(this, arguments);
+ if (this.constructor === b2Vec3) this.b2Vec3.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Vec3 = b2Vec3;
+
+ function b2Body() {
+ b2Body.b2Body.apply(this, arguments);
+ if (this.constructor === b2Body) this.b2Body.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Body = b2Body;
+
+ function b2BodyDef() {
+ b2BodyDef.b2BodyDef.apply(this, arguments);
+ if (this.constructor === b2BodyDef) this.b2BodyDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2BodyDef = b2BodyDef;
+
+ function b2ContactFilter() {
+ b2ContactFilter.b2ContactFilter.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactFilter = b2ContactFilter;
+
+ function b2ContactImpulse() {
+ b2ContactImpulse.b2ContactImpulse.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactImpulse = b2ContactImpulse;
+
+ function b2ContactListener() {
+ b2ContactListener.b2ContactListener.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactListener = b2ContactListener;
+
+ function b2ContactManager() {
+ b2ContactManager.b2ContactManager.apply(this, arguments);
+ if (this.constructor === b2ContactManager) this.b2ContactManager.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactManager = b2ContactManager;
+
+ function b2DebugDraw() {
+ b2DebugDraw.b2DebugDraw.apply(this, arguments);
+ if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2DebugDraw = b2DebugDraw;
+
+ function b2DestructionListener() {
+ b2DestructionListener.b2DestructionListener.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2DestructionListener = b2DestructionListener;
+
+ function b2FilterData() {
+ b2FilterData.b2FilterData.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2FilterData = b2FilterData;
+
+ function b2Fixture() {
+ b2Fixture.b2Fixture.apply(this, arguments);
+ if (this.constructor === b2Fixture) this.b2Fixture.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Fixture = b2Fixture;
+
+ function b2FixtureDef() {
+ b2FixtureDef.b2FixtureDef.apply(this, arguments);
+ if (this.constructor === b2FixtureDef) this.b2FixtureDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2FixtureDef = b2FixtureDef;
+
+ function b2Island() {
+ b2Island.b2Island.apply(this, arguments);
+ if (this.constructor === b2Island) this.b2Island.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Island = b2Island;
+
+ function b2TimeStep() {
+ b2TimeStep.b2TimeStep.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2TimeStep = b2TimeStep;
+
+ function b2World() {
+ b2World.b2World.apply(this, arguments);
+ if (this.constructor === b2World) this.b2World.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2World = b2World;
+
+ function b2CircleContact() {
+ b2CircleContact.b2CircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2CircleContact = b2CircleContact;
+
+ function b2Contact() {
+ b2Contact.b2Contact.apply(this, arguments);
+ if (this.constructor === b2Contact) this.b2Contact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2Contact = b2Contact;
+
+ function b2ContactConstraint() {
+ b2ContactConstraint.b2ContactConstraint.apply(this, arguments);
+ if (this.constructor === b2ContactConstraint) this.b2ContactConstraint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactConstraint = b2ContactConstraint;
+
+ function b2ContactConstraintPoint() {
+ b2ContactConstraintPoint.b2ContactConstraintPoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactConstraintPoint = b2ContactConstraintPoint;
+
+ function b2ContactEdge() {
+ b2ContactEdge.b2ContactEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactEdge = b2ContactEdge;
+
+ function b2ContactFactory() {
+ b2ContactFactory.b2ContactFactory.apply(this, arguments);
+ if (this.constructor === b2ContactFactory) this.b2ContactFactory.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactFactory = b2ContactFactory;
+
+ function b2ContactRegister() {
+ b2ContactRegister.b2ContactRegister.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactRegister = b2ContactRegister;
+
+ function b2ContactResult() {
+ b2ContactResult.b2ContactResult.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactResult = b2ContactResult;
+
+ function b2ContactSolver() {
+ b2ContactSolver.b2ContactSolver.apply(this, arguments);
+ if (this.constructor === b2ContactSolver) this.b2ContactSolver.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactSolver = b2ContactSolver;
+
+ function b2EdgeAndCircleContact() {
+ b2EdgeAndCircleContact.b2EdgeAndCircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2EdgeAndCircleContact = b2EdgeAndCircleContact;
+
+ function b2NullContact() {
+ b2NullContact.b2NullContact.apply(this, arguments);
+ if (this.constructor === b2NullContact) this.b2NullContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2NullContact = b2NullContact;
+
+ function b2PolyAndCircleContact() {
+ b2PolyAndCircleContact.b2PolyAndCircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolyAndCircleContact = b2PolyAndCircleContact;
+
+ function b2PolyAndEdgeContact() {
+ b2PolyAndEdgeContact.b2PolyAndEdgeContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolyAndEdgeContact = b2PolyAndEdgeContact;
+
+ function b2PolygonContact() {
+ b2PolygonContact.b2PolygonContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolygonContact = b2PolygonContact;
+
+ function b2PositionSolverManifold() {
+ b2PositionSolverManifold.b2PositionSolverManifold.apply(this, arguments);
+ if (this.constructor === b2PositionSolverManifold) this.b2PositionSolverManifold.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold = b2PositionSolverManifold;
+
+ function b2BuoyancyController() {
+ b2BuoyancyController.b2BuoyancyController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2BuoyancyController = b2BuoyancyController;
+
+ function b2ConstantAccelController() {
+ b2ConstantAccelController.b2ConstantAccelController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ConstantAccelController = b2ConstantAccelController;
+
+ function b2ConstantForceController() {
+ b2ConstantForceController.b2ConstantForceController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ConstantForceController = b2ConstantForceController;
+
+ function b2Controller() {
+ b2Controller.b2Controller.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2Controller = b2Controller;
+
+ function b2ControllerEdge() {
+ b2ControllerEdge.b2ControllerEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ControllerEdge = b2ControllerEdge;
+
+ function b2GravityController() {
+ b2GravityController.b2GravityController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2GravityController = b2GravityController;
+
+ function b2TensorDampingController() {
+ b2TensorDampingController.b2TensorDampingController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2TensorDampingController = b2TensorDampingController;
+
+ function b2DistanceJoint() {
+ b2DistanceJoint.b2DistanceJoint.apply(this, arguments);
+ if (this.constructor === b2DistanceJoint) this.b2DistanceJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2DistanceJoint = b2DistanceJoint;
+
+ function b2DistanceJointDef() {
+ b2DistanceJointDef.b2DistanceJointDef.apply(this, arguments);
+ if (this.constructor === b2DistanceJointDef) this.b2DistanceJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2DistanceJointDef = b2DistanceJointDef;
+
+ function b2FrictionJoint() {
+ b2FrictionJoint.b2FrictionJoint.apply(this, arguments);
+ if (this.constructor === b2FrictionJoint) this.b2FrictionJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2FrictionJoint = b2FrictionJoint;
+
+ function b2FrictionJointDef() {
+ b2FrictionJointDef.b2FrictionJointDef.apply(this, arguments);
+ if (this.constructor === b2FrictionJointDef) this.b2FrictionJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2FrictionJointDef = b2FrictionJointDef;
+
+ function b2GearJoint() {
+ b2GearJoint.b2GearJoint.apply(this, arguments);
+ if (this.constructor === b2GearJoint) this.b2GearJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2GearJoint = b2GearJoint;
+
+ function b2GearJointDef() {
+ b2GearJointDef.b2GearJointDef.apply(this, arguments);
+ if (this.constructor === b2GearJointDef) this.b2GearJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2GearJointDef = b2GearJointDef;
+
+ function b2Jacobian() {
+ b2Jacobian.b2Jacobian.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2Jacobian = b2Jacobian;
+
+ function b2Joint() {
+ b2Joint.b2Joint.apply(this, arguments);
+ if (this.constructor === b2Joint) this.b2Joint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2Joint = b2Joint;
+
+ function b2JointDef() {
+ b2JointDef.b2JointDef.apply(this, arguments);
+ if (this.constructor === b2JointDef) this.b2JointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2JointDef = b2JointDef;
+
+ function b2JointEdge() {
+ b2JointEdge.b2JointEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2JointEdge = b2JointEdge;
+
+ function b2LineJoint() {
+ b2LineJoint.b2LineJoint.apply(this, arguments);
+ if (this.constructor === b2LineJoint) this.b2LineJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2LineJoint = b2LineJoint;
+
+ function b2LineJointDef() {
+ b2LineJointDef.b2LineJointDef.apply(this, arguments);
+ if (this.constructor === b2LineJointDef) this.b2LineJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2LineJointDef = b2LineJointDef;
+
+ function b2MouseJoint() {
+ b2MouseJoint.b2MouseJoint.apply(this, arguments);
+ if (this.constructor === b2MouseJoint) this.b2MouseJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2MouseJoint = b2MouseJoint;
+
+ function b2MouseJointDef() {
+ b2MouseJointDef.b2MouseJointDef.apply(this, arguments);
+ if (this.constructor === b2MouseJointDef) this.b2MouseJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2MouseJointDef = b2MouseJointDef;
+
+ function b2PrismaticJoint() {
+ b2PrismaticJoint.b2PrismaticJoint.apply(this, arguments);
+ if (this.constructor === b2PrismaticJoint) this.b2PrismaticJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PrismaticJoint = b2PrismaticJoint;
+
+ function b2PrismaticJointDef() {
+ b2PrismaticJointDef.b2PrismaticJointDef.apply(this, arguments);
+ if (this.constructor === b2PrismaticJointDef) this.b2PrismaticJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PrismaticJointDef = b2PrismaticJointDef;
+
+ function b2PulleyJoint() {
+ b2PulleyJoint.b2PulleyJoint.apply(this, arguments);
+ if (this.constructor === b2PulleyJoint) this.b2PulleyJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PulleyJoint = b2PulleyJoint;
+
+ function b2PulleyJointDef() {
+ b2PulleyJointDef.b2PulleyJointDef.apply(this, arguments);
+ if (this.constructor === b2PulleyJointDef) this.b2PulleyJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PulleyJointDef = b2PulleyJointDef;
+
+ function b2RevoluteJoint() {
+ b2RevoluteJoint.b2RevoluteJoint.apply(this, arguments);
+ if (this.constructor === b2RevoluteJoint) this.b2RevoluteJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2RevoluteJoint = b2RevoluteJoint;
+
+ function b2RevoluteJointDef() {
+ b2RevoluteJointDef.b2RevoluteJointDef.apply(this, arguments);
+ if (this.constructor === b2RevoluteJointDef) this.b2RevoluteJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2RevoluteJointDef = b2RevoluteJointDef;
+
+ function b2WeldJoint() {
+ b2WeldJoint.b2WeldJoint.apply(this, arguments);
+ if (this.constructor === b2WeldJoint) this.b2WeldJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2WeldJoint = b2WeldJoint;
+
+ function b2WeldJointDef() {
+ b2WeldJointDef.b2WeldJointDef.apply(this, arguments);
+ if (this.constructor === b2WeldJointDef) this.b2WeldJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2WeldJointDef = b2WeldJointDef;
+})(); //definitions
+Box2D.postDefs = [];
+(function () {
+ var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ b2AABB.b2AABB = function () {
+ this.lowerBound = new b2Vec2();
+ this.upperBound = new b2Vec2();
+ };
+ b2AABB.prototype.IsValid = function () {
+ var dX = this.upperBound.x - this.lowerBound.x;
+ var dY = this.upperBound.y - this.lowerBound.y;
+ var valid = dX >= 0.0 && dY >= 0.0;
+ valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid();
+ return valid;
+ }
+ b2AABB.prototype.GetCenter = function () {
+ return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2);
+ }
+ b2AABB.prototype.GetExtents = function () {
+ return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2);
+ }
+ b2AABB.prototype.Contains = function (aabb) {
+ var result = true;
+ result = result && this.lowerBound.x <= aabb.lowerBound.x;
+ result = result && this.lowerBound.y <= aabb.lowerBound.y;
+ result = result && aabb.upperBound.x <= this.upperBound.x;
+ result = result && aabb.upperBound.y <= this.upperBound.y;
+ return result;
+ }
+ b2AABB.prototype.RayCast = function (output, input) {
+ var tmin = (-Number.MAX_VALUE);
+ var tmax = Number.MAX_VALUE;
+ var pX = input.p1.x;
+ var pY = input.p1.y;
+ var dX = input.p2.x - input.p1.x;
+ var dY = input.p2.y - input.p1.y;
+ var absDX = Math.abs(dX);
+ var absDY = Math.abs(dY);
+ var normal = output.normal;
+ var inv_d = 0;
+ var t1 = 0;
+ var t2 = 0;
+ var t3 = 0;
+ var s = 0; {
+ if (absDX < Number.MIN_VALUE) {
+ if (pX < this.lowerBound.x || this.upperBound.x < pX) return false;
+ }
+ else {
+ inv_d = 1.0 / dX;
+ t1 = (this.lowerBound.x - pX) * inv_d;
+ t2 = (this.upperBound.x - pX) * inv_d;
+ s = (-1.0);
+ if (t1 > t2) {
+ t3 = t1;
+ t1 = t2;
+ t2 = t3;
+ s = 1.0;
+ }
+ if (t1 > tmin) {
+ normal.x = s;
+ normal.y = 0;
+ tmin = t1;
+ }
+ tmax = Math.min(tmax, t2);
+ if (tmin > tmax) return false;
+ }
+ } {
+ if (absDY < Number.MIN_VALUE) {
+ if (pY < this.lowerBound.y || this.upperBound.y < pY) return false;
+ }
+ else {
+ inv_d = 1.0 / dY;
+ t1 = (this.lowerBound.y - pY) * inv_d;
+ t2 = (this.upperBound.y - pY) * inv_d;
+ s = (-1.0);
+ if (t1 > t2) {
+ t3 = t1;
+ t1 = t2;
+ t2 = t3;
+ s = 1.0;
+ }
+ if (t1 > tmin) {
+ normal.y = s;
+ normal.x = 0;
+ tmin = t1;
+ }
+ tmax = Math.min(tmax, t2);
+ if (tmin > tmax) return false;
+ }
+ }
+ output.fraction = tmin;
+ return true;
+ }
+ b2AABB.prototype.TestOverlap = function (other) {
+ var d1X = other.lowerBound.x - this.upperBound.x;
+ var d1Y = other.lowerBound.y - this.upperBound.y;
+ var d2X = this.lowerBound.x - other.upperBound.x;
+ var d2Y = this.lowerBound.y - other.upperBound.y;
+ if (d1X > 0.0 || d1Y > 0.0) return false;
+ if (d2X > 0.0 || d2Y > 0.0) return false;
+ return true;
+ }
+ b2AABB.Combine = function (aabb1, aabb2) {
+ var aabb = new b2AABB();
+ aabb.Combine(aabb1, aabb2);
+ return aabb;
+ }
+ b2AABB.prototype.Combine = function (aabb1, aabb2) {
+ this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x);
+ this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y);
+ this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x);
+ this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y);
+ }
+ b2Bound.b2Bound = function () {};
+ b2Bound.prototype.IsLower = function () {
+ return (this.value & 1) == 0;
+ }
+ b2Bound.prototype.IsUpper = function () {
+ return (this.value & 1) == 1;
+ }
+ b2Bound.prototype.Swap = function (b) {
+ var tempValue = this.value;
+ var tempProxy = this.proxy;
+ var tempStabbingCount = this.stabbingCount;
+ this.value = b.value;
+ this.proxy = b.proxy;
+ this.stabbingCount = b.stabbingCount;
+ b.value = tempValue;
+ b.proxy = tempProxy;
+ b.stabbingCount = tempStabbingCount;
+ }
+ b2BoundValues.b2BoundValues = function () {};
+ b2BoundValues.prototype.b2BoundValues = function () {
+ this.lowerValues = new Vector_a2j_Number();
+ this.lowerValues[0] = 0.0;
+ this.lowerValues[1] = 0.0;
+ this.upperValues = new Vector_a2j_Number();
+ this.upperValues[0] = 0.0;
+ this.upperValues[1] = 0.0;
+ }
+ b2Collision.b2Collision = function () {};
+ b2Collision.ClipSegmentToLine = function (vOut, vIn, normal, offset) {
+ if (offset === undefined) offset = 0;
+ var cv;
+ var numOut = 0;
+ cv = vIn[0];
+ var vIn0 = cv.v;
+ cv = vIn[1];
+ var vIn1 = cv.v;
+ var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset;
+ var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset;
+ if (distance0 <= 0.0) vOut[numOut++].Set(vIn[0]);
+ if (distance1 <= 0.0) vOut[numOut++].Set(vIn[1]);
+ if (distance0 * distance1 < 0.0) {
+ var interp = distance0 / (distance0 - distance1);
+ cv = vOut[numOut];
+ var tVec = cv.v;
+ tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x);
+ tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y);
+ cv = vOut[numOut];
+ var cv2;
+ if (distance0 > 0.0) {
+ cv2 = vIn[0];
+ cv.id = cv2.id;
+ }
+ else {
+ cv2 = vIn[1];
+ cv.id = cv2.id;
+ }++numOut;
+ }
+ return numOut;
+ }
+ b2Collision.EdgeSeparation = function (poly1, xf1, edge1, poly2, xf2) {
+ if (edge1 === undefined) edge1 = 0;
+ var count1 = parseInt(poly1.m_vertexCount);
+ var vertices1 = poly1.m_vertices;
+ var normals1 = poly1.m_normals;
+ var count2 = parseInt(poly2.m_vertexCount);
+ var vertices2 = poly2.m_vertices;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = normals1[edge1];
+ var normal1WorldX = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var normal1WorldY = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ var normal1X = (tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY);
+ var normal1Y = (tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY);
+ var index = 0;
+ var minDot = Number.MAX_VALUE;
+ for (var i = 0; i < count2; ++i) {
+ tVec = vertices2[i];
+ var dot = tVec.x * normal1X + tVec.y * normal1Y;
+ if (dot < minDot) {
+ minDot = dot;
+ index = i;
+ }
+ }
+ tVec = vertices1[edge1];
+ tMat = xf1.R;
+ var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = vertices2[index];
+ tMat = xf2.R;
+ var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ v2X -= v1X;
+ v2Y -= v1Y;
+ var separation = v2X * normal1WorldX + v2Y * normal1WorldY;
+ return separation;
+ }
+ b2Collision.FindMaxSeparation = function (edgeIndex, poly1, xf1, poly2, xf2) {
+ var count1 = parseInt(poly1.m_vertexCount);
+ var normals1 = poly1.m_normals;
+ var tVec;
+ var tMat;
+ tMat = xf2.R;
+ tVec = poly2.m_centroid;
+ var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf1.R;
+ tVec = poly1.m_centroid;
+ dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dLocal1X = (dX * xf1.R.col1.x + dY * xf1.R.col1.y);
+ var dLocal1Y = (dX * xf1.R.col2.x + dY * xf1.R.col2.y);
+ var edge = 0;
+ var maxDot = (-Number.MAX_VALUE);
+ for (var i = 0; i < count1; ++i) {
+ tVec = normals1[i];
+ var dot = (tVec.x * dLocal1X + tVec.y * dLocal1Y);
+ if (dot > maxDot) {
+ maxDot = dot;
+ edge = i;
+ }
+ }
+ var s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+ var prevEdge = parseInt(edge - 1 >= 0 ? edge - 1 : count1 - 1);
+ var sPrev = b2Collision.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
+ var nextEdge = parseInt(edge + 1 < count1 ? edge + 1 : 0);
+ var sNext = b2Collision.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
+ var bestEdge = 0;
+ var bestSeparation = 0;
+ var increment = 0;
+ if (sPrev > s && sPrev > sNext) {
+ increment = (-1);
+ bestEdge = prevEdge;
+ bestSeparation = sPrev;
+ }
+ else if (sNext > s) {
+ increment = 1;
+ bestEdge = nextEdge;
+ bestSeparation = sNext;
+ }
+ else {
+ edgeIndex[0] = edge;
+ return s;
+ }
+ while (true) {
+ if (increment == (-1)) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
+ else edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+ if (s > bestSeparation) {
+ bestEdge = edge;
+ bestSeparation = s;
+ }
+ else {
+ break;
+ }
+ }
+ edgeIndex[0] = bestEdge;
+ return bestSeparation;
+ }
+ b2Collision.FindIncidentEdge = function (c, poly1, xf1, edge1, poly2, xf2) {
+ if (edge1 === undefined) edge1 = 0;
+ var count1 = parseInt(poly1.m_vertexCount);
+ var normals1 = poly1.m_normals;
+ var count2 = parseInt(poly2.m_vertexCount);
+ var vertices2 = poly2.m_vertices;
+ var normals2 = poly2.m_normals;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = normals1[edge1];
+ var normal1X = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var normal1Y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ var tX = (tMat.col1.x * normal1X + tMat.col1.y * normal1Y);
+ normal1Y = (tMat.col2.x * normal1X + tMat.col2.y * normal1Y);
+ normal1X = tX;
+ var index = 0;
+ var minDot = Number.MAX_VALUE;
+ for (var i = 0; i < count2; ++i) {
+ tVec = normals2[i];
+ var dot = (normal1X * tVec.x + normal1Y * tVec.y);
+ if (dot < minDot) {
+ minDot = dot;
+ index = i;
+ }
+ }
+ var tClip;
+ var i1 = parseInt(index);
+ var i2 = parseInt(i1 + 1 < count2 ? i1 + 1 : 0);
+ tClip = c[0];
+ tVec = vertices2[i1];
+ tMat = xf2.R;
+ tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tClip.id.features.referenceEdge = edge1;
+ tClip.id.features.incidentEdge = i1;
+ tClip.id.features.incidentVertex = 0;
+ tClip = c[1];
+ tVec = vertices2[i2];
+ tMat = xf2.R;
+ tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tClip.id.features.referenceEdge = edge1;
+ tClip.id.features.incidentEdge = i2;
+ tClip.id.features.incidentVertex = 1;
+ }
+ b2Collision.MakeClipPointVector = function () {
+ var r = new Vector(2);
+ r[0] = new ClipVertex();
+ r[1] = new ClipVertex();
+ return r;
+ }
+ b2Collision.CollidePolygons = function (manifold, polyA, xfA, polyB, xfB) {
+ var cv;
+ manifold.m_pointCount = 0;
+ var totalRadius = polyA.m_radius + polyB.m_radius;
+ var edgeA = 0;
+ b2Collision.s_edgeAO[0] = edgeA;
+ var separationA = b2Collision.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB);
+ edgeA = b2Collision.s_edgeAO[0];
+ if (separationA > totalRadius) return;
+ var edgeB = 0;
+ b2Collision.s_edgeBO[0] = edgeB;
+ var separationB = b2Collision.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA);
+ edgeB = b2Collision.s_edgeBO[0];
+ if (separationB > totalRadius) return;
+ var poly1;
+ var poly2;
+ var xf1;
+ var xf2;
+ var edge1 = 0;
+ var flip = 0;
+ var k_relativeTol = 0.98;
+ var k_absoluteTol = 0.001;
+ var tMat;
+ if (separationB > k_relativeTol * separationA + k_absoluteTol) {
+ poly1 = polyB;
+ poly2 = polyA;
+ xf1 = xfB;
+ xf2 = xfA;
+ edge1 = edgeB;
+ manifold.m_type = b2Manifold.e_faceB;
+ flip = 1;
+ }
+ else {
+ poly1 = polyA;
+ poly2 = polyB;
+ xf1 = xfA;
+ xf2 = xfB;
+ edge1 = edgeA;
+ manifold.m_type = b2Manifold.e_faceA;
+ flip = 0;
+ }
+ var incidentEdge = b2Collision.s_incidentEdge;
+ b2Collision.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+ var count1 = parseInt(poly1.m_vertexCount);
+ var vertices1 = poly1.m_vertices;
+ var local_v11 = vertices1[edge1];
+ var local_v12;
+ if (edge1 + 1 < count1) {
+ local_v12 = vertices1[parseInt(edge1 + 1)];
+ }
+ else {
+ local_v12 = vertices1[0];
+ }
+ var localTangent = b2Collision.s_localTangent;
+ localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y);
+ localTangent.Normalize();
+ var localNormal = b2Collision.s_localNormal;
+ localNormal.x = localTangent.y;
+ localNormal.y = (-localTangent.x);
+ var planePoint = b2Collision.s_planePoint;
+ planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y));
+ var tangent = b2Collision.s_tangent;
+ tMat = xf1.R;
+ tangent.x = (tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y);
+ tangent.y = (tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y);
+ var tangent2 = b2Collision.s_tangent2;
+ tangent2.x = (-tangent.x);
+ tangent2.y = (-tangent.y);
+ var normal = b2Collision.s_normal;
+ normal.x = tangent.y;
+ normal.y = (-tangent.x);
+ var v11 = b2Collision.s_v11;
+ var v12 = b2Collision.s_v12;
+ v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y);
+ v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y);
+ v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y);
+ v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y);
+ var frontOffset = normal.x * v11.x + normal.y * v11.y;
+ var sideOffset1 = (-tangent.x * v11.x) - tangent.y * v11.y + totalRadius;
+ var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius;
+ var clipPoints1 = b2Collision.s_clipPoints1;
+ var clipPoints2 = b2Collision.s_clipPoints2;
+ var np = 0;
+ np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1);
+ if (np < 2) return;
+ np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2);
+ if (np < 2) return;
+ manifold.m_localPlaneNormal.SetV(localNormal);
+ manifold.m_localPoint.SetV(planePoint);
+ var pointCount = 0;
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i) {
+ cv = clipPoints2[i];
+ var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset;
+ if (separation <= totalRadius) {
+ var cp = manifold.m_points[pointCount];
+ tMat = xf2.R;
+ var tX = cv.v.x - xf2.position.x;
+ var tY = cv.v.y - xf2.position.y;
+ cp.m_localPoint.x = (tX * tMat.col1.x + tY * tMat.col1.y);
+ cp.m_localPoint.y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ cp.m_id.Set(cv.id);
+ cp.m_id.features.flip = flip;
+ ++pointCount;
+ }
+ }
+ manifold.m_pointCount = pointCount;
+ }
+ b2Collision.CollideCircles = function (manifold, circle1, xf1, circle2, xf2) {
+ manifold.m_pointCount = 0;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = circle1.m_p;
+ var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ tVec = circle2.m_p;
+ var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var distSqr = dX * dX + dY * dY;
+ var radius = circle1.m_radius + circle2.m_radius;
+ if (distSqr > radius * radius) {
+ return;
+ }
+ manifold.m_type = b2Manifold.e_circles;
+ manifold.m_localPoint.SetV(circle1.m_p);
+ manifold.m_localPlaneNormal.SetZero();
+ manifold.m_pointCount = 1;
+ manifold.m_points[0].m_localPoint.SetV(circle2.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ b2Collision.CollidePolygonAndCircle = function (manifold, polygon, xf1, circle, xf2) {
+ manifold.m_pointCount = 0;
+ var tPoint;
+ var dX = 0;
+ var dY = 0;
+ var positionX = 0;
+ var positionY = 0;
+ var tVec;
+ var tMat;
+ tMat = xf2.R;
+ tVec = circle.m_p;
+ var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ dX = cX - xf1.position.x;
+ dY = cY - xf1.position.y;
+ tMat = xf1.R;
+ var cLocalX = (dX * tMat.col1.x + dY * tMat.col1.y);
+ var cLocalY = (dX * tMat.col2.x + dY * tMat.col2.y);
+ var dist = 0;
+ var normalIndex = 0;
+ var separation = (-Number.MAX_VALUE);
+ var radius = polygon.m_radius + circle.m_radius;
+ var vertexCount = parseInt(polygon.m_vertexCount);
+ var vertices = polygon.m_vertices;
+ var normals = polygon.m_normals;
+ for (var i = 0; i < vertexCount; ++i) {
+ tVec = vertices[i];
+ dX = cLocalX - tVec.x;
+ dY = cLocalY - tVec.y;
+ tVec = normals[i];
+ var s = tVec.x * dX + tVec.y * dY;
+ if (s > radius) {
+ return;
+ }
+ if (s > separation) {
+ separation = s;
+ normalIndex = i;
+ }
+ }
+ var vertIndex1 = parseInt(normalIndex);
+ var vertIndex2 = parseInt(vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0);
+ var v1 = vertices[vertIndex1];
+ var v2 = vertices[vertIndex2];
+ if (separation < Number.MIN_VALUE) {
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.SetV(normals[normalIndex]);
+ manifold.m_localPoint.x = 0.5 * (v1.x + v2.x);
+ manifold.m_localPoint.y = 0.5 * (v1.y + v2.y);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ return;
+ }
+ var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y);
+ var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y);
+ if (u1 <= 0.0) {
+ if ((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = cLocalX - v1.x;
+ manifold.m_localPlaneNormal.y = cLocalY - v1.y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.SetV(v1);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ else if (u2 <= 0) {
+ if ((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = cLocalX - v2.x;
+ manifold.m_localPlaneNormal.y = cLocalY - v2.y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.SetV(v2);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ else {
+ var faceCenterX = 0.5 * (v1.x + v2.x);
+ var faceCenterY = 0.5 * (v1.y + v2.y);
+ separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y;
+ if (separation > radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = normals[vertIndex1].x;
+ manifold.m_localPlaneNormal.y = normals[vertIndex1].y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.Set(faceCenterX, faceCenterY);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ }
+ b2Collision.TestOverlap = function (a, b) {
+ var t1 = b.lowerBound;
+ var t2 = a.upperBound;
+ var d1X = t1.x - t2.x;
+ var d1Y = t1.y - t2.y;
+ t1 = a.lowerBound;
+ t2 = b.upperBound;
+ var d2X = t1.x - t2.x;
+ var d2Y = t1.y - t2.y;
+ if (d1X > 0.0 || d1Y > 0.0) return false;
+ if (d2X > 0.0 || d2Y > 0.0) return false;
+ return true;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_edgeAO = new Vector_a2j_Number(1);
+ Box2D.Collision.b2Collision.s_edgeBO = new Vector_a2j_Number(1);
+ Box2D.Collision.b2Collision.s_localTangent = new b2Vec2();
+ Box2D.Collision.b2Collision.s_localNormal = new b2Vec2();
+ Box2D.Collision.b2Collision.s_planePoint = new b2Vec2();
+ Box2D.Collision.b2Collision.s_normal = new b2Vec2();
+ Box2D.Collision.b2Collision.s_tangent = new b2Vec2();
+ Box2D.Collision.b2Collision.s_tangent2 = new b2Vec2();
+ Box2D.Collision.b2Collision.s_v11 = new b2Vec2();
+ Box2D.Collision.b2Collision.s_v12 = new b2Vec2();
+ Box2D.Collision.b2Collision.b2CollidePolyTempVec = new b2Vec2();
+ Box2D.Collision.b2Collision.b2_nullFeature = 0x000000ff;
+ });
+ b2ContactID.b2ContactID = function () {
+ this.features = new Features();
+ };
+ b2ContactID.prototype.b2ContactID = function () {
+ this.features._m_id = this;
+ }
+ b2ContactID.prototype.Set = function (id) {
+ this.key = id._key;
+ }
+ b2ContactID.prototype.Copy = function () {
+ var id = new b2ContactID();
+ id.key = this.key;
+ return id;
+ }
+ Object.defineProperty(b2ContactID.prototype, 'key', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._key;
+ }
+ });
+ Object.defineProperty(b2ContactID.prototype, 'key', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._key = value;
+ this.features._referenceEdge = this._key & 0x000000ff;
+ this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff;
+ this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff;
+ this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff;
+ }
+ });
+ b2ContactPoint.b2ContactPoint = function () {
+ this.position = new b2Vec2();
+ this.velocity = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ b2Distance.b2Distance = function () {};
+ b2Distance.Distance = function (output, cache, input) {
+ ++b2Distance.b2_gjkCalls;
+ var proxyA = input.proxyA;
+ var proxyB = input.proxyB;
+ var transformA = input.transformA;
+ var transformB = input.transformB;
+ var simplex = b2Distance.s_simplex;
+ simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
+ var vertices = simplex.m_vertices;
+ var k_maxIters = 20;
+ var saveA = b2Distance.s_saveA;
+ var saveB = b2Distance.s_saveB;
+ var saveCount = 0;
+ var closestPoint = simplex.GetClosestPoint();
+ var distanceSqr1 = closestPoint.LengthSquared();
+ var distanceSqr2 = distanceSqr1;
+ var i = 0;
+ var p;
+ var iter = 0;
+ while (iter < k_maxIters) {
+ saveCount = simplex.m_count;
+ for (i = 0;
+ i < saveCount; i++) {
+ saveA[i] = vertices[i].indexA;
+ saveB[i] = vertices[i].indexB;
+ }
+ switch (simplex.m_count) {
+ case 1:
+ break;
+ case 2:
+ simplex.Solve2();
+ break;
+ case 3:
+ simplex.Solve3();
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ }
+ if (simplex.m_count == 3) {
+ break;
+ }
+ p = simplex.GetClosestPoint();
+ distanceSqr2 = p.LengthSquared();
+ if (distanceSqr2 > distanceSqr1) {}
+ distanceSqr1 = distanceSqr2;
+ var d = simplex.GetSearchDirection();
+ if (d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) {
+ break;
+ }
+ var vertex = vertices[simplex.m_count];
+ vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative()));
+ vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA));
+ vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d));
+ vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB));
+ vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA);
+ ++iter;
+ ++b2Distance.b2_gjkIters;
+ var duplicate = false;
+ for (i = 0;
+ i < saveCount; i++) {
+ if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) {
+ duplicate = true;
+ break;
+ }
+ }
+ if (duplicate) {
+ break;
+ }++simplex.m_count;
+ }
+ b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter);
+ simplex.GetWitnessPoints(output.pointA, output.pointB);
+ output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length();
+ output.iterations = iter;
+ simplex.WriteCache(cache);
+ if (input.useRadii) {
+ var rA = proxyA.m_radius;
+ var rB = proxyB.m_radius;
+ if (output.distance > rA + rB && output.distance > Number.MIN_VALUE) {
+ output.distance -= rA + rB;
+ var normal = b2Math.SubtractVV(output.pointB, output.pointA);
+ normal.Normalize();
+ output.pointA.x += rA * normal.x;
+ output.pointA.y += rA * normal.y;
+ output.pointB.x -= rB * normal.x;
+ output.pointB.y -= rB * normal.y;
+ }
+ else {
+ p = new b2Vec2();
+ p.x = .5 * (output.pointA.x + output.pointB.x);
+ p.y = .5 * (output.pointA.y + output.pointB.y);
+ output.pointA.x = output.pointB.x = p.x;
+ output.pointA.y = output.pointB.y = p.y;
+ output.distance = 0.0;
+ }
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Distance.s_simplex = new b2Simplex();
+ Box2D.Collision.b2Distance.s_saveA = new Vector_a2j_Number(3);
+ Box2D.Collision.b2Distance.s_saveB = new Vector_a2j_Number(3);
+ });
+ b2DistanceInput.b2DistanceInput = function () {};
+ b2DistanceOutput.b2DistanceOutput = function () {
+ this.pointA = new b2Vec2();
+ this.pointB = new b2Vec2();
+ };
+ b2DistanceProxy.b2DistanceProxy = function () {};
+ b2DistanceProxy.prototype.Set = function (shape) {
+ switch (shape.GetType()) {
+ case b2Shape.e_circleShape:
+ {
+ var circle = (shape instanceof b2CircleShape ? shape : null);
+ this.m_vertices = new Vector(1, true);
+ this.m_vertices[0] = circle.m_p;
+ this.m_count = 1;
+ this.m_radius = circle.m_radius;
+ }
+ break;
+ case b2Shape.e_polygonShape:
+ {
+ var polygon = (shape instanceof b2PolygonShape ? shape : null);
+ this.m_vertices = polygon.m_vertices;
+ this.m_count = polygon.m_vertexCount;
+ this.m_radius = polygon.m_radius;
+ }
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ }
+ }
+ b2DistanceProxy.prototype.GetSupport = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_count; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return bestIndex;
+ }
+ b2DistanceProxy.prototype.GetSupportVertex = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_count; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return this.m_vertices[bestIndex];
+ }
+ b2DistanceProxy.prototype.GetVertexCount = function () {
+ return this.m_count;
+ }
+ b2DistanceProxy.prototype.GetVertex = function (index) {
+ if (index === undefined) index = 0;
+ b2Settings.b2Assert(0 <= index && index < this.m_count);
+ return this.m_vertices[index];
+ }
+ b2DynamicTree.b2DynamicTree = function () {};
+ b2DynamicTree.prototype.b2DynamicTree = function () {
+ this.m_root = null;
+ this.m_freeList = null;
+ this.m_path = 0;
+ this.m_insertionCount = 0;
+ }
+ b2DynamicTree.prototype.CreateProxy = function (aabb, userData) {
+ var node = this.AllocateNode();
+ var extendX = b2Settings.b2_aabbExtension;
+ var extendY = b2Settings.b2_aabbExtension;
+ node.aabb.lowerBound.x = aabb.lowerBound.x - extendX;
+ node.aabb.lowerBound.y = aabb.lowerBound.y - extendY;
+ node.aabb.upperBound.x = aabb.upperBound.x + extendX;
+ node.aabb.upperBound.y = aabb.upperBound.y + extendY;
+ node.userData = userData;
+ this.InsertLeaf(node);
+ return node;
+ }
+ b2DynamicTree.prototype.DestroyProxy = function (proxy) {
+ this.RemoveLeaf(proxy);
+ this.FreeNode(proxy);
+ }
+ b2DynamicTree.prototype.MoveProxy = function (proxy, aabb, displacement) {
+ b2Settings.b2Assert(proxy.IsLeaf());
+ if (proxy.aabb.Contains(aabb)) {
+ return false;
+ }
+ this.RemoveLeaf(proxy);
+ var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : (-displacement.x));
+ var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : (-displacement.y));
+ proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX;
+ proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY;
+ proxy.aabb.upperBound.x = aabb.upperBound.x + extendX;
+ proxy.aabb.upperBound.y = aabb.upperBound.y + extendY;
+ this.InsertLeaf(proxy);
+ return true;
+ }
+ b2DynamicTree.prototype.Rebalance = function (iterations) {
+ if (iterations === undefined) iterations = 0;
+ if (this.m_root == null) return;
+ for (var i = 0; i < iterations; i++) {
+ var node = this.m_root;
+ var bit = 0;
+ while (node.IsLeaf() == false) {
+ node = (this.m_path >> bit) & 1 ? node.child2 : node.child1;
+ bit = (bit + 1) & 31;
+ }++this.m_path;
+ this.RemoveLeaf(node);
+ this.InsertLeaf(node);
+ }
+ }
+ b2DynamicTree.prototype.GetFatAABB = function (proxy) {
+ return proxy.aabb;
+ }
+ b2DynamicTree.prototype.GetUserData = function (proxy) {
+ return proxy.userData;
+ }
+ b2DynamicTree.prototype.Query = function (callback, aabb) {
+ if (this.m_root == null) return;
+ var stack = new Vector();
+ var count = 0;
+ stack[count++] = this.m_root;
+ while (count > 0) {
+ var node = stack[--count];
+ if (node.aabb.TestOverlap(aabb)) {
+ if (node.IsLeaf()) {
+ var proceed = callback(node);
+ if (!proceed) return;
+ }
+ else {
+ stack[count++] = node.child1;
+ stack[count++] = node.child2;
+ }
+ }
+ }
+ }
+ b2DynamicTree.prototype.RayCast = function (callback, input) {
+ if (this.m_root == null) return;
+ var p1 = input.p1;
+ var p2 = input.p2;
+ var r = b2Math.SubtractVV(p1, p2);
+ r.Normalize();
+ var v = b2Math.CrossFV(1.0, r);
+ var abs_v = b2Math.AbsV(v);
+ var maxFraction = input.maxFraction;
+ var segmentAABB = new b2AABB();
+ var tX = 0;
+ var tY = 0; {
+ tX = p1.x + maxFraction * (p2.x - p1.x);
+ tY = p1.y + maxFraction * (p2.y - p1.y);
+ segmentAABB.lowerBound.x = Math.min(p1.x, tX);
+ segmentAABB.lowerBound.y = Math.min(p1.y, tY);
+ segmentAABB.upperBound.x = Math.max(p1.x, tX);
+ segmentAABB.upperBound.y = Math.max(p1.y, tY);
+ }
+ var stack = new Vector();
+ var count = 0;
+ stack[count++] = this.m_root;
+ while (count > 0) {
+ var node = stack[--count];
+ if (node.aabb.TestOverlap(segmentAABB) == false) {
+ continue;
+ }
+ var c = node.aabb.GetCenter();
+ var h = node.aabb.GetExtents();
+ var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y;
+ if (separation > 0.0) continue;
+ if (node.IsLeaf()) {
+ var subInput = new b2RayCastInput();
+ subInput.p1 = input.p1;
+ subInput.p2 = input.p2;
+ subInput.maxFraction = input.maxFraction;
+ maxFraction = callback(subInput, node);
+ if (maxFraction == 0.0) return;
+ if (maxFraction > 0.0) {
+ tX = p1.x + maxFraction * (p2.x - p1.x);
+ tY = p1.y + maxFraction * (p2.y - p1.y);
+ segmentAABB.lowerBound.x = Math.min(p1.x, tX);
+ segmentAABB.lowerBound.y = Math.min(p1.y, tY);
+ segmentAABB.upperBound.x = Math.max(p1.x, tX);
+ segmentAABB.upperBound.y = Math.max(p1.y, tY);
+ }
+ }
+ else {
+ stack[count++] = node.child1;
+ stack[count++] = node.child2;
+ }
+ }
+ }
+ b2DynamicTree.prototype.AllocateNode = function () {
+ if (this.m_freeList) {
+ var node = this.m_freeList;
+ this.m_freeList = node.parent;
+ node.parent = null;
+ node.child1 = null;
+ node.child2 = null;
+ return node;
+ }
+ return new b2DynamicTreeNode();
+ }
+ b2DynamicTree.prototype.FreeNode = function (node) {
+ node.parent = this.m_freeList;
+ this.m_freeList = node;
+ }
+ b2DynamicTree.prototype.InsertLeaf = function (leaf) {
+ ++this.m_insertionCount;
+ if (this.m_root == null) {
+ this.m_root = leaf;
+ this.m_root.parent = null;
+ return;
+ }
+ var center = leaf.aabb.GetCenter();
+ var sibling = this.m_root;
+ if (sibling.IsLeaf() == false) {
+ do {
+ var child1 = sibling.child1;
+ var child2 = sibling.child2;
+ var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y);
+ var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y);
+ if (norm1 < norm2) {
+ sibling = child1;
+ }
+ else {
+ sibling = child2;
+ }
+ }
+ while (sibling.IsLeaf() == false)
+ }
+ var node1 = sibling.parent;
+ var node2 = this.AllocateNode();
+ node2.parent = node1;
+ node2.userData = null;
+ node2.aabb.Combine(leaf.aabb, sibling.aabb);
+ if (node1) {
+ if (sibling.parent.child1 == sibling) {
+ node1.child1 = node2;
+ }
+ else {
+ node1.child2 = node2;
+ }
+ node2.child1 = sibling;
+ node2.child2 = leaf;
+ sibling.parent = node2;
+ leaf.parent = node2;
+ do {
+ if (node1.aabb.Contains(node2.aabb)) break;
+ node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb);
+ node2 = node1;
+ node1 = node1.parent;
+ }
+ while (node1)
+ }
+ else {
+ node2.child1 = sibling;
+ node2.child2 = leaf;
+ sibling.parent = node2;
+ leaf.parent = node2;
+ this.m_root = node2;
+ }
+ }
+ b2DynamicTree.prototype.RemoveLeaf = function (leaf) {
+ if (leaf == this.m_root) {
+ this.m_root = null;
+ return;
+ }
+ var node2 = leaf.parent;
+ var node1 = node2.parent;
+ var sibling;
+ if (node2.child1 == leaf) {
+ sibling = node2.child2;
+ }
+ else {
+ sibling = node2.child1;
+ }
+ if (node1) {
+ if (node1.child1 == node2) {
+ node1.child1 = sibling;
+ }
+ else {
+ node1.child2 = sibling;
+ }
+ sibling.parent = node1;
+ this.FreeNode(node2);
+ while (node1) {
+ var oldAABB = node1.aabb;
+ node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb);
+ if (oldAABB.Contains(node1.aabb)) break;
+ node1 = node1.parent;
+ }
+ }
+ else {
+ this.m_root = sibling;
+ sibling.parent = null;
+ this.FreeNode(node2);
+ }
+ }
+ b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () {
+ this.m_tree = new b2DynamicTree();
+ this.m_moveBuffer = new Vector();
+ this.m_pairBuffer = new Vector();
+ this.m_pairCount = 0;
+ };
+ b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) {
+ var proxy = this.m_tree.CreateProxy(aabb, userData);
+ ++this.m_proxyCount;
+ this.BufferMove(proxy);
+ return proxy;
+ }
+ b2DynamicTreeBroadPhase.prototype.DestroyProxy = function (proxy) {
+ this.UnBufferMove(proxy);
+ --this.m_proxyCount;
+ this.m_tree.DestroyProxy(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.MoveProxy = function (proxy, aabb, displacement) {
+ var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement);
+ if (buffer) {
+ this.BufferMove(proxy);
+ }
+ }
+ b2DynamicTreeBroadPhase.prototype.TestOverlap = function (proxyA, proxyB) {
+ var aabbA = this.m_tree.GetFatAABB(proxyA);
+ var aabbB = this.m_tree.GetFatAABB(proxyB);
+ return aabbA.TestOverlap(aabbB);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetUserData = function (proxy) {
+ return this.m_tree.GetUserData(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetFatAABB = function (proxy) {
+ return this.m_tree.GetFatAABB(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetProxyCount = function () {
+ return this.m_proxyCount;
+ }
+ b2DynamicTreeBroadPhase.prototype.UpdatePairs = function (callback) {
+ var __this = this;
+ __this.m_pairCount = 0;
+ var i = 0,
+ queryProxy;
+ for (i = 0;
+ i < __this.m_moveBuffer.length; ++i) {
+ queryProxy = __this.m_moveBuffer[i];
+
+ function QueryCallback(proxy) {
+ if (proxy == queryProxy) return true;
+ if (__this.m_pairCount == __this.m_pairBuffer.length) {
+ __this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair();
+ }
+ var pair = __this.m_pairBuffer[__this.m_pairCount];
+ pair.proxyA = proxy < queryProxy ? proxy : queryProxy;
+ pair.proxyB = proxy >= queryProxy ? proxy : queryProxy;++__this.m_pairCount;
+ return true;
+ };
+ var fatAABB = __this.m_tree.GetFatAABB(queryProxy);
+ __this.m_tree.Query(QueryCallback, fatAABB);
+ }
+ __this.m_moveBuffer.length = 0;
+ for (var i = 0; i < __this.m_pairCount;) {
+ var primaryPair = __this.m_pairBuffer[i];
+ var userDataA = __this.m_tree.GetUserData(primaryPair.proxyA);
+ var userDataB = __this.m_tree.GetUserData(primaryPair.proxyB);
+ callback(userDataA, userDataB);
+ ++i;
+ while (i < __this.m_pairCount) {
+ var pair = __this.m_pairBuffer[i];
+ if (pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) {
+ break;
+ }++i;
+ }
+ }
+ }
+ b2DynamicTreeBroadPhase.prototype.Query = function (callback, aabb) {
+ this.m_tree.Query(callback, aabb);
+ }
+ b2DynamicTreeBroadPhase.prototype.RayCast = function (callback, input) {
+ this.m_tree.RayCast(callback, input);
+ }
+ b2DynamicTreeBroadPhase.prototype.Validate = function () {}
+ b2DynamicTreeBroadPhase.prototype.Rebalance = function (iterations) {
+ if (iterations === undefined) iterations = 0;
+ this.m_tree.Rebalance(iterations);
+ }
+ b2DynamicTreeBroadPhase.prototype.BufferMove = function (proxy) {
+ this.m_moveBuffer[this.m_moveBuffer.length] = proxy;
+ }
+ b2DynamicTreeBroadPhase.prototype.UnBufferMove = function (proxy) {
+ var i = parseInt(this.m_moveBuffer.indexOf(proxy));
+ this.m_moveBuffer.splice(i, 1);
+ }
+ b2DynamicTreeBroadPhase.prototype.ComparePairs = function (pair1, pair2) {
+ return 0;
+ }
+ b2DynamicTreeBroadPhase.__implements = {};
+ b2DynamicTreeBroadPhase.__implements[IBroadPhase] = true;
+ b2DynamicTreeNode.b2DynamicTreeNode = function () {
+ this.aabb = new b2AABB();
+ };
+ b2DynamicTreeNode.prototype.IsLeaf = function () {
+ return this.child1 == null;
+ }
+ b2DynamicTreePair.b2DynamicTreePair = function () {};
+ b2Manifold.b2Manifold = function () {
+ this.m_pointCount = 0;
+ };
+ b2Manifold.prototype.b2Manifold = function () {
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2ManifoldPoint();
+ }
+ this.m_localPlaneNormal = new b2Vec2();
+ this.m_localPoint = new b2Vec2();
+ }
+ b2Manifold.prototype.Reset = function () {
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Reset();
+ }
+ this.m_localPlaneNormal.SetZero();
+ this.m_localPoint.SetZero();
+ this.m_type = 0;
+ this.m_pointCount = 0;
+ }
+ b2Manifold.prototype.Set = function (m) {
+ this.m_pointCount = m.m_pointCount;
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Set(m.m_points[i]);
+ }
+ this.m_localPlaneNormal.SetV(m.m_localPlaneNormal);
+ this.m_localPoint.SetV(m.m_localPoint);
+ this.m_type = m.m_type;
+ }
+ b2Manifold.prototype.Copy = function () {
+ var copy = new b2Manifold();
+ copy.Set(this);
+ return copy;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Manifold.e_circles = 0x0001;
+ Box2D.Collision.b2Manifold.e_faceA = 0x0002;
+ Box2D.Collision.b2Manifold.e_faceB = 0x0004;
+ });
+ b2ManifoldPoint.b2ManifoldPoint = function () {
+ this.m_localPoint = new b2Vec2();
+ this.m_id = new b2ContactID();
+ };
+ b2ManifoldPoint.prototype.b2ManifoldPoint = function () {
+ this.Reset();
+ }
+ b2ManifoldPoint.prototype.Reset = function () {
+ this.m_localPoint.SetZero();
+ this.m_normalImpulse = 0.0;
+ this.m_tangentImpulse = 0.0;
+ this.m_id.key = 0;
+ }
+ b2ManifoldPoint.prototype.Set = function (m) {
+ this.m_localPoint.SetV(m.m_localPoint);
+ this.m_normalImpulse = m.m_normalImpulse;
+ this.m_tangentImpulse = m.m_tangentImpulse;
+ this.m_id.Set(m.m_id);
+ }
+ b2Point.b2Point = function () {
+ this.p = new b2Vec2();
+ };
+ b2Point.prototype.Support = function (xf, vX, vY) {
+ if (vX === undefined) vX = 0;
+ if (vY === undefined) vY = 0;
+ return this.p;
+ }
+ b2Point.prototype.GetFirstVertex = function (xf) {
+ return this.p;
+ }
+ b2RayCastInput.b2RayCastInput = function () {
+ this.p1 = new b2Vec2();
+ this.p2 = new b2Vec2();
+ };
+ b2RayCastInput.prototype.b2RayCastInput = function (p1, p2, maxFraction) {
+ if (p1 === undefined) p1 = null;
+ if (p2 === undefined) p2 = null;
+ if (maxFraction === undefined) maxFraction = 1;
+ if (p1) this.p1.SetV(p1);
+ if (p2) this.p2.SetV(p2);
+ this.maxFraction = maxFraction;
+ }
+ b2RayCastOutput.b2RayCastOutput = function () {
+ this.normal = new b2Vec2();
+ };
+ b2Segment.b2Segment = function () {
+ this.p1 = new b2Vec2();
+ this.p2 = new b2Vec2();
+ };
+ b2Segment.prototype.TestSegment = function (lambda, normal, segment, maxLambda) {
+ if (maxLambda === undefined) maxLambda = 0;
+ var s = segment.p1;
+ var rX = segment.p2.x - s.x;
+ var rY = segment.p2.y - s.y;
+ var dX = this.p2.x - this.p1.x;
+ var dY = this.p2.y - this.p1.y;
+ var nX = dY;
+ var nY = (-dX);
+ var k_slop = 100.0 * Number.MIN_VALUE;
+ var denom = (-(rX * nX + rY * nY));
+ if (denom > k_slop) {
+ var bX = s.x - this.p1.x;
+ var bY = s.y - this.p1.y;
+ var a = (bX * nX + bY * nY);
+ if (0.0 <= a && a <= maxLambda * denom) {
+ var mu2 = (-rX * bY) + rY * bX;
+ if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) {
+ a /= denom;
+ var nLen = Math.sqrt(nX * nX + nY * nY);
+ nX /= nLen;
+ nY /= nLen;
+ lambda[0] = a;
+ normal.Set(nX, nY);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ b2Segment.prototype.Extend = function (aabb) {
+ this.ExtendForward(aabb);
+ this.ExtendBackward(aabb);
+ }
+
+
+
+
+ b2Segment.prototype.ExtendForward = function (aabb) {
+ var dX = this.p2.x - this.p1.x;
+ var dY = this.p2.y - this.p1.y;
+ var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY,
+ dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY);
+ this.p2.x = this.p1.x + dX * lambda;
+ this.p2.y = this.p1.y + dY * lambda;
+ }
+ b2Segment.prototype.ExtendBackward = function (aabb) {
+ var dX = (-this.p2.x) + this.p1.x;
+ var dY = (-this.p2.y) + this.p1.y;
+ var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY,
+ dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY);
+ this.p1.x = this.p2.x + dX * lambda;
+ this.p1.y = this.p2.y + dY * lambda;
+ }
+ b2SeparationFunction.b2SeparationFunction = function () {
+ this.m_localPoint = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ };
+ b2SeparationFunction.prototype.Initialize = function (cache, proxyA, transformA, proxyB, transformB) {
+ this.m_proxyA = proxyA;
+ this.m_proxyB = proxyB;
+ var count = parseInt(cache.count);
+ b2Settings.b2Assert(0 < count && count < 3);
+ var localPointA;
+ var localPointA1;
+ var localPointA2;
+ var localPointB;
+ var localPointB1;
+ var localPointB2;
+ var pointAX = 0;
+ var pointAY = 0;
+ var pointBX = 0;
+ var pointBY = 0;
+ var normalX = 0;
+ var normalY = 0;
+ var tMat;
+ var tVec;
+ var s = 0;
+ var sgn = 0;
+ if (count == 1) {
+ this.m_type = b2SeparationFunction.e_points;
+ localPointA = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointB = this.m_proxyB.GetVertex(cache.indexB[0]);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_axis.x = pointBX - pointAX;
+ this.m_axis.y = pointBY - pointAY;
+ this.m_axis.Normalize();
+ }
+ else if (cache.indexB[0] == cache.indexB[1]) {
+ this.m_type = b2SeparationFunction.e_faceA;
+ localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]);
+ localPointB = this.m_proxyB.GetVertex(cache.indexB[0]);
+ this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x);
+ this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y);
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0);
+ this.m_axis.Normalize();
+ tVec = this.m_axis;
+ tMat = transformA.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else if (cache.indexA[0] == cache.indexA[0]) {
+ this.m_type = b2SeparationFunction.e_faceB;
+ localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]);
+ localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]);
+ localPointA = this.m_proxyA.GetVertex(cache.indexA[0]);
+ this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x);
+ this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y);
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0);
+ this.m_axis.Normalize();
+ tVec = this.m_axis;
+ tMat = transformB.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else {
+ localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]);
+ localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]);
+ localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]);
+ var pA = b2Math.MulX(transformA, localPointA);
+ var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1));
+ var pB = b2Math.MulX(transformB, localPointB);
+ var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1));
+ var a = dA.x * dA.x + dA.y * dA.y;
+ var e = dB.x * dB.x + dB.y * dB.y;
+ var r = b2Math.SubtractVV(dB, dA);
+ var c = dA.x * r.x + dA.y * r.y;
+ var f = dB.x * r.x + dB.y * r.y;
+ var b = dA.x * dB.x + dA.y * dB.y;
+ var denom = a * e - b * b;
+ s = 0.0;
+ if (denom != 0.0) {
+ s = b2Math.Clamp((b * f - c * e) / denom, 0.0, 1.0);
+ }
+ var t = (b * s + f) / e;
+ if (t < 0.0) {
+ t = 0.0;
+ s = b2Math.Clamp((b - c) / a, 0.0, 1.0);
+ }
+ localPointA = new b2Vec2();
+ localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x);
+ localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y);
+ localPointB = new b2Vec2();
+ localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x);
+ localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y);
+ if (s == 0.0 || s == 1.0) {
+ this.m_type = b2SeparationFunction.e_faceB;
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0);
+ this.m_axis.Normalize();
+ this.m_localPoint = localPointB;
+ tVec = this.m_axis;
+ tMat = transformB.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else {
+ this.m_type = b2SeparationFunction.e_faceA;
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0);
+ this.m_localPoint = localPointA;
+ tVec = this.m_axis;
+ tMat = transformA.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ }
+ }
+ b2SeparationFunction.prototype.Evaluate = function (transformA, transformB) {
+ var axisA;
+ var axisB;
+ var localPointA;
+ var localPointB;
+ var pointA;
+ var pointB;
+ var seperation = 0;
+ var normal;
+ switch (this.m_type) {
+ case b2SeparationFunction.e_points:
+ {
+ axisA = b2Math.MulTMV(transformA.R, this.m_axis);
+ axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative());
+ localPointA = this.m_proxyA.GetSupportVertex(axisA);
+ localPointB = this.m_proxyB.GetSupportVertex(axisB);
+ pointA = b2Math.MulX(transformA, localPointA);
+ pointB = b2Math.MulX(transformB, localPointB);
+ seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y;
+ return seperation;
+ }
+ case b2SeparationFunction.e_faceA:
+ {
+ normal = b2Math.MulMV(transformA.R, this.m_axis);
+ pointA = b2Math.MulX(transformA, this.m_localPoint);
+ axisB = b2Math.MulTMV(transformB.R, normal.GetNegative());
+ localPointB = this.m_proxyB.GetSupportVertex(axisB);
+ pointB = b2Math.MulX(transformB, localPointB);
+ seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y;
+ return seperation;
+ }
+ case b2SeparationFunction.e_faceB:
+ {
+ normal = b2Math.MulMV(transformB.R, this.m_axis);
+ pointB = b2Math.MulX(transformB, this.m_localPoint);
+ axisA = b2Math.MulTMV(transformA.R, normal.GetNegative());
+ localPointA = this.m_proxyA.GetSupportVertex(axisA);
+ pointA = b2Math.MulX(transformA, localPointA);
+ seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y;
+ return seperation;
+ }
+ default:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2SeparationFunction.e_points = 0x01;
+ Box2D.Collision.b2SeparationFunction.e_faceA = 0x02;
+ Box2D.Collision.b2SeparationFunction.e_faceB = 0x04;
+ });
+ b2Simplex.b2Simplex = function () {
+ this.m_v1 = new b2SimplexVertex();
+ this.m_v2 = new b2SimplexVertex();
+ this.m_v3 = new b2SimplexVertex();
+ this.m_vertices = new Vector(3);
+ };
+ b2Simplex.prototype.b2Simplex = function () {
+ this.m_vertices[0] = this.m_v1;
+ this.m_vertices[1] = this.m_v2;
+ this.m_vertices[2] = this.m_v3;
+ }
+ b2Simplex.prototype.ReadCache = function (cache, proxyA, transformA, proxyB, transformB) {
+ b2Settings.b2Assert(0 <= cache.count && cache.count <= 3);
+ var wALocal;
+ var wBLocal;
+ this.m_count = cache.count;
+ var vertices = this.m_vertices;
+ for (var i = 0; i < this.m_count; i++) {
+ var v = vertices[i];
+ v.indexA = cache.indexA[i];
+ v.indexB = cache.indexB[i];
+ wALocal = proxyA.GetVertex(v.indexA);
+ wBLocal = proxyB.GetVertex(v.indexB);
+ v.wA = b2Math.MulX(transformA, wALocal);
+ v.wB = b2Math.MulX(transformB, wBLocal);
+ v.w = b2Math.SubtractVV(v.wB, v.wA);
+ v.a = 0;
+ }
+ if (this.m_count > 1) {
+ var metric1 = cache.metric;
+ var metric2 = this.GetMetric();
+ if (metric2 < .5 * metric1 || 2.0 * metric1 < metric2 || metric2 < Number.MIN_VALUE) {
+ this.m_count = 0;
+ }
+ }
+ if (this.m_count == 0) {
+ v = vertices[0];
+ v.indexA = 0;
+ v.indexB = 0;
+ wALocal = proxyA.GetVertex(0);
+ wBLocal = proxyB.GetVertex(0);
+ v.wA = b2Math.MulX(transformA, wALocal);
+ v.wB = b2Math.MulX(transformB, wBLocal);
+ v.w = b2Math.SubtractVV(v.wB, v.wA);
+ this.m_count = 1;
+ }
+ }
+ b2Simplex.prototype.WriteCache = function (cache) {
+ cache.metric = this.GetMetric();
+ cache.count = Box2D.parseUInt(this.m_count);
+ var vertices = this.m_vertices;
+ for (var i = 0; i < this.m_count; i++) {
+ cache.indexA[i] = Box2D.parseUInt(vertices[i].indexA);
+ cache.indexB[i] = Box2D.parseUInt(vertices[i].indexB);
+ }
+ }
+ b2Simplex.prototype.GetSearchDirection = function () {
+ switch (this.m_count) {
+ case 1:
+ return this.m_v1.w.GetNegative();
+ case 2:
+ {
+ var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w);
+ var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative());
+ if (sgn > 0.0) {
+ return b2Math.CrossFV(1.0, e12);
+ }
+ else {
+ return b2Math.CrossVF(e12, 1.0);
+ }
+ }
+ default:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ }
+ }
+ b2Simplex.prototype.GetClosestPoint = function () {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ case 1:
+ return this.m_v1.w;
+ case 2:
+ return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y);
+ default:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ }
+ }
+ b2Simplex.prototype.GetWitnessPoints = function (pA, pB) {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ break;
+ case 1:
+ pA.SetV(this.m_v1.wA);
+ pB.SetV(this.m_v1.wB);
+ break;
+ case 2:
+ pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x;
+ pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y;
+ pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x;
+ pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y;
+ break;
+ case 3:
+ pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x;
+ pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y;
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ break;
+ }
+ }
+ b2Simplex.prototype.GetMetric = function () {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ case 1:
+ return 0.0;
+ case 2:
+ return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length();
+ case 3:
+ return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w));
+ default:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ }
+ }
+ b2Simplex.prototype.Solve2 = function () {
+ var w1 = this.m_v1.w;
+ var w2 = this.m_v2.w;
+ var e12 = b2Math.SubtractVV(w2, w1);
+ var d12_2 = (-(w1.x * e12.x + w1.y * e12.y));
+ if (d12_2 <= 0.0) {
+ this.m_v1.a = 1.0;
+ this.m_count = 1;
+ return;
+ }
+ var d12_1 = (w2.x * e12.x + w2.y * e12.y);
+ if (d12_1 <= 0.0) {
+ this.m_v2.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v2);
+ return;
+ }
+ var inv_d12 = 1.0 / (d12_1 + d12_2);
+ this.m_v1.a = d12_1 * inv_d12;
+ this.m_v2.a = d12_2 * inv_d12;
+ this.m_count = 2;
+ }
+ b2Simplex.prototype.Solve3 = function () {
+ var w1 = this.m_v1.w;
+ var w2 = this.m_v2.w;
+ var w3 = this.m_v3.w;
+ var e12 = b2Math.SubtractVV(w2, w1);
+ var w1e12 = b2Math.Dot(w1, e12);
+ var w2e12 = b2Math.Dot(w2, e12);
+ var d12_1 = w2e12;
+ var d12_2 = (-w1e12);
+ var e13 = b2Math.SubtractVV(w3, w1);
+ var w1e13 = b2Math.Dot(w1, e13);
+ var w3e13 = b2Math.Dot(w3, e13);
+ var d13_1 = w3e13;
+ var d13_2 = (-w1e13);
+ var e23 = b2Math.SubtractVV(w3, w2);
+ var w2e23 = b2Math.Dot(w2, e23);
+ var w3e23 = b2Math.Dot(w3, e23);
+ var d23_1 = w3e23;
+ var d23_2 = (-w2e23);
+ var n123 = b2Math.CrossVV(e12, e13);
+ var d123_1 = n123 * b2Math.CrossVV(w2, w3);
+ var d123_2 = n123 * b2Math.CrossVV(w3, w1);
+ var d123_3 = n123 * b2Math.CrossVV(w1, w2);
+ if (d12_2 <= 0.0 && d13_2 <= 0.0) {
+ this.m_v1.a = 1.0;
+ this.m_count = 1;
+ return;
+ }
+ if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0) {
+ var inv_d12 = 1.0 / (d12_1 + d12_2);
+ this.m_v1.a = d12_1 * inv_d12;
+ this.m_v2.a = d12_2 * inv_d12;
+ this.m_count = 2;
+ return;
+ }
+ if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0) {
+ var inv_d13 = 1.0 / (d13_1 + d13_2);
+ this.m_v1.a = d13_1 * inv_d13;
+ this.m_v3.a = d13_2 * inv_d13;
+ this.m_count = 2;
+ this.m_v2.Set(this.m_v3);
+ return;
+ }
+ if (d12_1 <= 0.0 && d23_2 <= 0.0) {
+ this.m_v2.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v2);
+ return;
+ }
+ if (d13_1 <= 0.0 && d23_1 <= 0.0) {
+ this.m_v3.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v3);
+ return;
+ }
+ if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0) {
+ var inv_d23 = 1.0 / (d23_1 + d23_2);
+ this.m_v2.a = d23_1 * inv_d23;
+ this.m_v3.a = d23_2 * inv_d23;
+ this.m_count = 2;
+ this.m_v1.Set(this.m_v3);
+ return;
+ }
+ var inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);
+ this.m_v1.a = d123_1 * inv_d123;
+ this.m_v2.a = d123_2 * inv_d123;
+ this.m_v3.a = d123_3 * inv_d123;
+ this.m_count = 3;
+ }
+ b2SimplexCache.b2SimplexCache = function () {
+ this.indexA = new Vector_a2j_Number(3);
+ this.indexB = new Vector_a2j_Number(3);
+ };
+ b2SimplexVertex.b2SimplexVertex = function () {};
+ b2SimplexVertex.prototype.Set = function (other) {
+ this.wA.SetV(other.wA);
+ this.wB.SetV(other.wB);
+ this.w.SetV(other.w);
+ this.a = other.a;
+ this.indexA = other.indexA;
+ this.indexB = other.indexB;
+ }
+ b2TimeOfImpact.b2TimeOfImpact = function () {};
+ b2TimeOfImpact.TimeOfImpact = function (input) {
+ ++b2TimeOfImpact.b2_toiCalls;
+ var proxyA = input.proxyA;
+ var proxyB = input.proxyB;
+ var sweepA = input.sweepA;
+ var sweepB = input.sweepB;
+ b2Settings.b2Assert(sweepA.t0 == sweepB.t0);
+ b2Settings.b2Assert(1.0 - sweepA.t0 > Number.MIN_VALUE);
+ var radius = proxyA.m_radius + proxyB.m_radius;
+ var tolerance = input.tolerance;
+ var alpha = 0.0;
+ var k_maxIterations = 1000;
+ var iter = 0;
+ var target = 0.0;
+ b2TimeOfImpact.s_cache.count = 0;
+ b2TimeOfImpact.s_distanceInput.useRadii = false;
+ for (;;) {
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha);
+ b2TimeOfImpact.s_distanceInput.proxyA = proxyA;
+ b2TimeOfImpact.s_distanceInput.proxyB = proxyB;
+ b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA;
+ b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB;
+ b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput);
+ if (b2TimeOfImpact.s_distanceOutput.distance <= 0.0) {
+ alpha = 1.0;
+ break;
+ }
+ b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB);
+ var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (separation <= 0.0) {
+ alpha = 1.0;
+ break;
+ }
+ if (iter == 0) {
+ if (separation > radius) {
+ target = b2Math.Max(radius - tolerance, 0.75 * radius);
+ }
+ else {
+ target = b2Math.Max(separation - tolerance, 0.02 * radius);
+ }
+ }
+ if (separation - target < 0.5 * tolerance) {
+ if (iter == 0) {
+ alpha = 1.0;
+ break;
+ }
+ break;
+ }
+ var newAlpha = alpha; {
+ var x1 = alpha;
+ var x2 = 1.0;
+ var f1 = separation;
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2);
+ var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (f2 >= target) {
+ alpha = 1.0;
+ break;
+ }
+ var rootIterCount = 0;
+ for (;;) {
+ var x = 0;
+ if (rootIterCount & 1) {
+ x = x1 + (target - f1) * (x2 - x1) / (f2 - f1);
+ }
+ else {
+ x = 0.5 * (x1 + x2);
+ }
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, x);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, x);
+ var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (b2Math.Abs(f - target) < 0.025 * tolerance) {
+ newAlpha = x;
+ break;
+ }
+ if (f > target) {
+ x1 = x;
+ f1 = f;
+ }
+ else {
+ x2 = x;
+ f2 = f;
+ }++rootIterCount;
+ ++b2TimeOfImpact.b2_toiRootIters;
+ if (rootIterCount == 50) {
+ break;
+ }
+ }
+ b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount);
+ }
+ if (newAlpha < (1.0 + 100.0 * Number.MIN_VALUE) * alpha) {
+ break;
+ }
+ alpha = newAlpha;
+ iter++;
+ ++b2TimeOfImpact.b2_toiIters;
+ if (iter == k_maxIterations) {
+ break;
+ }
+ }
+ b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter);
+ return alpha;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2TimeOfImpact.b2_toiCalls = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiRootIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters = 0;
+ Box2D.Collision.b2TimeOfImpact.s_cache = new b2SimplexCache();
+ Box2D.Collision.b2TimeOfImpact.s_distanceInput = new b2DistanceInput();
+ Box2D.Collision.b2TimeOfImpact.s_xfA = new b2Transform();
+ Box2D.Collision.b2TimeOfImpact.s_xfB = new b2Transform();
+ Box2D.Collision.b2TimeOfImpact.s_fcn = new b2SeparationFunction();
+ Box2D.Collision.b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput();
+ });
+ b2TOIInput.b2TOIInput = function () {
+ this.proxyA = new b2DistanceProxy();
+ this.proxyB = new b2DistanceProxy();
+ this.sweepA = new b2Sweep();
+ this.sweepB = new b2Sweep();
+ };
+ b2WorldManifold.b2WorldManifold = function () {
+ this.m_normal = new b2Vec2();
+ };
+ b2WorldManifold.prototype.b2WorldManifold = function () {
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2Vec2();
+ }
+ }
+ b2WorldManifold.prototype.Initialize = function (manifold, xfA, radiusA, xfB, radiusB) {
+ if (radiusA === undefined) radiusA = 0;
+ if (radiusB === undefined) radiusB = 0;
+ if (manifold.m_pointCount == 0) {
+ return;
+ }
+ var i = 0;
+ var tVec;
+ var tMat;
+ var normalX = 0;
+ var normalY = 0;
+ var planePointX = 0;
+ var planePointY = 0;
+ var clipPointX = 0;
+ var clipPointY = 0;
+ switch (manifold.m_type) {
+ case b2Manifold.e_circles:
+ {
+ tMat = xfA.R;
+ tVec = manifold.m_localPoint;
+ var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfB.R;
+ tVec = manifold.m_points[0].m_localPoint;
+ var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ var dX = pointBX - pointAX;
+ var dY = pointBY - pointAY;
+ var d2 = dX * dX + dY * dY;
+ if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) {
+ var d = Math.sqrt(d2);
+ this.m_normal.x = dX / d;
+ this.m_normal.y = dY / d;
+ }
+ else {
+ this.m_normal.x = 1;
+ this.m_normal.y = 0;
+ }
+ var cAX = pointAX + radiusA * this.m_normal.x;
+ var cAY = pointAY + radiusA * this.m_normal.y;
+ var cBX = pointBX - radiusB * this.m_normal.x;
+ var cBY = pointBY - radiusB * this.m_normal.y;
+ this.m_points[0].x = 0.5 * (cAX + cBX);
+ this.m_points[0].y = 0.5 * (cAY + cBY);
+ }
+ break;
+ case b2Manifold.e_faceA:
+ {
+ tMat = xfA.R;
+ tVec = manifold.m_localPlaneNormal;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfA.R;
+ tVec = manifold.m_localPoint;
+ planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_normal.x = normalX;
+ this.m_normal.y = normalY;
+ for (i = 0;
+ i < manifold.m_pointCount; i++) {
+ tMat = xfB.R;
+ tVec = manifold.m_points[i].m_localPoint;
+ clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX;
+ this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY;
+ }
+ }
+ break;
+ case b2Manifold.e_faceB:
+ {
+ tMat = xfB.R;
+ tVec = manifold.m_localPlaneNormal;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfB.R;
+ tVec = manifold.m_localPoint;
+ planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_normal.x = (-normalX);
+ this.m_normal.y = (-normalY);
+ for (i = 0;
+ i < manifold.m_pointCount; i++) {
+ tMat = xfA.R;
+ tVec = manifold.m_points[i].m_localPoint;
+ clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX;
+ this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY;
+ }
+ }
+ break;
+ }
+ }
+ ClipVertex.ClipVertex = function () {
+ this.v = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ ClipVertex.prototype.Set = function (other) {
+ this.v.SetV(other.v);
+ this.id.Set(other.id);
+ }
+ Features.Features = function () {};
+ Object.defineProperty(Features.prototype, 'referenceEdge', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._referenceEdge;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'referenceEdge', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._referenceEdge = value;
+ this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceEdge & 0x000000ff);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentEdge', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._incidentEdge;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentEdge', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._incidentEdge = value;
+ this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentVertex', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._incidentVertex;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentVertex', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._incidentVertex = value;
+ this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'flip', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._flip;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'flip', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._flip = value;
+ this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000);
+ }
+ });
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ Box2D.inherit(b2CircleShape, Box2D.Collision.Shapes.b2Shape);
+ b2CircleShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2CircleShape.b2CircleShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ this.m_p = new b2Vec2();
+ };
+ b2CircleShape.prototype.Copy = function () {
+ var s = new b2CircleShape();
+ s.Set(this);
+ return s;
+ }
+ b2CircleShape.prototype.Set = function (other) {
+ this.__super.Set.call(this, other);
+ if (Box2D.is(other, b2CircleShape)) {
+ var other2 = (other instanceof b2CircleShape ? other : null);
+ this.m_p.SetV(other2.m_p);
+ }
+ }
+ b2CircleShape.prototype.TestPoint = function (transform, p) {
+ var tMat = transform.R;
+ var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ dX = p.x - dX;
+ dY = p.y - dY;
+ return (dX * dX + dY * dY) <= this.m_radius * this.m_radius;
+ }
+ b2CircleShape.prototype.RayCast = function (output, input, transform) {
+ var tMat = transform.R;
+ var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ var sX = input.p1.x - positionX;
+ var sY = input.p1.y - positionY;
+ var b = (sX * sX + sY * sY) - this.m_radius * this.m_radius;
+ var rX = input.p2.x - input.p1.x;
+ var rY = input.p2.y - input.p1.y;
+ var c = (sX * rX + sY * rY);
+ var rr = (rX * rX + rY * rY);
+ var sigma = c * c - rr * b;
+ if (sigma < 0.0 || rr < Number.MIN_VALUE) {
+ return false;
+ }
+ var a = (-(c + Math.sqrt(sigma)));
+ if (0.0 <= a && a <= input.maxFraction * rr) {
+ a /= rr;
+ output.fraction = a;
+ output.normal.x = sX + a * rX;
+ output.normal.y = sY + a * rY;
+ output.normal.Normalize();
+ return true;
+ }
+ return false;
+ }
+ b2CircleShape.prototype.ComputeAABB = function (aabb, transform) {
+ var tMat = transform.R;
+ var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius);
+ aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius);
+ }
+ b2CircleShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius;
+ massData.center.SetV(this.m_p);
+ massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y));
+ }
+ b2CircleShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var p = b2Math.MulX(xf, this.m_p);
+ var l = (-(b2Math.Dot(normal, p) - offset));
+ if (l < (-this.m_radius) + Number.MIN_VALUE) {
+ return 0;
+ }
+ if (l > this.m_radius) {
+ c.SetV(p);
+ return Math.PI * this.m_radius * this.m_radius;
+ }
+ var r2 = this.m_radius * this.m_radius;
+ var l2 = l * l;
+ var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2);
+ var com = (-2 / 3 * Math.pow(r2 - l2, 1.5) / area);
+ c.x = p.x + normal.x * com;
+ c.y = p.y + normal.y * com;
+ return area;
+ }
+ b2CircleShape.prototype.GetLocalPosition = function () {
+ return this.m_p;
+ }
+ b2CircleShape.prototype.SetLocalPosition = function (position) {
+ this.m_p.SetV(position);
+ }
+ b2CircleShape.prototype.GetRadius = function () {
+ return this.m_radius;
+ }
+ b2CircleShape.prototype.SetRadius = function (radius) {
+ if (radius === undefined) radius = 0;
+ this.m_radius = radius;
+ }
+ b2CircleShape.prototype.b2CircleShape = function (radius) {
+ if (radius === undefined) radius = 0;
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_circleShape;
+ this.m_radius = radius;
+ }
+ b2EdgeChainDef.b2EdgeChainDef = function () {};
+ b2EdgeChainDef.prototype.b2EdgeChainDef = function () {
+ this.vertexCount = 0;
+ this.isALoop = true;
+ this.vertices = [];
+ }
+ Box2D.inherit(b2EdgeShape, Box2D.Collision.Shapes.b2Shape);
+ b2EdgeShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2EdgeShape.b2EdgeShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ this.s_supportVec = new b2Vec2();
+ this.m_v1 = new b2Vec2();
+ this.m_v2 = new b2Vec2();
+ this.m_coreV1 = new b2Vec2();
+ this.m_coreV2 = new b2Vec2();
+ this.m_normal = new b2Vec2();
+ this.m_direction = new b2Vec2();
+ this.m_cornerDir1 = new b2Vec2();
+ this.m_cornerDir2 = new b2Vec2();
+ };
+ b2EdgeShape.prototype.TestPoint = function (transform, p) {
+ return false;
+ }
+ b2EdgeShape.prototype.RayCast = function (output, input, transform) {
+ var tMat;
+ var rX = input.p2.x - input.p1.x;
+ var rY = input.p2.y - input.p1.y;
+ tMat = transform.R;
+ var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y);
+ var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y);
+ var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y;
+ var nY = (-(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X));
+ var k_slop = 100.0 * Number.MIN_VALUE;
+ var denom = (-(rX * nX + rY * nY));
+ if (denom > k_slop) {
+ var bX = input.p1.x - v1X;
+ var bY = input.p1.y - v1Y;
+ var a = (bX * nX + bY * nY);
+ if (0.0 <= a && a <= input.maxFraction * denom) {
+ var mu2 = (-rX * bY) + rY * bX;
+ if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) {
+ a /= denom;
+ output.fraction = a;
+ var nLen = Math.sqrt(nX * nX + nY * nY);
+ output.normal.x = nX / nLen;
+ output.normal.y = nY / nLen;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ b2EdgeShape.prototype.ComputeAABB = function (aabb, transform) {
+ var tMat = transform.R;
+ var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y);
+ var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y);
+ var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y);
+ var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y);
+ if (v1X < v2X) {
+ aabb.lowerBound.x = v1X;
+ aabb.upperBound.x = v2X;
+ }
+ else {
+ aabb.lowerBound.x = v2X;
+ aabb.upperBound.x = v1X;
+ }
+ if (v1Y < v2Y) {
+ aabb.lowerBound.y = v1Y;
+ aabb.upperBound.y = v2Y;
+ }
+ else {
+ aabb.lowerBound.y = v2Y;
+ aabb.upperBound.y = v1Y;
+ }
+ }
+ b2EdgeShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ massData.mass = 0;
+ massData.center.SetV(this.m_v1);
+ massData.I = 0;
+ }
+ b2EdgeShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var v0 = new b2Vec2(normal.x * offset, normal.y * offset);
+ var v1 = b2Math.MulX(xf, this.m_v1);
+ var v2 = b2Math.MulX(xf, this.m_v2);
+ var d1 = b2Math.Dot(normal, v1) - offset;
+ var d2 = b2Math.Dot(normal, v2) - offset;
+ if (d1 > 0) {
+ if (d2 > 0) {
+ return 0;
+ }
+ else {
+ v1.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x;
+ v1.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y;
+ }
+ }
+ else {
+ if (d2 > 0) {
+ v2.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x;
+ v2.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y;
+ }
+ else {}
+ }
+ c.x = (v0.x + v1.x + v2.x) / 3;
+ c.y = (v0.y + v1.y + v2.y) / 3;
+ return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x));
+ }
+ b2EdgeShape.prototype.GetLength = function () {
+ return this.m_length;
+ }
+ b2EdgeShape.prototype.GetVertex1 = function () {
+ return this.m_v1;
+ }
+ b2EdgeShape.prototype.GetVertex2 = function () {
+ return this.m_v2;
+ }
+ b2EdgeShape.prototype.GetCoreVertex1 = function () {
+ return this.m_coreV1;
+ }
+ b2EdgeShape.prototype.GetCoreVertex2 = function () {
+ return this.m_coreV2;
+ }
+ b2EdgeShape.prototype.GetNormalVector = function () {
+ return this.m_normal;
+ }
+ b2EdgeShape.prototype.GetDirectionVector = function () {
+ return this.m_direction;
+ }
+ b2EdgeShape.prototype.GetCorner1Vector = function () {
+ return this.m_cornerDir1;
+ }
+ b2EdgeShape.prototype.GetCorner2Vector = function () {
+ return this.m_cornerDir2;
+ }
+ b2EdgeShape.prototype.Corner1IsConvex = function () {
+ return this.m_cornerConvex1;
+ }
+ b2EdgeShape.prototype.Corner2IsConvex = function () {
+ return this.m_cornerConvex2;
+ }
+ b2EdgeShape.prototype.GetFirstVertex = function (xf) {
+ var tMat = xf.R;
+ return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y));
+ }
+ b2EdgeShape.prototype.GetNextEdge = function () {
+ return this.m_nextEdge;
+ }
+ b2EdgeShape.prototype.GetPrevEdge = function () {
+ return this.m_prevEdge;
+ }
+ b2EdgeShape.prototype.Support = function (xf, dX, dY) {
+ if (dX === undefined) dX = 0;
+ if (dY === undefined) dY = 0;
+ var tMat = xf.R;
+ var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y);
+ var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y);
+ var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y);
+ var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y);
+ if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY)) {
+ this.s_supportVec.x = v1X;
+ this.s_supportVec.y = v1Y;
+ }
+ else {
+ this.s_supportVec.x = v2X;
+ this.s_supportVec.y = v2Y;
+ }
+ return this.s_supportVec;
+ }
+ b2EdgeShape.prototype.b2EdgeShape = function (v1, v2) {
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_edgeShape;
+ this.m_prevEdge = null;
+ this.m_nextEdge = null;
+ this.m_v1 = v1;
+ this.m_v2 = v2;
+ this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y);
+ this.m_length = this.m_direction.Normalize();
+ this.m_normal.Set(this.m_direction.y, (-this.m_direction.x));
+ this.m_coreV1.Set((-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x)) + this.m_v1.x, (-b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y)) + this.m_v1.y);
+ this.m_coreV2.Set((-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x)) + this.m_v2.x, (-b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y)) + this.m_v2.y);
+ this.m_cornerDir1 = this.m_normal;
+ this.m_cornerDir2.Set((-this.m_normal.x), (-this.m_normal.y));
+ }
+ b2EdgeShape.prototype.SetPrevEdge = function (edge, core, cornerDir, convex) {
+ this.m_prevEdge = edge;
+ this.m_coreV1 = core;
+ this.m_cornerDir1 = cornerDir;
+ this.m_cornerConvex1 = convex;
+ }
+ b2EdgeShape.prototype.SetNextEdge = function (edge, core, cornerDir, convex) {
+ this.m_nextEdge = edge;
+ this.m_coreV2 = core;
+ this.m_cornerDir2 = cornerDir;
+ this.m_cornerConvex2 = convex;
+ }
+ b2MassData.b2MassData = function () {
+ this.mass = 0.0;
+ this.center = new b2Vec2(0, 0);
+ this.I = 0.0;
+ };
+ Box2D.inherit(b2PolygonShape, Box2D.Collision.Shapes.b2Shape);
+ b2PolygonShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2PolygonShape.b2PolygonShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ };
+ b2PolygonShape.prototype.Copy = function () {
+ var s = new b2PolygonShape();
+ s.Set(this);
+ return s;
+ }
+ b2PolygonShape.prototype.Set = function (other) {
+ this.__super.Set.call(this, other);
+ if (Box2D.is(other, b2PolygonShape)) {
+ var other2 = (other instanceof b2PolygonShape ? other : null);
+ this.m_centroid.SetV(other2.m_centroid);
+ this.m_vertexCount = other2.m_vertexCount;
+ this.Reserve(this.m_vertexCount);
+ for (var i = 0; i < this.m_vertexCount; i++) {
+ this.m_vertices[i].SetV(other2.m_vertices[i]);
+ this.m_normals[i].SetV(other2.m_normals[i]);
+ }
+ }
+ }
+ b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var v = new Vector();
+ var i = 0,
+ tVec;
+ for (i = 0;
+ i < vertices.length; ++i) {
+ tVec = vertices[i];
+ v.push(tVec);
+ }
+ this.SetAsVector(v, vertexCount);
+ }
+ b2PolygonShape.AsArray = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsArray(vertices, vertexCount);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsVector = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ if (vertexCount == 0) vertexCount = vertices.length;
+ b2Settings.b2Assert(2 <= vertexCount);
+ this.m_vertexCount = vertexCount;
+ this.Reserve(vertexCount);
+ var i = 0;
+ for (i = 0;
+ i < this.m_vertexCount; i++) {
+ this.m_vertices[i].SetV(vertices[i]);
+ }
+ for (i = 0;
+ i < this.m_vertexCount; ++i) {
+ var i1 = parseInt(i);
+ var i2 = parseInt(i + 1 < this.m_vertexCount ? i + 1 : 0);
+ var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]);
+ b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE);
+ this.m_normals[i].SetV(b2Math.CrossVF(edge, 1.0));
+ this.m_normals[i].Normalize();
+ }
+ this.m_centroid = b2PolygonShape.ComputeCentroid(this.m_vertices, this.m_vertexCount);
+ }
+ b2PolygonShape.AsVector = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsVector(vertices, vertexCount);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsBox = function (hx, hy) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ this.m_vertexCount = 4;
+ this.Reserve(4);
+ this.m_vertices[0].Set((-hx), (-hy));
+ this.m_vertices[1].Set(hx, (-hy));
+ this.m_vertices[2].Set(hx, hy);
+ this.m_vertices[3].Set((-hx), hy);
+ this.m_normals[0].Set(0.0, (-1.0));
+ this.m_normals[1].Set(1.0, 0.0);
+ this.m_normals[2].Set(0.0, 1.0);
+ this.m_normals[3].Set((-1.0), 0.0);
+ this.m_centroid.SetZero();
+ }
+ b2PolygonShape.AsBox = function (hx, hy) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsBox(hx, hy);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsOrientedBox = function (hx, hy, center, angle) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ if (center === undefined) center = null;
+ if (angle === undefined) angle = 0.0;
+ this.m_vertexCount = 4;
+ this.Reserve(4);
+ this.m_vertices[0].Set((-hx), (-hy));
+ this.m_vertices[1].Set(hx, (-hy));
+ this.m_vertices[2].Set(hx, hy);
+ this.m_vertices[3].Set((-hx), hy);
+ this.m_normals[0].Set(0.0, (-1.0));
+ this.m_normals[1].Set(1.0, 0.0);
+ this.m_normals[2].Set(0.0, 1.0);
+ this.m_normals[3].Set((-1.0), 0.0);
+ this.m_centroid = center;
+ var xf = new b2Transform();
+ xf.position = center;
+ xf.R.Set(angle);
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]);
+ this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]);
+ }
+ }
+ b2PolygonShape.AsOrientedBox = function (hx, hy, center, angle) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ if (center === undefined) center = null;
+ if (angle === undefined) angle = 0.0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsOrientedBox(hx, hy, center, angle);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsEdge = function (v1, v2) {
+ this.m_vertexCount = 2;
+ this.Reserve(2);
+ this.m_vertices[0].SetV(v1);
+ this.m_vertices[1].SetV(v2);
+ this.m_centroid.x = 0.5 * (v1.x + v2.x);
+ this.m_centroid.y = 0.5 * (v1.y + v2.y);
+ this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0);
+ this.m_normals[0].Normalize();
+ this.m_normals[1].x = (-this.m_normals[0].x);
+ this.m_normals[1].y = (-this.m_normals[0].y);
+ }
+ b2PolygonShape.AsEdge = function (v1, v2) {
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsEdge(v1, v2);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.TestPoint = function (xf, p) {
+ var tVec;
+ var tMat = xf.R;
+ var tX = p.x - xf.position.x;
+ var tY = p.y - xf.position.y;
+ var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y);
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ tX = pLocalX - tVec.x;
+ tY = pLocalY - tVec.y;
+ tVec = this.m_normals[i];
+ var dot = (tVec.x * tX + tVec.y * tY);
+ if (dot > 0.0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ b2PolygonShape.prototype.RayCast = function (output, input, transform) {
+ var lower = 0.0;
+ var upper = input.maxFraction;
+ var tX = 0;
+ var tY = 0;
+ var tMat;
+ var tVec;
+ tX = input.p1.x - transform.position.x;
+ tY = input.p1.y - transform.position.y;
+ tMat = transform.R;
+ var p1X = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var p1Y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ tX = input.p2.x - transform.position.x;
+ tY = input.p2.y - transform.position.y;
+ tMat = transform.R;
+ var p2X = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var p2Y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var index = parseInt((-1));
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ tX = tVec.x - p1X;
+ tY = tVec.y - p1Y;
+ tVec = this.m_normals[i];
+ var numerator = (tVec.x * tX + tVec.y * tY);
+ var denominator = (tVec.x * dX + tVec.y * dY);
+ if (denominator == 0.0) {
+ if (numerator < 0.0) {
+ return false;
+ }
+ }
+ else {
+ if (denominator < 0.0 && numerator < lower * denominator) {
+ lower = numerator / denominator;
+ index = i;
+ }
+ else if (denominator > 0.0 && numerator < upper * denominator) {
+ upper = numerator / denominator;
+ }
+ }
+ if (upper < lower - Number.MIN_VALUE) {
+ return false;
+ }
+ }
+ if (index >= 0) {
+ output.fraction = lower;
+ tMat = transform.R;
+ tVec = this.m_normals[index];
+ output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ return true;
+ }
+ return false;
+ }
+ b2PolygonShape.prototype.ComputeAABB = function (aabb, xf) {
+ var tMat = xf.R;
+ var tVec = this.m_vertices[0];
+ var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var upperX = lowerX;
+ var upperY = lowerY;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ lowerX = lowerX < vX ? lowerX : vX;
+ lowerY = lowerY < vY ? lowerY : vY;
+ upperX = upperX > vX ? upperX : vX;
+ upperY = upperY > vY ? upperY : vY;
+ }
+ aabb.lowerBound.x = lowerX - this.m_radius;
+ aabb.lowerBound.y = lowerY - this.m_radius;
+ aabb.upperBound.x = upperX + this.m_radius;
+ aabb.upperBound.y = upperY + this.m_radius;
+ }
+ b2PolygonShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ if (this.m_vertexCount == 2) {
+ massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x);
+ massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y);
+ massData.mass = 0.0;
+ massData.I = 0.0;
+ return;
+ }
+ var centerX = 0.0;
+ var centerY = 0.0;
+ var area = 0.0;
+ var I = 0.0;
+ var p1X = 0.0;
+ var p1Y = 0.0;
+ var k_inv3 = 1.0 / 3.0;
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ var p2 = this.m_vertices[i];
+ var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0];
+ var e1X = p2.x - p1X;
+ var e1Y = p2.y - p1Y;
+ var e2X = p3.x - p1X;
+ var e2Y = p3.y - p1Y;
+ var D = e1X * e2Y - e1Y * e2X;
+ var triangleArea = 0.5 * D;area += triangleArea;
+ centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x);
+ centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y);
+ var px = p1X;
+ var py = p1Y;
+ var ex1 = e1X;
+ var ey1 = e1Y;
+ var ex2 = e2X;
+ var ey2 = e2Y;
+ var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px;
+ var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;I += D * (intx2 + inty2);
+ }
+ massData.mass = density * area;
+ centerX *= 1.0 / area;
+ centerY *= 1.0 / area;
+ massData.center.Set(centerX, centerY);
+ massData.I = density * I;
+ }
+ b2PolygonShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var normalL = b2Math.MulTMV(xf.R, normal);
+ var offsetL = offset - b2Math.Dot(normal, xf.position);
+ var depths = new Vector_a2j_Number();
+ var diveCount = 0;
+ var intoIndex = parseInt((-1));
+ var outoIndex = parseInt((-1));
+ var lastSubmerged = false;
+ var i = 0;
+ for (i = 0;
+ i < this.m_vertexCount; ++i) {
+ depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL;
+ var isSubmerged = depths[i] < (-Number.MIN_VALUE);
+ if (i > 0) {
+ if (isSubmerged) {
+ if (!lastSubmerged) {
+ intoIndex = i - 1;
+ diveCount++;
+ }
+ }
+ else {
+ if (lastSubmerged) {
+ outoIndex = i - 1;
+ diveCount++;
+ }
+ }
+ }
+ lastSubmerged = isSubmerged;
+ }
+ switch (diveCount) {
+ case 0:
+ if (lastSubmerged) {
+ var md = new b2MassData();
+ this.ComputeMass(md, 1);
+ c.SetV(b2Math.MulX(xf, md.center));
+ return md.mass;
+ }
+ else {
+ return 0;
+ }
+ break;
+ case 1:
+ if (intoIndex == (-1)) {
+ intoIndex = this.m_vertexCount - 1;
+ }
+ else {
+ outoIndex = this.m_vertexCount - 1;
+ }
+ break;
+ }
+ var intoIndex2 = parseInt((intoIndex + 1) % this.m_vertexCount);
+ var outoIndex2 = parseInt((outoIndex + 1) % this.m_vertexCount);
+ var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);
+ var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);
+ var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda);
+ var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda);
+ var area = 0;
+ var center = new b2Vec2();
+ var p2 = this.m_vertices[intoIndex2];
+ var p3;
+ i = intoIndex2;
+ while (i != outoIndex2) {
+ i = (i + 1) % this.m_vertexCount;
+ if (i == outoIndex2) p3 = outoVec;
+ else p3 = this.m_vertices[i];
+ var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x));
+ area += triangleArea;
+ center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3;
+ center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3;
+ p2 = p3;
+ }
+ center.Multiply(1 / area);
+ c.SetV(b2Math.MulX(xf, center));
+ return area;
+ }
+ b2PolygonShape.prototype.GetVertexCount = function () {
+ return this.m_vertexCount;
+ }
+ b2PolygonShape.prototype.GetVertices = function () {
+ return this.m_vertices;
+ }
+ b2PolygonShape.prototype.GetNormals = function () {
+ return this.m_normals;
+ }
+ b2PolygonShape.prototype.GetSupport = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return bestIndex;
+ }
+ b2PolygonShape.prototype.GetSupportVertex = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return this.m_vertices[bestIndex];
+ }
+ b2PolygonShape.prototype.Validate = function () {
+ return false;
+ }
+ b2PolygonShape.prototype.b2PolygonShape = function () {
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_polygonShape;
+ this.m_centroid = new b2Vec2();
+ this.m_vertices = new Vector();
+ this.m_normals = new Vector();
+ }
+ b2PolygonShape.prototype.Reserve = function (count) {
+ if (count === undefined) count = 0;
+ for (var i = parseInt(this.m_vertices.length); i < count; i++) {
+ this.m_vertices[i] = new b2Vec2();
+ this.m_normals[i] = new b2Vec2();
+ }
+ }
+ b2PolygonShape.ComputeCentroid = function (vs, count) {
+ if (count === undefined) count = 0;
+ var c = new b2Vec2();
+ var area = 0.0;
+ var p1X = 0.0;
+ var p1Y = 0.0;
+ var inv3 = 1.0 / 3.0;
+ for (var i = 0; i < count; ++i) {
+ var p2 = vs[i];
+ var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0];
+ var e1X = p2.x - p1X;
+ var e1Y = p2.y - p1Y;
+ var e2X = p3.x - p1X;
+ var e2Y = p3.y - p1Y;
+ var D = (e1X * e2Y - e1Y * e2X);
+ var triangleArea = 0.5 * D;area += triangleArea;
+ c.x += triangleArea * inv3 * (p1X + p2.x + p3.x);
+ c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y);
+ }
+ c.x *= 1.0 / area;
+ c.y *= 1.0 / area;
+ return c;
+ }
+ b2PolygonShape.ComputeOBB = function (obb, vs, count) {
+ if (count === undefined) count = 0;
+ var i = 0;
+ var p = new Vector(count + 1);
+ for (i = 0;
+ i < count; ++i) {
+ p[i] = vs[i];
+ }
+ p[count] = p[0];
+ var minArea = Number.MAX_VALUE;
+ for (i = 1;
+ i <= count; ++i) {
+ var root = p[parseInt(i - 1)];
+ var uxX = p[i].x - root.x;
+ var uxY = p[i].y - root.y;
+ var length = Math.sqrt(uxX * uxX + uxY * uxY);
+ uxX /= length;
+ uxY /= length;
+ var uyX = (-uxY);
+ var uyY = uxX;
+ var lowerX = Number.MAX_VALUE;
+ var lowerY = Number.MAX_VALUE;
+ var upperX = (-Number.MAX_VALUE);
+ var upperY = (-Number.MAX_VALUE);
+ for (var j = 0; j < count; ++j) {
+ var dX = p[j].x - root.x;
+ var dY = p[j].y - root.y;
+ var rX = (uxX * dX + uxY * dY);
+ var rY = (uyX * dX + uyY * dY);
+ if (rX < lowerX) lowerX = rX;
+ if (rY < lowerY) lowerY = rY;
+ if (rX > upperX) upperX = rX;
+ if (rY > upperY) upperY = rY;
+ }
+ var area = (upperX - lowerX) * (upperY - lowerY);
+ if (area < 0.95 * minArea) {
+ minArea = area;
+ obb.R.col1.x = uxX;
+ obb.R.col1.y = uxY;
+ obb.R.col2.x = uyX;
+ obb.R.col2.y = uyY;
+ var centerX = 0.5 * (lowerX + upperX);
+ var centerY = 0.5 * (lowerY + upperY);
+ var tMat = obb.R;
+ obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY);
+ obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY);
+ obb.extents.x = 0.5 * (upperX - lowerX);
+ obb.extents.y = 0.5 * (upperY - lowerY);
+ }
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.Shapes.b2PolygonShape.s_mat = new b2Mat22();
+ });
+ b2Shape.b2Shape = function () {};
+ b2Shape.prototype.Copy = function () {
+ return null;
+ }
+ b2Shape.prototype.Set = function (other) {
+ this.m_radius = other.m_radius;
+ }
+ b2Shape.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Shape.prototype.TestPoint = function (xf, p) {
+ return false;
+ }
+ b2Shape.prototype.RayCast = function (output, input, transform) {
+ return false;
+ }
+ b2Shape.prototype.ComputeAABB = function (aabb, xf) {}
+ b2Shape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ }
+ b2Shape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ return 0;
+ }
+ b2Shape.TestOverlap = function (shape1, transform1, shape2, transform2) {
+ var input = new b2DistanceInput();
+ input.proxyA = new b2DistanceProxy();
+ input.proxyA.Set(shape1);
+ input.proxyB = new b2DistanceProxy();
+ input.proxyB.Set(shape2);
+ input.transformA = transform1;
+ input.transformB = transform2;
+ input.useRadii = true;
+ var simplexCache = new b2SimplexCache();
+ simplexCache.count = 0;
+ var output = new b2DistanceOutput();
+ b2Distance.Distance(output, simplexCache, input);
+ return output.distance < 10.0 * Number.MIN_VALUE;
+ }
+ b2Shape.prototype.b2Shape = function () {
+ this.m_type = b2Shape.e_unknownShape;
+ this.m_radius = b2Settings.b2_linearSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.Shapes.b2Shape.e_unknownShape = parseInt((-1));
+ Box2D.Collision.Shapes.b2Shape.e_circleShape = 0;
+ Box2D.Collision.Shapes.b2Shape.e_polygonShape = 1;
+ Box2D.Collision.Shapes.b2Shape.e_edgeShape = 2;
+ Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount = 3;
+ Box2D.Collision.Shapes.b2Shape.e_hitCollide = 1;
+ Box2D.Collision.Shapes.b2Shape.e_missCollide = 0;
+ Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide = parseInt((-1));
+ });
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3;
+
+ b2Color.b2Color = function () {
+ this._r = 0;
+ this._g = 0;
+ this._b = 0;
+ };
+ b2Color.prototype.b2Color = function (rr, gg, bb) {
+ if (rr === undefined) rr = 0;
+ if (gg === undefined) gg = 0;
+ if (bb === undefined) bb = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ b2Color.prototype.Set = function (rr, gg, bb) {
+ if (rr === undefined) rr = 0;
+ if (gg === undefined) gg = 0;
+ if (bb === undefined) bb = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ Object.defineProperty(b2Color.prototype, 'r', {
+ enumerable: false,
+ configurable: true,
+ set: function (rr) {
+ if (rr === undefined) rr = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'g', {
+ enumerable: false,
+ configurable: true,
+ set: function (gg) {
+ if (gg === undefined) gg = 0;
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'b', {
+ enumerable: false,
+ configurable: true,
+ set: function (bb) {
+ if (bb === undefined) bb = 0;
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'color', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return (this._r << 16) | (this._g << 8) | (this._b);
+ }
+ });
+ b2Settings.b2Settings = function () {};
+ b2Settings.b2MixFriction = function (friction1, friction2) {
+ if (friction1 === undefined) friction1 = 0;
+ if (friction2 === undefined) friction2 = 0;
+ return Math.sqrt(friction1 * friction2);
+ }
+ b2Settings.b2MixRestitution = function (restitution1, restitution2) {
+ if (restitution1 === undefined) restitution1 = 0;
+ if (restitution2 === undefined) restitution2 = 0;
+ return restitution1 > restitution2 ? restitution1 : restitution2;
+ }
+ b2Settings.b2Assert = function (a) {
+ if (!a) {
+ throw "Assertion Failed";
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Common.b2Settings.VERSION = "2.1alpha";
+ Box2D.Common.b2Settings.USHRT_MAX = 0x0000ffff;
+ Box2D.Common.b2Settings.b2_pi = Math.PI;
+ Box2D.Common.b2Settings.b2_maxManifoldPoints = 2;
+ Box2D.Common.b2Settings.b2_aabbExtension = 0.1;
+ Box2D.Common.b2Settings.b2_aabbMultiplier = 2.0;
+ Box2D.Common.b2Settings.b2_polygonRadius = 2.0 * b2Settings.b2_linearSlop;
+ Box2D.Common.b2Settings.b2_linearSlop = 0.005;
+ Box2D.Common.b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_toiSlop = 8.0 * b2Settings.b2_linearSlop;
+ Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland = 32;
+ Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland = 32;
+ Box2D.Common.b2Settings.b2_velocityThreshold = 1.0;
+ Box2D.Common.b2Settings.b2_maxLinearCorrection = 0.2;
+ Box2D.Common.b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_maxTranslation = 2.0;
+ Box2D.Common.b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation;
+ Box2D.Common.b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation;
+ Box2D.Common.b2Settings.b2_contactBaumgarte = 0.2;
+ Box2D.Common.b2Settings.b2_timeToSleep = 0.5;
+ Box2D.Common.b2Settings.b2_linearSleepTolerance = 0.01;
+ Box2D.Common.b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 * b2Settings.b2_pi;
+ });
+})();
+(function () {
+ var b2AABB = Box2D.Collision.b2AABB,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3;
+
+ b2Mat22.b2Mat22 = function () {
+ this.col1 = new b2Vec2();
+ this.col2 = new b2Vec2();
+ };
+ b2Mat22.prototype.b2Mat22 = function () {
+ this.SetIdentity();
+ }
+ b2Mat22.FromAngle = function (angle) {
+ if (angle === undefined) angle = 0;
+ var mat = new b2Mat22();
+ mat.Set(angle);
+ return mat;
+ }
+ b2Mat22.FromVV = function (c1, c2) {
+ var mat = new b2Mat22();
+ mat.SetVV(c1, c2);
+ return mat;
+ }
+ b2Mat22.prototype.Set = function (angle) {
+ if (angle === undefined) angle = 0;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ this.col1.x = c;
+ this.col2.x = (-s);
+ this.col1.y = s;
+ this.col2.y = c;
+ }
+ b2Mat22.prototype.SetVV = function (c1, c2) {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ }
+ b2Mat22.prototype.Copy = function () {
+ var mat = new b2Mat22();
+ mat.SetM(this);
+ return mat;
+ }
+ b2Mat22.prototype.SetM = function (m) {
+ this.col1.SetV(m.col1);
+ this.col2.SetV(m.col2);
+ }
+ b2Mat22.prototype.AddM = function (m) {
+ this.col1.x += m.col1.x;
+ this.col1.y += m.col1.y;
+ this.col2.x += m.col2.x;
+ this.col2.y += m.col2.y;
+ }
+ b2Mat22.prototype.SetIdentity = function () {
+ this.col1.x = 1.0;
+ this.col2.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 1.0;
+ }
+ b2Mat22.prototype.SetZero = function () {
+ this.col1.x = 0.0;
+ this.col2.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 0.0;
+ }
+ b2Mat22.prototype.GetAngle = function () {
+ return Math.atan2(this.col1.y, this.col1.x);
+ }
+ b2Mat22.prototype.GetInverse = function (out) {
+ var a = this.col1.x;
+ var b = this.col2.x;
+ var c = this.col1.y;
+ var d = this.col2.y;
+ var det = a * d - b * c;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.col1.x = det * d;
+ out.col2.x = (-det * b);
+ out.col1.y = (-det * c);
+ out.col2.y = det * a;
+ return out;
+ }
+ b2Mat22.prototype.Solve = function (out, bX, bY) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ var a11 = this.col1.x;
+ var a12 = this.col2.x;
+ var a21 = this.col1.y;
+ var a22 = this.col2.y;
+ var det = a11 * a22 - a12 * a21;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (a22 * bX - a12 * bY);
+ out.y = det * (a11 * bY - a21 * bX);
+ return out;
+ }
+ b2Mat22.prototype.Abs = function () {
+ this.col1.Abs();
+ this.col2.Abs();
+ }
+ b2Mat33.b2Mat33 = function () {
+ this.col1 = new b2Vec3();
+ this.col2 = new b2Vec3();
+ this.col3 = new b2Vec3();
+ };
+ b2Mat33.prototype.b2Mat33 = function (c1, c2, c3) {
+ if (c1 === undefined) c1 = null;
+ if (c2 === undefined) c2 = null;
+ if (c3 === undefined) c3 = null;
+ if (!c1 && !c2 && !c3) {
+ this.col1.SetZero();
+ this.col2.SetZero();
+ this.col3.SetZero();
+ }
+ else {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ this.col3.SetV(c3);
+ }
+ }
+ b2Mat33.prototype.SetVVV = function (c1, c2, c3) {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ this.col3.SetV(c3);
+ }
+ b2Mat33.prototype.Copy = function () {
+ return new b2Mat33(this.col1, this.col2, this.col3);
+ }
+ b2Mat33.prototype.SetM = function (m) {
+ this.col1.SetV(m.col1);
+ this.col2.SetV(m.col2);
+ this.col3.SetV(m.col3);
+ }
+ b2Mat33.prototype.AddM = function (m) {
+ this.col1.x += m.col1.x;
+ this.col1.y += m.col1.y;
+ this.col1.z += m.col1.z;
+ this.col2.x += m.col2.x;
+ this.col2.y += m.col2.y;
+ this.col2.z += m.col2.z;
+ this.col3.x += m.col3.x;
+ this.col3.y += m.col3.y;
+ this.col3.z += m.col3.z;
+ }
+ b2Mat33.prototype.SetIdentity = function () {
+ this.col1.x = 1.0;
+ this.col2.x = 0.0;
+ this.col3.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 1.0;
+ this.col3.y = 0.0;
+ this.col1.z = 0.0;
+ this.col2.z = 0.0;
+ this.col3.z = 1.0;
+ }
+ b2Mat33.prototype.SetZero = function () {
+ this.col1.x = 0.0;
+ this.col2.x = 0.0;
+ this.col3.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 0.0;
+ this.col3.y = 0.0;
+ this.col1.z = 0.0;
+ this.col2.z = 0.0;
+ this.col3.z = 0.0;
+ }
+ b2Mat33.prototype.Solve22 = function (out, bX, bY) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ var a11 = this.col1.x;
+ var a12 = this.col2.x;
+ var a21 = this.col1.y;
+ var a22 = this.col2.y;
+ var det = a11 * a22 - a12 * a21;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (a22 * bX - a12 * bY);
+ out.y = det * (a11 * bY - a21 * bX);
+ return out;
+ }
+ b2Mat33.prototype.Solve33 = function (out, bX, bY, bZ) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ if (bZ === undefined) bZ = 0;
+ var a11 = this.col1.x;
+ var a21 = this.col1.y;
+ var a31 = this.col1.z;
+ var a12 = this.col2.x;
+ var a22 = this.col2.y;
+ var a32 = this.col2.z;
+ var a13 = this.col3.x;
+ var a23 = this.col3.y;
+ var a33 = this.col3.z;
+ var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13);
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13));
+ out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13));
+ out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX));
+ return out;
+ }
+ b2Math.b2Math = function () {};
+ b2Math.IsValid = function (x) {
+ if (x === undefined) x = 0;
+ return isFinite(x);
+ }
+ b2Math.Dot = function (a, b) {
+ return a.x * b.x + a.y * b.y;
+ }
+ b2Math.CrossVV = function (a, b) {
+ return a.x * b.y - a.y * b.x;
+ }
+ b2Math.CrossVF = function (a, s) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2(s * a.y, (-s * a.x));
+ return v;
+ }
+ b2Math.CrossFV = function (s, a) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2((-s * a.y), s * a.x);
+ return v;
+ }
+ b2Math.MulMV = function (A, v) {
+ var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
+ return u;
+ }
+ b2Math.MulTMV = function (A, v) {
+ var u = new b2Vec2(b2Math.Dot(v, A.col1), b2Math.Dot(v, A.col2));
+ return u;
+ }
+ b2Math.MulX = function (T, v) {
+ var a = b2Math.MulMV(T.R, v);
+ a.x += T.position.x;
+ a.y += T.position.y;
+ return a;
+ }
+ b2Math.MulXT = function (T, v) {
+ var a = b2Math.SubtractVV(v, T.position);
+ var tX = (a.x * T.R.col1.x + a.y * T.R.col1.y);
+ a.y = (a.x * T.R.col2.x + a.y * T.R.col2.y);
+ a.x = tX;
+ return a;
+ }
+ b2Math.AddVV = function (a, b) {
+ var v = new b2Vec2(a.x + b.x, a.y + b.y);
+ return v;
+ }
+ b2Math.SubtractVV = function (a, b) {
+ var v = new b2Vec2(a.x - b.x, a.y - b.y);
+ return v;
+ }
+ b2Math.Distance = function (a, b) {
+ var cX = a.x - b.x;
+ var cY = a.y - b.y;
+ return Math.sqrt(cX * cX + cY * cY);
+ }
+ b2Math.DistanceSquared = function (a, b) {
+ var cX = a.x - b.x;
+ var cY = a.y - b.y;
+ return (cX * cX + cY * cY);
+ }
+ b2Math.MulFV = function (s, a) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2(s * a.x, s * a.y);
+ return v;
+ }
+ b2Math.AddMM = function (A, B) {
+ var C = b2Mat22.FromVV(b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2));
+ return C;
+ }
+ b2Math.MulMM = function (A, B) {
+ var C = b2Mat22.FromVV(b2Math.MulMV(A, B.col1), b2Math.MulMV(A, B.col2));
+ return C;
+ }
+ b2Math.MulTMM = function (A, B) {
+ var c1 = new b2Vec2(b2Math.Dot(A.col1, B.col1), b2Math.Dot(A.col2, B.col1));
+ var c2 = new b2Vec2(b2Math.Dot(A.col1, B.col2), b2Math.Dot(A.col2, B.col2));
+ var C = b2Mat22.FromVV(c1, c2);
+ return C;
+ }
+ b2Math.Abs = function (a) {
+ if (a === undefined) a = 0;
+ return a > 0.0 ? a : (-a);
+ }
+ b2Math.AbsV = function (a) {
+ var b = new b2Vec2(b2Math.Abs(a.x), b2Math.Abs(a.y));
+ return b;
+ }
+ b2Math.AbsM = function (A) {
+ var B = b2Mat22.FromVV(b2Math.AbsV(A.col1), b2Math.AbsV(A.col2));
+ return B;
+ }
+ b2Math.Min = function (a, b) {
+ if (a === undefined) a = 0;
+ if (b === undefined) b = 0;
+ return a < b ? a : b;
+ }
+ b2Math.MinV = function (a, b) {
+ var c = new b2Vec2(b2Math.Min(a.x, b.x), b2Math.Min(a.y, b.y));
+ return c;
+ }
+ b2Math.Max = function (a, b) {
+ if (a === undefined) a = 0;
+ if (b === undefined) b = 0;
+ return a > b ? a : b;
+ }
+ b2Math.MaxV = function (a, b) {
+ var c = new b2Vec2(b2Math.Max(a.x, b.x), b2Math.Max(a.y, b.y));
+ return c;
+ }
+ b2Math.Clamp = function (a, low, high) {
+ if (a === undefined) a = 0;
+ if (low === undefined) low = 0;
+ if (high === undefined) high = 0;
+ return a < low ? low : a > high ? high : a;
+ }
+ b2Math.ClampV = function (a, low, high) {
+ return b2Math.MaxV(low, b2Math.MinV(a, high));
+ }
+ b2Math.Swap = function (a, b) {
+ var tmp = a[0];
+ a[0] = b[0];
+ b[0] = tmp;
+ }
+ b2Math.Random = function () {
+ return Math.random() * 2 - 1;
+ }
+ b2Math.RandomRange = function (lo, hi) {
+ if (lo === undefined) lo = 0;
+ if (hi === undefined) hi = 0;
+ var r = Math.random();
+ r = (hi - lo) * r + lo;
+ return r;
+ }
+ b2Math.NextPowerOfTwo = function (x) {
+ if (x === undefined) x = 0;
+ x |= (x >> 1) & 0x7FFFFFFF;
+ x |= (x >> 2) & 0x3FFFFFFF;
+ x |= (x >> 4) & 0x0FFFFFFF;
+ x |= (x >> 8) & 0x00FFFFFF;
+ x |= (x >> 16) & 0x0000FFFF;
+ return x + 1;
+ }
+ b2Math.IsPowerOfTwo = function (x) {
+ if (x === undefined) x = 0;
+ var result = x > 0 && (x & (x - 1)) == 0;
+ return result;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Common.Math.b2Math.b2Vec2_zero = new b2Vec2(0.0, 0.0);
+ Box2D.Common.Math.b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1.0, 0.0), new b2Vec2(0.0, 1.0));
+ Box2D.Common.Math.b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity);
+ });
+ b2Sweep.b2Sweep = function () {
+ this.localCenter = new b2Vec2();
+ this.c0 = new b2Vec2;
+ this.c = new b2Vec2();
+ };
+ b2Sweep.prototype.Set = function (other) {
+ this.localCenter.SetV(other.localCenter);
+ this.c0.SetV(other.c0);
+ this.c.SetV(other.c);
+ this.a0 = other.a0;
+ this.a = other.a;
+ this.t0 = other.t0;
+ }
+ b2Sweep.prototype.Copy = function () {
+ var copy = new b2Sweep();
+ copy.localCenter.SetV(this.localCenter);
+ copy.c0.SetV(this.c0);
+ copy.c.SetV(this.c);
+ copy.a0 = this.a0;
+ copy.a = this.a;
+ copy.t0 = this.t0;
+ return copy;
+ }
+ b2Sweep.prototype.GetTransform = function (xf, alpha) {
+ if (alpha === undefined) alpha = 0;
+ xf.position.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x;
+ xf.position.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y;
+ var angle = (1.0 - alpha) * this.a0 + alpha * this.a;
+ xf.R.Set(angle);
+ var tMat = xf.R;
+ xf.position.x -= (tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y);
+ xf.position.y -= (tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y);
+ }
+ b2Sweep.prototype.Advance = function (t) {
+ if (t === undefined) t = 0;
+ if (this.t0 < t && 1.0 - this.t0 > Number.MIN_VALUE) {
+ var alpha = (t - this.t0) / (1.0 - this.t0);
+ this.c0.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x;
+ this.c0.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y;
+ this.a0 = (1.0 - alpha) * this.a0 + alpha * this.a;
+ this.t0 = t;
+ }
+ }
+ b2Transform.b2Transform = function () {
+ this.position = new b2Vec2;
+ this.R = new b2Mat22();
+ };
+ b2Transform.prototype.b2Transform = function (pos, r) {
+ if (pos === undefined) pos = null;
+ if (r === undefined) r = null;
+ if (pos) {
+ this.position.SetV(pos);
+ this.R.SetM(r);
+ }
+ }
+ b2Transform.prototype.Initialize = function (pos, r) {
+ this.position.SetV(pos);
+ this.R.SetM(r);
+ }
+ b2Transform.prototype.SetIdentity = function () {
+ this.position.SetZero();
+ this.R.SetIdentity();
+ }
+ b2Transform.prototype.Set = function (x) {
+ this.position.SetV(x.position);
+ this.R.SetM(x.R);
+ }
+ b2Transform.prototype.GetAngle = function () {
+ return Math.atan2(this.R.col1.y, this.R.col1.x);
+ }
+ b2Vec2.b2Vec2 = function () {};
+ b2Vec2.prototype.b2Vec2 = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ this.x = x_;
+ this.y = y_;
+ }
+ b2Vec2.prototype.SetZero = function () {
+ this.x = 0.0;
+ this.y = 0.0;
+ }
+ b2Vec2.prototype.Set = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ this.x = x_;
+ this.y = y_;
+ }
+ b2Vec2.prototype.SetV = function (v) {
+ this.x = v.x;
+ this.y = v.y;
+ }
+ b2Vec2.prototype.GetNegative = function () {
+ return new b2Vec2((-this.x), (-this.y));
+ }
+ b2Vec2.prototype.NegativeSelf = function () {
+ this.x = (-this.x);
+ this.y = (-this.y);
+ }
+ b2Vec2.Make = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ return new b2Vec2(x_, y_);
+ }
+ b2Vec2.prototype.Copy = function () {
+ return new b2Vec2(this.x, this.y);
+ }
+ b2Vec2.prototype.Add = function (v) {
+ this.x += v.x;
+ this.y += v.y;
+ }
+ b2Vec2.prototype.Subtract = function (v) {
+ this.x -= v.x;
+ this.y -= v.y;
+ }
+ b2Vec2.prototype.Multiply = function (a) {
+ if (a === undefined) a = 0;
+ this.x *= a;
+ this.y *= a;
+ }
+ b2Vec2.prototype.MulM = function (A) {
+ var tX = this.x;
+ this.x = A.col1.x * tX + A.col2.x * this.y;
+ this.y = A.col1.y * tX + A.col2.y * this.y;
+ }
+ b2Vec2.prototype.MulTM = function (A) {
+ var tX = b2Math.Dot(this, A.col1);
+ this.y = b2Math.Dot(this, A.col2);
+ this.x = tX;
+ }
+ b2Vec2.prototype.CrossVF = function (s) {
+ if (s === undefined) s = 0;
+ var tX = this.x;
+ this.x = s * this.y;
+ this.y = (-s * tX);
+ }
+ b2Vec2.prototype.CrossFV = function (s) {
+ if (s === undefined) s = 0;
+ var tX = this.x;
+ this.x = (-s * this.y);
+ this.y = s * tX;
+ }
+ b2Vec2.prototype.MinV = function (b) {
+ this.x = this.x < b.x ? this.x : b.x;
+ this.y = this.y < b.y ? this.y : b.y;
+ }
+ b2Vec2.prototype.MaxV = function (b) {
+ this.x = this.x > b.x ? this.x : b.x;
+ this.y = this.y > b.y ? this.y : b.y;
+ }
+ b2Vec2.prototype.Abs = function () {
+ if (this.x < 0) this.x = (-this.x);
+ if (this.y < 0) this.y = (-this.y);
+ }
+ b2Vec2.prototype.Length = function () {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ b2Vec2.prototype.LengthSquared = function () {
+ return (this.x * this.x + this.y * this.y);
+ }
+ b2Vec2.prototype.Normalize = function () {
+ var length = Math.sqrt(this.x * this.x + this.y * this.y);
+ if (length < Number.MIN_VALUE) {
+ return 0.0;
+ }
+ var invLength = 1.0 / length;
+ this.x *= invLength;
+ this.y *= invLength;
+ return length;
+ }
+ b2Vec2.prototype.IsValid = function () {
+ return b2Math.IsValid(this.x) && b2Math.IsValid(this.y);
+ }
+ b2Vec3.b2Vec3 = function () {};
+ b2Vec3.prototype.b2Vec3 = function (x, y, z) {
+ if (x === undefined) x = 0;
+ if (y === undefined) y = 0;
+ if (z === undefined) z = 0;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ b2Vec3.prototype.SetZero = function () {
+ this.x = this.y = this.z = 0.0;
+ }
+ b2Vec3.prototype.Set = function (x, y, z) {
+ if (x === undefined) x = 0;
+ if (y === undefined) y = 0;
+ if (z === undefined) z = 0;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ b2Vec3.prototype.SetV = function (v) {
+ this.x = v.x;
+ this.y = v.y;
+ this.z = v.z;
+ }
+ b2Vec3.prototype.GetNegative = function () {
+ return new b2Vec3((-this.x), (-this.y), (-this.z));
+ }
+ b2Vec3.prototype.NegativeSelf = function () {
+ this.x = (-this.x);
+ this.y = (-this.y);
+ this.z = (-this.z);
+ }
+ b2Vec3.prototype.Copy = function () {
+ return new b2Vec3(this.x, this.y, this.z);
+ }
+ b2Vec3.prototype.Add = function (v) {
+ this.x += v.x;
+ this.y += v.y;
+ this.z += v.z;
+ }
+ b2Vec3.prototype.Subtract = function (v) {
+ this.x -= v.x;
+ this.y -= v.y;
+ this.z -= v.z;
+ }
+ b2Vec3.prototype.Multiply = function (a) {
+ if (a === undefined) a = 0;
+ this.x *= a;
+ this.y *= a;
+ this.z *= a;
+ }
+})();
+(function () {
+ var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact,
+ b2Contact = Box2D.Dynamics.Contacts.b2Contact,
+ b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint,
+ b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint,
+ b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge,
+ b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory,
+ b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister,
+ b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult,
+ b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver,
+ b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,
+ b2NullContact = Box2D.Dynamics.Contacts.b2NullContact,
+ b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact,
+ b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,
+ b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact,
+ b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold,
+ b2Controller = Box2D.Dynamics.Controllers.b2Controller,
+ b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint,
+ b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef,
+ b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint,
+ b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef,
+ b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint,
+ b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef,
+ b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian,
+ b2Joint = Box2D.Dynamics.Joints.b2Joint,
+ b2JointDef = Box2D.Dynamics.Joints.b2JointDef,
+ b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge,
+ b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint,
+ b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef,
+ b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint,
+ b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
+ b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint,
+ b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef,
+ b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint,
+ b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef,
+ b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
+ b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef,
+ b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint,
+ b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef;
+
+ b2Body.b2Body = function () {
+ this.m_xf = new b2Transform();
+ this.m_sweep = new b2Sweep();
+ this.m_linearVelocity = new b2Vec2();
+ this.m_force = new b2Vec2();
+ };
+ b2Body.prototype.connectEdges = function (s1, s2, angle1) {
+ if (angle1 === undefined) angle1 = 0;
+ var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x);
+ var coreOffset = Math.tan((angle2 - angle1) * 0.5);
+ var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector());
+ core = b2Math.SubtractVV(core, s2.GetNormalVector());
+ core = b2Math.MulFV(b2Settings.b2_toiSlop, core);
+ core = b2Math.AddVV(core, s2.GetVertex1());
+ var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector());
+ cornerDir.Normalize();
+ var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0.0;
+ s1.SetNextEdge(s2, core, cornerDir, convex);
+ s2.SetPrevEdge(s1, core, cornerDir, convex);
+ return angle2;
+ }
+ b2Body.prototype.CreateFixture = function (def) {
+ if (this.m_world.IsLocked() == true) {
+ return null;
+ }
+ var fixture = new b2Fixture();
+ fixture.Create(this, this.m_xf, def);
+ if (this.m_flags & b2Body.e_activeFlag) {
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ fixture.CreateProxy(broadPhase, this.m_xf);
+ }
+ fixture.m_next = this.m_fixtureList;
+ this.m_fixtureList = fixture;
+ ++this.m_fixtureCount;
+ fixture.m_body = this;
+ if (fixture.m_density > 0.0) {
+ this.ResetMassData();
+ }
+ this.m_world.m_flags |= b2World.e_newFixture;
+ return fixture;
+ }
+ b2Body.prototype.CreateFixture2 = function (shape, density) {
+ if (density === undefined) density = 0.0;
+ var def = new b2FixtureDef();
+ def.shape = shape;
+ def.density = density;
+ return this.CreateFixture(def);
+ }
+ b2Body.prototype.DestroyFixture = function (fixture) {
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ var node = this.m_fixtureList;
+ var ppF = null;
+ var found = false;
+ while (node != null) {
+ if (node == fixture) {
+ if (ppF) ppF.m_next = fixture.m_next;
+ else this.m_fixtureList = fixture.m_next;
+ found = true;
+ break;
+ }
+ ppF = node;
+ node = node.m_next;
+ }
+ var edge = this.m_contactList;
+ while (edge) {
+ var c = edge.contact;
+ edge = edge.next;
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ if (fixture == fixtureA || fixture == fixtureB) {
+ this.m_world.m_contactManager.Destroy(c);
+ }
+ }
+ if (this.m_flags & b2Body.e_activeFlag) {
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ fixture.DestroyProxy(broadPhase);
+ }
+ else {}
+ fixture.Destroy();
+ fixture.m_body = null;
+ fixture.m_next = null;
+ --this.m_fixtureCount;
+ this.ResetMassData();
+ }
+ b2Body.prototype.SetPositionAndAngle = function (position, angle) {
+ if (angle === undefined) angle = 0;
+ var f;
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ this.m_xf.R.Set(angle);
+ this.m_xf.position.SetV(position);
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_sweep.c.x += this.m_xf.position.x;
+ this.m_sweep.c.y += this.m_xf.position.y;
+ this.m_sweep.c0.SetV(this.m_sweep.c);
+ this.m_sweep.a0 = this.m_sweep.a = angle;
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.Synchronize(broadPhase, this.m_xf, this.m_xf);
+ }
+ this.m_world.m_contactManager.FindNewContacts();
+ }
+ b2Body.prototype.SetTransform = function (xf) {
+ this.SetPositionAndAngle(xf.position, xf.GetAngle());
+ }
+ b2Body.prototype.GetTransform = function () {
+ return this.m_xf;
+ }
+ b2Body.prototype.GetPosition = function () {
+ return this.m_xf.position;
+ }
+ b2Body.prototype.SetPosition = function (position) {
+ this.SetPositionAndAngle(position, this.GetAngle());
+ }
+ b2Body.prototype.GetAngle = function () {
+ return this.m_sweep.a;
+ }
+ b2Body.prototype.SetAngle = function (angle) {
+ if (angle === undefined) angle = 0;
+ this.SetPositionAndAngle(this.GetPosition(), angle);
+ }
+ b2Body.prototype.GetWorldCenter = function () {
+ return this.m_sweep.c;
+ }
+ b2Body.prototype.GetLocalCenter = function () {
+ return this.m_sweep.localCenter;
+ }
+ b2Body.prototype.SetLinearVelocity = function (v) {
+ if (this.m_type == b2Body.b2_staticBody) {
+ return;
+ }
+ this.m_linearVelocity.SetV(v);
+ }
+ b2Body.prototype.GetLinearVelocity = function () {
+ return this.m_linearVelocity;
+ }
+ b2Body.prototype.SetAngularVelocity = function (omega) {
+ if (omega === undefined) omega = 0;
+ if (this.m_type == b2Body.b2_staticBody) {
+ return;
+ }
+ this.m_angularVelocity = omega;
+ }
+ b2Body.prototype.GetAngularVelocity = function () {
+ return this.m_angularVelocity;
+ }
+ b2Body.prototype.GetDefinition = function () {
+ var bd = new b2BodyDef();
+ bd.type = this.GetType();
+ bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag;
+ bd.angle = this.GetAngle();
+ bd.angularDamping = this.m_angularDamping;
+ bd.angularVelocity = this.m_angularVelocity;
+ bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag;
+ bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag;
+ bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag;
+ bd.linearDamping = this.m_linearDamping;
+ bd.linearVelocity.SetV(this.GetLinearVelocity());
+ bd.position = this.GetPosition();
+ bd.userData = this.GetUserData();
+ return bd;
+ }
+ b2Body.prototype.ApplyForce = function (force, point) {
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_force.x += force.x;
+ this.m_force.y += force.y;
+ this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x);
+ }
+ b2Body.prototype.ApplyTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_torque += torque;
+ }
+ b2Body.prototype.ApplyImpulse = function (impulse, point) {
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_linearVelocity.x += this.m_invMass * impulse.x;
+ this.m_linearVelocity.y += this.m_invMass * impulse.y;
+ this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x);
+ }
+ b2Body.prototype.Split = function (callback) {
+ var linearVelocity = this.GetLinearVelocity().Copy();
+ var angularVelocity = this.GetAngularVelocity();
+ var center = this.GetWorldCenter();
+ var body1 = this;
+ var body2 = this.m_world.CreateBody(this.GetDefinition());
+ var prev;
+ for (var f = body1.m_fixtureList; f;) {
+ if (callback(f)) {
+ var next = f.m_next;
+ if (prev) {
+ prev.m_next = next;
+ }
+ else {
+ body1.m_fixtureList = next;
+ }
+ body1.m_fixtureCount--;
+ f.m_next = body2.m_fixtureList;
+ body2.m_fixtureList = f;
+ body2.m_fixtureCount++;
+ f.m_body = body2;
+ f = next;
+ }
+ else {
+ prev = f;
+ f = f.m_next;
+ }
+ }
+ body1.ResetMassData();
+ body2.ResetMassData();
+ var center1 = body1.GetWorldCenter();
+ var center2 = body2.GetWorldCenter();
+ var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center)));
+ var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center)));
+ body1.SetLinearVelocity(velocity1);
+ body2.SetLinearVelocity(velocity2);
+ body1.SetAngularVelocity(angularVelocity);
+ body2.SetAngularVelocity(angularVelocity);
+ body1.SynchronizeFixtures();
+ body2.SynchronizeFixtures();
+ return body2;
+ }
+ b2Body.prototype.Merge = function (other) {
+ var f;
+ for (f = other.m_fixtureList;
+ f;) {
+ var next = f.m_next;
+ other.m_fixtureCount--;
+ f.m_next = this.m_fixtureList;
+ this.m_fixtureList = f;
+ this.m_fixtureCount++;
+ f.m_body = body2;
+ f = next;
+ }
+ body1.m_fixtureCount = 0;
+ var body1 = this;
+
+ var body2 = other;
+ var center1 = body1.GetWorldCenter();
+ var center2 = body2.GetWorldCenter();
+ var velocity1 = body1.GetLinearVelocity().Copy();
+ var velocity2 = body2.GetLinearVelocity().Copy();
+ var angular1 = body1.GetAngularVelocity();
+ var angular = body2.GetAngularVelocity();
+ body1.ResetMassData();
+ this.SynchronizeFixtures();
+ }
+ b2Body.prototype.GetMass = function () {
+ return this.m_mass;
+ }
+ b2Body.prototype.GetInertia = function () {
+ return this.m_I;
+ }
+ b2Body.prototype.GetMassData = function (data) {
+ data.mass = this.m_mass;
+ data.I = this.m_I;
+ data.center.SetV(this.m_sweep.localCenter);
+ }
+ b2Body.prototype.SetMassData = function (massData) {
+ b2Settings.b2Assert(this.m_world.IsLocked() == false);
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ this.m_invMass = 0.0;
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_mass = massData.mass;
+ if (this.m_mass <= 0.0) {
+ this.m_mass = 1.0;
+ }
+ this.m_invMass = 1.0 / this.m_mass;
+ if (massData.I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) {
+ this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y);
+ this.m_invI = 1.0 / this.m_I;
+ }
+ var oldCenter = this.m_sweep.c.Copy();
+ this.m_sweep.localCenter.SetV(massData.center);
+ this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter));
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y));
+ this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x));
+ }
+ b2Body.prototype.ResetMassData = function () {
+ this.m_mass = 0.0;
+ this.m_invMass = 0.0;
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_sweep.localCenter.SetZero();
+ if (this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) {
+ return;
+ }
+ var center = b2Vec2.Make(0, 0);
+ for (var f = this.m_fixtureList; f; f = f.m_next) {
+ if (f.m_density == 0.0) {
+ continue;
+ }
+ var massData = f.GetMassData();
+ this.m_mass += massData.mass;
+ center.x += massData.center.x * massData.mass;
+ center.y += massData.center.y * massData.mass;
+ this.m_I += massData.I;
+ }
+ if (this.m_mass > 0.0) {
+ this.m_invMass = 1.0 / this.m_mass;
+ center.x *= this.m_invMass;
+ center.y *= this.m_invMass;
+ }
+ else {
+ this.m_mass = 1.0;
+ this.m_invMass = 1.0;
+ }
+ if (this.m_I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) {
+ this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y);
+ this.m_I *= this.m_inertiaScale;
+ b2Settings.b2Assert(this.m_I > 0);
+ this.m_invI = 1.0 / this.m_I;
+ }
+ else {
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ }
+ var oldCenter = this.m_sweep.c.Copy();
+ this.m_sweep.localCenter.SetV(center);
+ this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter));
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y));
+ this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x));
+ }
+ b2Body.prototype.GetWorldPoint = function (localPoint) {
+ var A = this.m_xf.R;
+ var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y);
+ u.x += this.m_xf.position.x;
+ u.y += this.m_xf.position.y;
+ return u;
+ }
+ b2Body.prototype.GetWorldVector = function (localVector) {
+ return b2Math.MulMV(this.m_xf.R, localVector);
+ }
+ b2Body.prototype.GetLocalPoint = function (worldPoint) {
+ return b2Math.MulXT(this.m_xf, worldPoint);
+ }
+ b2Body.prototype.GetLocalVector = function (worldVector) {
+ return b2Math.MulTMV(this.m_xf.R, worldVector);
+ }
+ b2Body.prototype.GetLinearVelocityFromWorldPoint = function (worldPoint) {
+ return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x));
+ }
+ b2Body.prototype.GetLinearVelocityFromLocalPoint = function (localPoint) {
+ var A = this.m_xf.R;
+ var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y);
+ worldPoint.x += this.m_xf.position.x;
+ worldPoint.y += this.m_xf.position.y;
+ return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x));
+ }
+ b2Body.prototype.GetLinearDamping = function () {
+ return this.m_linearDamping;
+ }
+ b2Body.prototype.SetLinearDamping = function (linearDamping) {
+ if (linearDamping === undefined) linearDamping = 0;
+ this.m_linearDamping = linearDamping;
+ }
+ b2Body.prototype.GetAngularDamping = function () {
+ return this.m_angularDamping;
+ }
+ b2Body.prototype.SetAngularDamping = function (angularDamping) {
+ if (angularDamping === undefined) angularDamping = 0;
+ this.m_angularDamping = angularDamping;
+ }
+ b2Body.prototype.SetType = function (type) {
+ if (type === undefined) type = 0;
+ if (this.m_type == type) {
+ return;
+ }
+ this.m_type = type;
+ this.ResetMassData();
+ if (this.m_type == b2Body.b2_staticBody) {
+ this.m_linearVelocity.SetZero();
+ this.m_angularVelocity = 0.0;
+ }
+ this.SetAwake(true);
+ this.m_force.SetZero();
+ this.m_torque = 0.0;
+ for (var ce = this.m_contactList; ce; ce = ce.next) {
+ ce.contact.FlagForFiltering();
+ }
+ }
+ b2Body.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Body.prototype.SetBullet = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_bulletFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_bulletFlag;
+ }
+ }
+ b2Body.prototype.IsBullet = function () {
+ return (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag;
+ }
+ b2Body.prototype.SetSleepingAllowed = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_allowSleepFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_allowSleepFlag;
+ this.SetAwake(true);
+ }
+ }
+ b2Body.prototype.SetAwake = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_awakeFlag;
+ this.m_sleepTime = 0.0;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_awakeFlag;
+ this.m_sleepTime = 0.0;
+ this.m_linearVelocity.SetZero();
+ this.m_angularVelocity = 0.0;
+ this.m_force.SetZero();
+ this.m_torque = 0.0;
+ }
+ }
+ b2Body.prototype.IsAwake = function () {
+ return (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag;
+ }
+ b2Body.prototype.SetFixedRotation = function (fixed) {
+ if (fixed) {
+ this.m_flags |= b2Body.e_fixedRotationFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_fixedRotationFlag;
+ }
+ this.ResetMassData();
+ }
+ b2Body.prototype.IsFixedRotation = function () {
+ return (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag;
+ }
+ b2Body.prototype.SetActive = function (flag) {
+ if (flag == this.IsActive()) {
+ return;
+ }
+ var broadPhase;
+ var f;
+ if (flag) {
+ this.m_flags |= b2Body.e_activeFlag;
+ broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.CreateProxy(broadPhase, this.m_xf);
+ }
+ }
+ else {
+ this.m_flags &= ~b2Body.e_activeFlag;
+ broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.DestroyProxy(broadPhase);
+ }
+ var ce = this.m_contactList;
+ while (ce) {
+ var ce0 = ce;
+ ce = ce.next;
+ this.m_world.m_contactManager.Destroy(ce0.contact);
+ }
+ this.m_contactList = null;
+ }
+ }
+ b2Body.prototype.IsActive = function () {
+ return (this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag;
+ }
+ b2Body.prototype.IsSleepingAllowed = function () {
+ return (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag;
+ }
+ b2Body.prototype.GetFixtureList = function () {
+ return this.m_fixtureList;
+ }
+ b2Body.prototype.GetJointList = function () {
+ return this.m_jointList;
+ }
+ b2Body.prototype.GetControllerList = function () {
+ return this.m_controllerList;
+ }
+ b2Body.prototype.GetContactList = function () {
+ return this.m_contactList;
+ }
+ b2Body.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Body.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Body.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Body.prototype.GetWorld = function () {
+ return this.m_world;
+ }
+ b2Body.prototype.b2Body = function (bd, world) {
+ this.m_flags = 0;
+ if (bd.bullet) {
+ this.m_flags |= b2Body.e_bulletFlag;
+ }
+ if (bd.fixedRotation) {
+ this.m_flags |= b2Body.e_fixedRotationFlag;
+ }
+ if (bd.allowSleep) {
+ this.m_flags |= b2Body.e_allowSleepFlag;
+ }
+ if (bd.awake) {
+ this.m_flags |= b2Body.e_awakeFlag;
+ }
+ if (bd.active) {
+ this.m_flags |= b2Body.e_activeFlag;
+ }
+ this.m_world = world;
+ this.m_xf.position.SetV(bd.position);
+ this.m_xf.R.Set(bd.angle);
+ this.m_sweep.localCenter.SetZero();
+ this.m_sweep.t0 = 1.0;
+ this.m_sweep.a0 = this.m_sweep.a = bd.angle;
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_sweep.c.x += this.m_xf.position.x;
+ this.m_sweep.c.y += this.m_xf.position.y;
+ this.m_sweep.c0.SetV(this.m_sweep.c);
+ this.m_jointList = null;
+ this.m_controllerList = null;
+ this.m_contactList = null;
+ this.m_controllerCount = 0;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_linearVelocity.SetV(bd.linearVelocity);
+ this.m_angularVelocity = bd.angularVelocity;
+ this.m_linearDamping = bd.linearDamping;
+ this.m_angularDamping = bd.angularDamping;
+ this.m_force.Set(0.0, 0.0);
+ this.m_torque = 0.0;
+ this.m_sleepTime = 0.0;
+ this.m_type = bd.type;
+ if (this.m_type == b2Body.b2_dynamicBody) {
+ this.m_mass = 1.0;
+ this.m_invMass = 1.0;
+ }
+ else {
+ this.m_mass = 0.0;
+ this.m_invMass = 0.0;
+ }
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_inertiaScale = bd.inertiaScale;
+ this.m_userData = bd.userData;
+ this.m_fixtureList = null;
+ this.m_fixtureCount = 0;
+ }
+ b2Body.prototype.SynchronizeFixtures = function () {
+ var xf1 = b2Body.s_xf1;
+ xf1.R.Set(this.m_sweep.a0);
+ var tMat = xf1.R;
+ var tVec = this.m_sweep.localCenter;
+ xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var f;
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.Synchronize(broadPhase, xf1, this.m_xf);
+ }
+ }
+ b2Body.prototype.SynchronizeTransform = function () {
+ this.m_xf.R.Set(this.m_sweep.a);
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ }
+ b2Body.prototype.ShouldCollide = function (other) {
+ if (this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) {
+ return false;
+ }
+ for (var jn = this.m_jointList; jn; jn = jn.next) {
+ if (jn.other == other) if (jn.joint.m_collideConnected == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+ b2Body.prototype.Advance = function (t) {
+ if (t === undefined) t = 0;
+ this.m_sweep.Advance(t);
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_sweep.a = this.m_sweep.a0;
+ this.SynchronizeTransform();
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2Body.s_xf1 = new b2Transform();
+ Box2D.Dynamics.b2Body.e_islandFlag = 0x0001;
+ Box2D.Dynamics.b2Body.e_awakeFlag = 0x0002;
+ Box2D.Dynamics.b2Body.e_allowSleepFlag = 0x0004;
+ Box2D.Dynamics.b2Body.e_bulletFlag = 0x0008;
+ Box2D.Dynamics.b2Body.e_fixedRotationFlag = 0x0010;
+ Box2D.Dynamics.b2Body.e_activeFlag = 0x0020;
+ Box2D.Dynamics.b2Body.b2_staticBody = 0;
+ Box2D.Dynamics.b2Body.b2_kinematicBody = 1;
+ Box2D.Dynamics.b2Body.b2_dynamicBody = 2;
+ });
+ b2BodyDef.b2BodyDef = function () {
+ this.position = new b2Vec2();
+ this.linearVelocity = new b2Vec2();
+ };
+ b2BodyDef.prototype.b2BodyDef = function () {
+ this.userData = null;
+ this.position.Set(0.0, 0.0);
+ this.angle = 0.0;
+ this.linearVelocity.Set(0, 0);
+ this.angularVelocity = 0.0;
+ this.linearDamping = 0.0;
+ this.angularDamping = 0.0;
+ this.allowSleep = true;
+ this.awake = true;
+ this.fixedRotation = false;
+ this.bullet = false;
+ this.type = b2Body.b2_staticBody;
+ this.active = true;
+ this.inertiaScale = 1.0;
+ }
+ b2ContactFilter.b2ContactFilter = function () {};
+ b2ContactFilter.prototype.ShouldCollide = function (fixtureA, fixtureB) {
+ var filter1 = fixtureA.GetFilterData();
+ var filter2 = fixtureB.GetFilterData();
+ if (filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) {
+ return filter1.groupIndex > 0;
+ }
+ var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0;
+ return collide;
+ }
+ b2ContactFilter.prototype.RayCollide = function (userData, fixture) {
+ if (!userData) return true;
+ return this.ShouldCollide((userData instanceof b2Fixture ? userData : null), fixture);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactFilter.b2_defaultFilter = new b2ContactFilter();
+ });
+ b2ContactImpulse.b2ContactImpulse = function () {
+ this.normalImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ this.tangentImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ };
+ b2ContactListener.b2ContactListener = function () {};
+ b2ContactListener.prototype.BeginContact = function (contact) {}
+ b2ContactListener.prototype.EndContact = function (contact) {}
+ b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {}
+ b2ContactListener.prototype.PostSolve = function (contact, impulse) {}
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactListener.b2_defaultListener = new b2ContactListener();
+ });
+ b2ContactManager.b2ContactManager = function () {};
+ b2ContactManager.prototype.b2ContactManager = function () {
+ this.m_world = null;
+ this.m_contactCount = 0;
+ this.m_contactFilter = b2ContactFilter.b2_defaultFilter;
+ this.m_contactListener = b2ContactListener.b2_defaultListener;
+ this.m_contactFactory = new b2ContactFactory(this.m_allocator);
+ this.m_broadPhase = new b2DynamicTreeBroadPhase();
+ }
+ b2ContactManager.prototype.AddPair = function (proxyUserDataA, proxyUserDataB) {
+ var fixtureA = (proxyUserDataA instanceof b2Fixture ? proxyUserDataA : null);
+ var fixtureB = (proxyUserDataB instanceof b2Fixture ? proxyUserDataB : null);
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA == bodyB) return;
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ var fA = edge.contact.GetFixtureA();
+ var fB = edge.contact.GetFixtureB();
+ if (fA == fixtureA && fB == fixtureB) return;
+ if (fA == fixtureB && fB == fixtureA) return;
+ }
+ edge = edge.next;
+ }
+ if (bodyB.ShouldCollide(bodyA) == false) {
+ return;
+ }
+ if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) {
+ return;
+ }
+ var c = this.m_contactFactory.Create(fixtureA, fixtureB);
+ fixtureA = c.GetFixtureA();
+ fixtureB = c.GetFixtureB();
+ bodyA = fixtureA.m_body;
+ bodyB = fixtureB.m_body;
+ c.m_prev = null;
+ c.m_next = this.m_world.m_contactList;
+ if (this.m_world.m_contactList != null) {
+ this.m_world.m_contactList.m_prev = c;
+ }
+ this.m_world.m_contactList = c;
+ c.m_nodeA.contact = c;
+ c.m_nodeA.other = bodyB;
+ c.m_nodeA.prev = null;
+ c.m_nodeA.next = bodyA.m_contactList;
+ if (bodyA.m_contactList != null) {
+ bodyA.m_contactList.prev = c.m_nodeA;
+ }
+ bodyA.m_contactList = c.m_nodeA;
+ c.m_nodeB.contact = c;
+ c.m_nodeB.other = bodyA;
+ c.m_nodeB.prev = null;
+ c.m_nodeB.next = bodyB.m_contactList;
+ if (bodyB.m_contactList != null) {
+ bodyB.m_contactList.prev = c.m_nodeB;
+ }
+ bodyB.m_contactList = c.m_nodeB;
+ ++this.m_world.m_contactCount;
+ return;
+ }
+ b2ContactManager.prototype.FindNewContacts = function () {
+ this.m_broadPhase.UpdatePairs(Box2D.generateCallback(this, this.AddPair));
+ }
+ b2ContactManager.prototype.Destroy = function (c) {
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (c.IsTouching()) {
+ this.m_contactListener.EndContact(c);
+ }
+ if (c.m_prev) {
+ c.m_prev.m_next = c.m_next;
+ }
+ if (c.m_next) {
+ c.m_next.m_prev = c.m_prev;
+ }
+ if (c == this.m_world.m_contactList) {
+ this.m_world.m_contactList = c.m_next;
+ }
+ if (c.m_nodeA.prev) {
+ c.m_nodeA.prev.next = c.m_nodeA.next;
+ }
+ if (c.m_nodeA.next) {
+ c.m_nodeA.next.prev = c.m_nodeA.prev;
+ }
+ if (c.m_nodeA == bodyA.m_contactList) {
+ bodyA.m_contactList = c.m_nodeA.next;
+ }
+ if (c.m_nodeB.prev) {
+ c.m_nodeB.prev.next = c.m_nodeB.next;
+ }
+ if (c.m_nodeB.next) {
+ c.m_nodeB.next.prev = c.m_nodeB.prev;
+ }
+ if (c.m_nodeB == bodyB.m_contactList) {
+ bodyB.m_contactList = c.m_nodeB.next;
+ }
+ this.m_contactFactory.Destroy(c);
+ --this.m_contactCount;
+ }
+ b2ContactManager.prototype.Collide = function () {
+ var c = this.m_world.m_contactList;
+ while (c) {
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA.IsAwake() == false && bodyB.IsAwake() == false) {
+ c = c.GetNext();
+ continue;
+ }
+ if (c.m_flags & b2Contact.e_filterFlag) {
+ if (bodyB.ShouldCollide(bodyA) == false) {
+ var cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) {
+ cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ c.m_flags &= ~b2Contact.e_filterFlag;
+ }
+ var proxyA = fixtureA.m_proxy;
+ var proxyB = fixtureB.m_proxy;
+ var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB);
+ if (overlap == false) {
+ cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ c.Update(this.m_contactListener);
+ c = c.GetNext();
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactManager.s_evalCP = new b2ContactPoint();
+ });
+ b2DebugDraw.b2DebugDraw = function () {};
+ b2DebugDraw.prototype.b2DebugDraw = function () {}
+ b2DebugDraw.prototype.SetFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.GetFlags = function () {}
+ b2DebugDraw.prototype.AppendFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.ClearFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.SetSprite = function (sprite) {}
+ b2DebugDraw.prototype.GetSprite = function () {}
+ b2DebugDraw.prototype.SetDrawScale = function (drawScale) {
+ if (drawScale === undefined) drawScale = 0;
+ }
+ b2DebugDraw.prototype.GetDrawScale = function () {}
+ b2DebugDraw.prototype.SetLineThickness = function (lineThickness) {
+ if (lineThickness === undefined) lineThickness = 0;
+ }
+ b2DebugDraw.prototype.GetLineThickness = function () {}
+ b2DebugDraw.prototype.SetAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ }
+ b2DebugDraw.prototype.GetAlpha = function () {}
+ b2DebugDraw.prototype.SetFillAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ }
+ b2DebugDraw.prototype.GetFillAlpha = function () {}
+ b2DebugDraw.prototype.SetXFormScale = function (xformScale) {
+ if (xformScale === undefined) xformScale = 0;
+ }
+ b2DebugDraw.prototype.GetXFormScale = function () {}
+ b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
+ if (vertexCount === undefined) vertexCount = 0;
+ }
+ b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
+ if (vertexCount === undefined) vertexCount = 0;
+ }
+ b2DebugDraw.prototype.DrawCircle = function (center, radius, color) {
+ if (radius === undefined) radius = 0;
+ }
+ b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
+ if (radius === undefined) radius = 0;
+ }
+ b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {}
+ b2DebugDraw.prototype.DrawTransform = function (xf) {}
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001;
+ Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002;
+ Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004;
+ Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008;
+ Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010;
+ Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020;
+ });
+ b2DestructionListener.b2DestructionListener = function () {};
+ b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {}
+ b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {}
+ b2FilterData.b2FilterData = function () {
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.groupIndex = 0;
+ };
+ b2FilterData.prototype.Copy = function () {
+ var copy = new b2FilterData();
+ copy.categoryBits = this.categoryBits;
+ copy.maskBits = this.maskBits;
+ copy.groupIndex = this.groupIndex;
+ return copy;
+ }
+ b2Fixture.b2Fixture = function () {
+ this.m_filter = new b2FilterData();
+ };
+ b2Fixture.prototype.GetType = function () {
+ return this.m_shape.GetType();
+ }
+ b2Fixture.prototype.GetShape = function () {
+ return this.m_shape;
+ }
+ b2Fixture.prototype.SetSensor = function (sensor) {
+ if (this.m_isSensor == sensor) return;
+ this.m_isSensor = sensor;
+ if (this.m_body == null) return;
+ var edge = this.m_body.GetContactList();
+ while (edge) {
+ var contact = edge.contact;
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ if (fixtureA == this || fixtureB == this) contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor());
+ edge = edge.next;
+ }
+ }
+ b2Fixture.prototype.IsSensor = function () {
+ return this.m_isSensor;
+ }
+ b2Fixture.prototype.SetFilterData = function (filter) {
+ this.m_filter = filter.Copy();
+ if (this.m_body) return;
+ var edge = this.m_body.GetContactList();
+ while (edge) {
+ var contact = edge.contact;
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ if (fixtureA == this || fixtureB == this) contact.FlagForFiltering();
+ edge = edge.next;
+ }
+ }
+ b2Fixture.prototype.GetFilterData = function () {
+ return this.m_filter.Copy();
+ }
+ b2Fixture.prototype.GetBody = function () {
+ return this.m_body;
+ }
+ b2Fixture.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Fixture.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Fixture.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Fixture.prototype.TestPoint = function (p) {
+ return this.m_shape.TestPoint(this.m_body.GetTransform(), p);
+ }
+ b2Fixture.prototype.RayCast = function (output, input) {
+ return this.m_shape.RayCast(output, input, this.m_body.GetTransform());
+ }
+ b2Fixture.prototype.GetMassData = function (massData) {
+ if (massData === undefined) massData = null;
+ if (massData == null) {
+ massData = new b2MassData();
+ }
+ this.m_shape.ComputeMass(massData, this.m_density);
+ return massData;
+ }
+ b2Fixture.prototype.SetDensity = function (density) {
+ if (density === undefined) density = 0;
+ this.m_density = density;
+ }
+ b2Fixture.prototype.GetDensity = function () {
+ return this.m_density;
+ }
+ b2Fixture.prototype.GetFriction = function () {
+ return this.m_friction;
+ }
+ b2Fixture.prototype.SetFriction = function (friction) {
+ if (friction === undefined) friction = 0;
+ this.m_friction = friction;
+ }
+ b2Fixture.prototype.GetRestitution = function () {
+ return this.m_restitution;
+ }
+ b2Fixture.prototype.SetRestitution = function (restitution) {
+ if (restitution === undefined) restitution = 0;
+ this.m_restitution = restitution;
+ }
+ b2Fixture.prototype.GetAABB = function () {
+ return this.m_aabb;
+ }
+ b2Fixture.prototype.b2Fixture = function () {
+ this.m_aabb = new b2AABB();
+ this.m_userData = null;
+ this.m_body = null;
+ this.m_next = null;
+ this.m_shape = null;
+ this.m_density = 0.0;
+ this.m_friction = 0.0;
+ this.m_restitution = 0.0;
+ }
+ b2Fixture.prototype.Create = function (body, xf, def) {
+ this.m_userData = def.userData;
+ this.m_friction = def.friction;
+ this.m_restitution = def.restitution;
+ this.m_body = body;
+ this.m_next = null;
+ this.m_filter = def.filter.Copy();
+ this.m_isSensor = def.isSensor;
+ this.m_shape = def.shape.Copy();
+ this.m_density = def.density;
+ }
+ b2Fixture.prototype.Destroy = function () {
+ this.m_shape = null;
+ }
+ b2Fixture.prototype.CreateProxy = function (broadPhase, xf) {
+ this.m_shape.ComputeAABB(this.m_aabb, xf);
+ this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this);
+ }
+ b2Fixture.prototype.DestroyProxy = function (broadPhase) {
+ if (this.m_proxy == null) {
+ return;
+ }
+ broadPhase.DestroyProxy(this.m_proxy);
+ this.m_proxy = null;
+ }
+ b2Fixture.prototype.Synchronize = function (broadPhase, transform1, transform2) {
+ if (!this.m_proxy) return;
+ var aabb1 = new b2AABB();
+ var aabb2 = new b2AABB();
+ this.m_shape.ComputeAABB(aabb1, transform1);
+ this.m_shape.ComputeAABB(aabb2, transform2);
+ this.m_aabb.Combine(aabb1, aabb2);
+ var displacement = b2Math.SubtractVV(transform2.position, transform1.position);
+ broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement);
+ }
+ b2FixtureDef.b2FixtureDef = function () {
+ this.filter = new b2FilterData();
+ };
+ b2FixtureDef.prototype.b2FixtureDef = function () {
+ this.shape = null;
+ this.userData = null;
+ this.friction = 0.2;
+ this.restitution = 0.0;
+ this.density = 0.0;
+ this.filter.categoryBits = 0x0001;
+ this.filter.maskBits = 0xFFFF;
+ this.filter.groupIndex = 0;
+ this.isSensor = false;
+ }
+ b2Island.b2Island = function () {};
+ b2Island.prototype.b2Island = function () {
+ this.m_bodies = new Vector();
+ this.m_contacts = new Vector();
+ this.m_joints = new Vector();
+ }
+ b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) {
+ if (bodyCapacity === undefined) bodyCapacity = 0;
+ if (contactCapacity === undefined) contactCapacity = 0;
+ if (jointCapacity === undefined) jointCapacity = 0;
+ var i = 0;
+ this.m_bodyCapacity = bodyCapacity;
+ this.m_contactCapacity = contactCapacity;
+ this.m_jointCapacity = jointCapacity;
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ this.m_allocator = allocator;
+ this.m_listener = listener;
+ this.m_contactSolver = contactSolver;
+ for (i = this.m_bodies.length;
+ i < bodyCapacity; i++)
+ this.m_bodies[i] = null;
+ for (i = this.m_contacts.length;
+ i < contactCapacity; i++)
+ this.m_contacts[i] = null;
+ for (i = this.m_joints.length;
+ i < jointCapacity; i++)
+ this.m_joints[i] = null;
+ }
+ b2Island.prototype.Clear = function () {
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ }
+ b2Island.prototype.Solve = function (step, gravity, allowSleep) {
+ var i = 0;
+ var j = 0;
+ var b;
+ var joint;
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() != b2Body.b2_dynamicBody) continue;
+ b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x);
+ b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y);
+ b.m_angularVelocity += step.dt * b.m_invI * b.m_torque;
+ b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0));
+ b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0);
+ }
+ this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator);
+ var contactSolver = this.m_contactSolver;
+ contactSolver.InitVelocityConstraints(step);
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ joint = this.m_joints[i];
+ joint.InitVelocityConstraints(step);
+ }
+ for (i = 0;
+ i < step.velocityIterations; ++i) {
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ joint = this.m_joints[j];
+ joint.SolveVelocityConstraints(step);
+ }
+ contactSolver.SolveVelocityConstraints();
+ }
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ joint = this.m_joints[i];
+ joint.FinalizeVelocityConstraints();
+ }
+ contactSolver.FinalizeVelocityConstraints();
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) continue;
+ var translationX = step.dt * b.m_linearVelocity.x;
+ var translationY = step.dt * b.m_linearVelocity.y;
+ if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) {
+ b.m_linearVelocity.Normalize();
+ b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt;
+ b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt;
+ }
+ var rotation = step.dt * b.m_angularVelocity;
+ if (rotation * rotation > b2Settings.b2_maxRotationSquared) {
+ if (b.m_angularVelocity < 0.0) {
+ b.m_angularVelocity = (-b2Settings.b2_maxRotation * step.inv_dt);
+ }
+ else {
+ b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt;
+ }
+ }
+ b.m_sweep.c0.SetV(b.m_sweep.c);
+ b.m_sweep.a0 = b.m_sweep.a;
+ b.m_sweep.c.x += step.dt * b.m_linearVelocity.x;
+ b.m_sweep.c.y += step.dt * b.m_linearVelocity.y;
+ b.m_sweep.a += step.dt * b.m_angularVelocity;
+ b.SynchronizeTransform();
+ }
+ for (i = 0;
+ i < step.positionIterations; ++i) {
+ var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ var jointsOkay = true;
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ joint = this.m_joints[j];
+ var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ jointsOkay = jointsOkay && jointOkay;
+ }
+ if (contactsOkay && jointsOkay) {
+ break;
+ }
+ }
+ this.Report(contactSolver.m_constraints);
+ if (allowSleep) {
+ var minSleepTime = Number.MAX_VALUE;
+ var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;
+ var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ if ((b.m_flags & b2Body.e_allowSleepFlag) == 0) {
+ b.m_sleepTime = 0.0;
+ minSleepTime = 0.0;
+ }
+ if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) {
+ b.m_sleepTime = 0.0;
+ minSleepTime = 0.0;
+ }
+ else {
+ b.m_sleepTime += step.dt;
+ minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime);
+ }
+ }
+ if (minSleepTime >= b2Settings.b2_timeToSleep) {
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ b.SetAwake(false);
+ }
+ }
+ }
+ }
+ b2Island.prototype.SolveTOI = function (subStep) {
+ var i = 0;
+ var j = 0;
+ this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator);
+ var contactSolver = this.m_contactSolver;
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ this.m_joints[i].InitVelocityConstraints(subStep);
+ }
+ for (i = 0;
+ i < subStep.velocityIterations; ++i) {
+ contactSolver.SolveVelocityConstraints();
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ this.m_joints[j].SolveVelocityConstraints(subStep);
+ }
+ }
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ var b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) continue;
+ var translationX = subStep.dt * b.m_linearVelocity.x;
+ var translationY = subStep.dt * b.m_linearVelocity.y;
+ if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) {
+ b.m_linearVelocity.Normalize();
+ b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt;
+ b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt;
+ }
+ var rotation = subStep.dt * b.m_angularVelocity;
+ if (rotation * rotation > b2Settings.b2_maxRotationSquared) {
+ if (b.m_angularVelocity < 0.0) {
+ b.m_angularVelocity = (-b2Settings.b2_maxRotation * subStep.inv_dt);
+ }
+ else {
+ b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt;
+ }
+ }
+ b.m_sweep.c0.SetV(b.m_sweep.c);
+ b.m_sweep.a0 = b.m_sweep.a;
+ b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x;
+ b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y;
+ b.m_sweep.a += subStep.dt * b.m_angularVelocity;
+ b.SynchronizeTransform();
+ }
+ var k_toiBaumgarte = 0.75;
+ for (i = 0;
+ i < subStep.positionIterations; ++i) {
+ var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte);
+ var jointsOkay = true;
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ jointsOkay = jointsOkay && jointOkay;
+ }
+ if (contactsOkay && jointsOkay) {
+ break;
+ }
+ }
+ this.Report(contactSolver.m_constraints);
+ }
+ b2Island.prototype.Report = function (constraints) {
+ if (this.m_listener == null) {
+ return;
+ }
+ for (var i = 0; i < this.m_contactCount; ++i) {
+ var c = this.m_contacts[i];
+ var cc = constraints[i];
+ for (var j = 0; j < cc.pointCount; ++j) {
+ b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
+ b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
+ }
+ this.m_listener.PostSolve(c, b2Island.s_impulse);
+ }
+ }
+ b2Island.prototype.AddBody = function (body) {
+ body.m_islandIndex = this.m_bodyCount;
+ this.m_bodies[this.m_bodyCount++] = body;
+ }
+ b2Island.prototype.AddContact = function (contact) {
+ this.m_contacts[this.m_contactCount++] = contact;
+ }
+ b2Island.prototype.AddJoint = function (joint) {
+ this.m_joints[this.m_jointCount++] = joint;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2Island.s_impulse = new b2ContactImpulse();
+ });
+ b2TimeStep.b2TimeStep = function () {};
+ b2TimeStep.prototype.Set = function (step) {
+ this.dt = step.dt;
+ this.inv_dt = step.inv_dt;
+ this.positionIterations = step.positionIterations;
+ this.velocityIterations = step.velocityIterations;
+ this.warmStarting = step.warmStarting;
+ }
+ b2World.b2World = function () {
+ this.s_stack = new Vector();
+ this.m_contactManager = new b2ContactManager();
+ this.m_contactSolver = new b2ContactSolver();
+ this.m_island = new b2Island();
+ };
+ b2World.prototype.b2World = function (gravity, doSleep) {
+ this.m_destructionListener = null;
+ this.m_debugDraw = null;
+ this.m_bodyList = null;
+ this.m_contactList = null;
+ this.m_jointList = null;
+ this.m_controllerList = null;
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ this.m_controllerCount = 0;
+ b2World.m_warmStarting = true;
+ b2World.m_continuousPhysics = true;
+ this.m_allowSleep = doSleep;
+ this.m_gravity = gravity;
+ this.m_inv_dt0 = 0.0;
+ this.m_contactManager.m_world = this;
+ var bd = new b2BodyDef();
+ this.m_groundBody = this.CreateBody(bd);
+ }
+ b2World.prototype.SetDestructionListener = function (listener) {
+ this.m_destructionListener = listener;
+ }
+ b2World.prototype.SetContactFilter = function (filter) {
+ this.m_contactManager.m_contactFilter = filter;
+ }
+ b2World.prototype.SetContactListener = function (listener) {
+ this.m_contactManager.m_contactListener = listener;
+ }
+ b2World.prototype.SetDebugDraw = function (debugDraw) {
+ this.m_debugDraw = debugDraw;
+ }
+ b2World.prototype.SetBroadPhase = function (broadPhase) {
+ var oldBroadPhase = this.m_contactManager.m_broadPhase;
+ this.m_contactManager.m_broadPhase = broadPhase;
+ for (var b = this.m_bodyList; b; b = b.m_next) {
+ for (var f = b.m_fixtureList; f; f = f.m_next) {
+ f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f);
+ }
+ }
+ }
+ b2World.prototype.Validate = function () {
+ this.m_contactManager.m_broadPhase.Validate();
+ }
+ b2World.prototype.GetProxyCount = function () {
+ return this.m_contactManager.m_broadPhase.GetProxyCount();
+ }
+ b2World.prototype.CreateBody = function (def) {
+ if (this.IsLocked() == true) {
+ return null;
+ }
+ var b = new b2Body(def, this);
+ b.m_prev = null;
+ b.m_next = this.m_bodyList;
+ if (this.m_bodyList) {
+ this.m_bodyList.m_prev = b;
+ }
+ this.m_bodyList = b;
+ ++this.m_bodyCount;
+ return b;
+ }
+ b2World.prototype.DestroyBody = function (b) {
+ if (this.IsLocked() == true) {
+ return;
+ }
+ var jn = b.m_jointList;
+ while (jn) {
+ var jn0 = jn;
+ jn = jn.next;
+ if (this.m_destructionListener) {
+ this.m_destructionListener.SayGoodbyeJoint(jn0.joint);
+ }
+ this.DestroyJoint(jn0.joint);
+ }
+ var coe = b.m_controllerList;
+ while (coe) {
+ var coe0 = coe;
+ coe = coe.nextController;
+ coe0.controller.RemoveBody(b);
+ }
+ var ce = b.m_contactList;
+ while (ce) {
+ var ce0 = ce;
+ ce = ce.next;
+ this.m_contactManager.Destroy(ce0.contact);
+ }
+ b.m_contactList = null;
+ var f = b.m_fixtureList;
+ while (f) {
+ var f0 = f;
+ f = f.m_next;
+ if (this.m_destructionListener) {
+ this.m_destructionListener.SayGoodbyeFixture(f0);
+ }
+ f0.DestroyProxy(this.m_contactManager.m_broadPhase);
+ f0.Destroy();
+ }
+ b.m_fixtureList = null;
+ b.m_fixtureCount = 0;
+ if (b.m_prev) {
+ b.m_prev.m_next = b.m_next;
+ }
+ if (b.m_next) {
+ b.m_next.m_prev = b.m_prev;
+ }
+ if (b == this.m_bodyList) {
+ this.m_bodyList = b.m_next;
+ }--this.m_bodyCount;
+ }
+ b2World.prototype.CreateJoint = function (def) {
+ var j = b2Joint.Create(def, null);
+ j.m_prev = null;
+ j.m_next = this.m_jointList;
+ if (this.m_jointList) {
+ this.m_jointList.m_prev = j;
+ }
+ this.m_jointList = j;
+ ++this.m_jointCount;
+ j.m_edgeA.joint = j;
+ j.m_edgeA.other = j.m_bodyB;
+ j.m_edgeA.prev = null;
+ j.m_edgeA.next = j.m_bodyA.m_jointList;
+ if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = j.m_edgeA;
+ j.m_bodyA.m_jointList = j.m_edgeA;
+ j.m_edgeB.joint = j;
+ j.m_edgeB.other = j.m_bodyA;
+ j.m_edgeB.prev = null;
+ j.m_edgeB.next = j.m_bodyB.m_jointList;
+ if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = j.m_edgeB;
+ j.m_bodyB.m_jointList = j.m_edgeB;
+ var bodyA = def.bodyA;
+ var bodyB = def.bodyB;
+ if (def.collideConnected == false) {
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ edge.contact.FlagForFiltering();
+ }
+ edge = edge.next;
+ }
+ }
+ return j;
+ }
+ b2World.prototype.DestroyJoint = function (j) {
+ var collideConnected = j.m_collideConnected;
+ if (j.m_prev) {
+ j.m_prev.m_next = j.m_next;
+ }
+ if (j.m_next) {
+ j.m_next.m_prev = j.m_prev;
+ }
+ if (j == this.m_jointList) {
+ this.m_jointList = j.m_next;
+ }
+ var bodyA = j.m_bodyA;
+ var bodyB = j.m_bodyB;
+ bodyA.SetAwake(true);
+ bodyB.SetAwake(true);
+ if (j.m_edgeA.prev) {
+ j.m_edgeA.prev.next = j.m_edgeA.next;
+ }
+ if (j.m_edgeA.next) {
+ j.m_edgeA.next.prev = j.m_edgeA.prev;
+ }
+ if (j.m_edgeA == bodyA.m_jointList) {
+ bodyA.m_jointList = j.m_edgeA.next;
+ }
+ j.m_edgeA.prev = null;
+ j.m_edgeA.next = null;
+ if (j.m_edgeB.prev) {
+ j.m_edgeB.prev.next = j.m_edgeB.next;
+ }
+ if (j.m_edgeB.next) {
+ j.m_edgeB.next.prev = j.m_edgeB.prev;
+ }
+ if (j.m_edgeB == bodyB.m_jointList) {
+ bodyB.m_jointList = j.m_edgeB.next;
+ }
+ j.m_edgeB.prev = null;
+ j.m_edgeB.next = null;
+ b2Joint.Destroy(j, null);
+ --this.m_jointCount;
+ if (collideConnected == false) {
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ edge.contact.FlagForFiltering();
+ }
+ edge = edge.next;
+ }
+ }
+ }
+ b2World.prototype.AddController = function (c) {
+ c.m_next = this.m_controllerList;
+ c.m_prev = null;
+ this.m_controllerList = c;
+ c.m_world = this;
+ this.m_controllerCount++;
+ return c;
+ }
+ b2World.prototype.RemoveController = function (c) {
+ if (c.m_prev) c.m_prev.m_next = c.m_next;
+ if (c.m_next) c.m_next.m_prev = c.m_prev;
+ if (this.m_controllerList == c) this.m_controllerList = c.m_next;
+ this.m_controllerCount--;
+ }
+ b2World.prototype.CreateController = function (controller) {
+ if (controller.m_world != this) throw new Error("Controller can only be a member of one world");
+ controller.m_next = this.m_controllerList;
+ controller.m_prev = null;
+ if (this.m_controllerList) this.m_controllerList.m_prev = controller;
+ this.m_controllerList = controller;
+ ++this.m_controllerCount;
+ controller.m_world = this;
+ return controller;
+ }
+ b2World.prototype.DestroyController = function (controller) {
+ controller.Clear();
+ if (controller.m_next) controller.m_next.m_prev = controller.m_prev;
+ if (controller.m_prev) controller.m_prev.m_next = controller.m_next;
+ if (controller == this.m_controllerList) this.m_controllerList = controller.m_next;
+ --this.m_controllerCount;
+ }
+ b2World.prototype.SetWarmStarting = function (flag) {
+ b2World.m_warmStarting = flag;
+ }
+ b2World.prototype.SetContinuousPhysics = function (flag) {
+ b2World.m_continuousPhysics = flag;
+ }
+ b2World.prototype.GetBodyCount = function () {
+ return this.m_bodyCount;
+ }
+ b2World.prototype.GetJointCount = function () {
+ return this.m_jointCount;
+ }
+ b2World.prototype.GetContactCount = function () {
+ return this.m_contactCount;
+ }
+ b2World.prototype.SetGravity = function (gravity) {
+ this.m_gravity = gravity;
+ }
+ b2World.prototype.GetGravity = function () {
+ return this.m_gravity;
+ }
+ b2World.prototype.GetGroundBody = function () {
+ return this.m_groundBody;
+ }
+ b2World.prototype.Step = function (dt, velocityIterations, positionIterations) {
+ if (dt === undefined) dt = 0;
+ if (velocityIterations === undefined) velocityIterations = 0;
+ if (positionIterations === undefined) positionIterations = 0;
+ if (this.m_flags & b2World.e_newFixture) {
+ this.m_contactManager.FindNewContacts();
+ this.m_flags &= ~b2World.e_newFixture;
+ }
+ this.m_flags |= b2World.e_locked;
+ var step = b2World.s_timestep2;
+ step.dt = dt;
+ step.velocityIterations = velocityIterations;
+ step.positionIterations = positionIterations;
+ if (dt > 0.0) {
+ step.inv_dt = 1.0 / dt;
+ }
+ else {
+ step.inv_dt = 0.0;
+ }
+ step.dtRatio = this.m_inv_dt0 * dt;
+ step.warmStarting = b2World.m_warmStarting;
+ this.m_contactManager.Collide();
+ if (step.dt > 0.0) {
+ this.Solve(step);
+ }
+ if (b2World.m_continuousPhysics && step.dt > 0.0) {
+ this.SolveTOI(step);
+ }
+ if (step.dt > 0.0) {
+ this.m_inv_dt0 = step.inv_dt;
+ }
+ this.m_flags &= ~b2World.e_locked;
+ }
+ b2World.prototype.ClearForces = function () {
+ for (var body = this.m_bodyList; body; body = body.m_next) {
+ body.m_force.SetZero();
+ body.m_torque = 0.0;
+ }
+ }
+ b2World.prototype.DrawDebugData = function () {
+ if (this.m_debugDraw == null) {
+ return;
+ }
+ this.m_debugDraw.m_sprite.graphics.clear();
+ var flags = this.m_debugDraw.GetFlags();
+ var i = 0;
+ var b;
+ var f;
+ var s;
+ var j;
+ var bp;
+ var invQ = new b2Vec2;
+ var x1 = new b2Vec2;
+ var x2 = new b2Vec2;
+ var xf;
+ var b1 = new b2AABB();
+ var b2 = new b2AABB();
+ var vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()];
+ var color = new b2Color(0, 0, 0);
+ if (flags & b2DebugDraw.e_shapeBit) {
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ xf = b.m_xf;
+ for (f = b.GetFixtureList();
+ f; f = f.m_next) {
+ s = f.GetShape();
+ if (b.IsActive() == false) {
+ color.Set(0.5, 0.5, 0.3);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.GetType() == b2Body.b2_staticBody) {
+ color.Set(0.5, 0.9, 0.5);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.GetType() == b2Body.b2_kinematicBody) {
+ color.Set(0.5, 0.5, 0.9);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.IsAwake() == false) {
+ color.Set(0.6, 0.6, 0.6);
+ this.DrawShape(s, xf, color);
+ }
+ else {
+ color.Set(0.9, 0.7, 0.7);
+ this.DrawShape(s, xf, color);
+ }
+ }
+ }
+ }
+ if (flags & b2DebugDraw.e_jointBit) {
+ for (j = this.m_jointList;
+ j; j = j.m_next) {
+ this.DrawJoint(j);
+ }
+ }
+ if (flags & b2DebugDraw.e_controllerBit) {
+ for (var c = this.m_controllerList; c; c = c.m_next) {
+ c.Draw(this.m_debugDraw);
+ }
+ }
+ if (flags & b2DebugDraw.e_pairBit) {
+ color.Set(0.3, 0.9, 0.9);
+ for (var contact = this.m_contactManager.m_contactList; contact; contact = contact.GetNext()) {
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ var cA = fixtureA.GetAABB().GetCenter();
+ var cB = fixtureB.GetAABB().GetCenter();
+ this.m_debugDraw.DrawSegment(cA, cB, color);
+ }
+ }
+ if (flags & b2DebugDraw.e_aabbBit) {
+ bp = this.m_contactManager.m_broadPhase;
+ vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()];
+ for (b = this.m_bodyList;
+ b; b = b.GetNext()) {
+ if (b.IsActive() == false) {
+ continue;
+ }
+ for (f = b.GetFixtureList();
+ f; f = f.GetNext()) {
+ var aabb = bp.GetFatAABB(f.m_proxy);
+ vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
+ vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
+ vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
+ vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
+ this.m_debugDraw.DrawPolygon(vs, 4, color);
+ }
+ }
+ }
+ if (flags & b2DebugDraw.e_centerOfMassBit) {
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ xf = b2World.s_xf;
+ xf.R = b.m_xf.R;
+ xf.position = b.GetWorldCenter();
+ this.m_debugDraw.DrawTransform(xf);
+ }
+ }
+ }
+ b2World.prototype.QueryAABB = function (callback, aabb) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ return callback(broadPhase.GetUserData(proxy));
+ };
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.QueryShape = function (callback, shape, transform) {
+ var __this = this;
+ if (transform === undefined) transform = null;
+ if (transform == null) {
+ transform = new b2Transform();
+ transform.SetIdentity();
+ }
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null);
+ if (b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) return callback(fixture);
+ return true;
+ };
+ var aabb = new b2AABB();
+ shape.ComputeAABB(aabb, transform);
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.QueryPoint = function (callback, p) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null);
+ if (fixture.TestPoint(p)) return callback(fixture);
+ return true;
+ };
+ var aabb = new b2AABB();
+ aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop);
+ aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop);
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.RayCast = function (callback, point1, point2) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+ var output = new b2RayCastOutput;
+
+ function RayCastWrapper(input, proxy) {
+ var userData = broadPhase.GetUserData(proxy);
+ var fixture = (userData instanceof b2Fixture ? userData : null);
+ var hit = fixture.RayCast(output, input);
+ if (hit) {
+ var fraction = output.fraction;
+ var point = new b2Vec2((1.0 - fraction) * point1.x + fraction * point2.x, (1.0 - fraction) * point1.y + fraction * point2.y);
+ return callback(fixture, point, output.normal, fraction);
+ }
+ return input.maxFraction;
+ };
+ var input = new b2RayCastInput(point1, point2);
+ broadPhase.RayCast(RayCastWrapper, input);
+ }
+ b2World.prototype.RayCastOne = function (point1, point2) {
+ var __this = this;
+ var result;
+
+ function RayCastOneWrapper(fixture, point, normal, fraction) {
+ if (fraction === undefined) fraction = 0;
+ result = fixture;
+ return fraction;
+ };
+ __this.RayCast(RayCastOneWrapper, point1, point2);
+ return result;
+ }
+ b2World.prototype.RayCastAll = function (point1, point2) {
+ var __this = this;
+ var result = new Vector();
+
+ function RayCastAllWrapper(fixture, point, normal, fraction) {
+ if (fraction === undefined) fraction = 0;
+ result[result.length] = fixture;
+ return 1;
+ };
+ __this.RayCast(RayCastAllWrapper, point1, point2);
+ return result;
+ }
+ b2World.prototype.GetBodyList = function () {
+ return this.m_bodyList;
+ }
+ b2World.prototype.GetJointList = function () {
+ return this.m_jointList;
+ }
+ b2World.prototype.GetContactList = function () {
+ return this.m_contactList;
+ }
+ b2World.prototype.IsLocked = function () {
+ return (this.m_flags & b2World.e_locked) > 0;
+ }
+ b2World.prototype.Solve = function (step) {
+ var b;
+ for (var controller = this.m_controllerList; controller; controller = controller.m_next) {
+ controller.Step(step);
+ }
+ var island = this.m_island;
+ island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver);
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ }
+ for (var c = this.m_contactList; c; c = c.m_next) {
+ c.m_flags &= ~b2Contact.e_islandFlag;
+ }
+ for (var j = this.m_jointList; j; j = j.m_next) {
+ j.m_islandFlag = false;
+ }
+ var stackSize = parseInt(this.m_bodyCount);
+ var stack = this.s_stack;
+ for (var seed = this.m_bodyList; seed; seed = seed.m_next) {
+ if (seed.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ if (seed.IsAwake() == false || seed.IsActive() == false) {
+ continue;
+ }
+ if (seed.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ island.Clear();
+ var stackCount = 0;
+ stack[stackCount++] = seed;
+ seed.m_flags |= b2Body.e_islandFlag;
+ while (stackCount > 0) {
+ b = stack[--stackCount];
+ island.AddBody(b);
+ if (b.IsAwake() == false) {
+ b.SetAwake(true);
+ }
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ var other;
+ for (var ce = b.m_contactList; ce; ce = ce.next) {
+ if (ce.contact.m_flags & b2Contact.e_islandFlag) {
+ continue;
+ }
+ if (ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) {
+ continue;
+ }
+ island.AddContact(ce.contact);
+ ce.contact.m_flags |= b2Contact.e_islandFlag;
+ other = ce.other;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ stack[stackCount++] = other;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ for (var jn = b.m_jointList; jn; jn = jn.next) {
+ if (jn.joint.m_islandFlag == true) {
+ continue;
+ }
+ other = jn.other;
+ if (other.IsActive() == false) {
+ continue;
+ }
+ island.AddJoint(jn.joint);
+ jn.joint.m_islandFlag = true;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ stack[stackCount++] = other;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ }
+ island.Solve(step, this.m_gravity, this.m_allowSleep);
+ for (var i = 0; i < island.m_bodyCount; ++i) {
+ b = island.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ }
+ }
+ }
+ for (i = 0;
+ i < stack.length; ++i) {
+ if (!stack[i]) break;
+ stack[i] = null;
+ }
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ if (b.IsAwake() == false || b.IsActive() == false) {
+ continue;
+ }
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ b.SynchronizeFixtures();
+ }
+ this.m_contactManager.FindNewContacts();
+ }
+ b2World.prototype.SolveTOI = function (step) {
+ var b;
+ var fA;
+ var fB;
+ var bA;
+ var bB;
+ var cEdge;
+ var j;
+ var island = this.m_island;
+ island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver);
+ var queue = b2World.s_queue;
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ b.m_sweep.t0 = 0.0;
+ }
+ var c;
+ for (c = this.m_contactList;
+ c; c = c.m_next) {
+ c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag);
+ }
+ for (j = this.m_jointList;
+ j; j = j.m_next) {
+ j.m_islandFlag = false;
+ }
+ for (;;) {
+ var minContact = null;
+ var minTOI = 1.0;
+ for (c = this.m_contactList;
+ c; c = c.m_next) {
+ if (c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) {
+ continue;
+ }
+ var toi = 1.0;
+ if (c.m_flags & b2Contact.e_toiFlag) {
+ toi = c.m_toi;
+ }
+ else {
+ fA = c.m_fixtureA;
+ fB = c.m_fixtureB;
+ bA = fA.m_body;
+ bB = fB.m_body;
+ if ((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) {
+ continue;
+ }
+ var t0 = bA.m_sweep.t0;
+ if (bA.m_sweep.t0 < bB.m_sweep.t0) {
+ t0 = bB.m_sweep.t0;
+ bA.m_sweep.Advance(t0);
+ }
+ else if (bB.m_sweep.t0 < bA.m_sweep.t0) {
+ t0 = bA.m_sweep.t0;
+ bB.m_sweep.Advance(t0);
+ }
+ toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep);
+ b2Settings.b2Assert(0.0 <= toi && toi <= 1.0);
+ if (toi > 0.0 && toi < 1.0) {
+ toi = (1.0 - toi) * t0 + toi;
+ if (toi > 1) toi = 1;
+ }
+ c.m_toi = toi;
+ c.m_flags |= b2Contact.e_toiFlag;
+ }
+ if (Number.MIN_VALUE < toi && toi < minTOI) {
+ minContact = c;
+ minTOI = toi;
+ }
+ }
+ if (minContact == null || 1.0 - 100.0 * Number.MIN_VALUE < minTOI) {
+ break;
+ }
+ fA = minContact.m_fixtureA;
+ fB = minContact.m_fixtureB;
+ bA = fA.m_body;
+ bB = fB.m_body;
+ b2World.s_backupA.Set(bA.m_sweep);
+ b2World.s_backupB.Set(bB.m_sweep);
+ bA.Advance(minTOI);
+ bB.Advance(minTOI);
+ minContact.Update(this.m_contactManager.m_contactListener);
+ minContact.m_flags &= ~b2Contact.e_toiFlag;
+ if (minContact.IsSensor() == true || minContact.IsEnabled() == false) {
+ bA.m_sweep.Set(b2World.s_backupA);
+ bB.m_sweep.Set(b2World.s_backupB);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ continue;
+ }
+ if (minContact.IsTouching() == false) {
+ continue;
+ }
+ var seed = bA;
+ if (seed.GetType() != b2Body.b2_dynamicBody) {
+ seed = bB;
+ }
+ island.Clear();
+ var queueStart = 0;
+ var queueSize = 0;
+ queue[queueStart + queueSize++] = seed;
+ seed.m_flags |= b2Body.e_islandFlag;
+ while (queueSize > 0) {
+ b = queue[queueStart++];
+ --queueSize;
+ island.AddBody(b);
+ if (b.IsAwake() == false) {
+ b.SetAwake(true);
+ }
+ if (b.GetType() != b2Body.b2_dynamicBody) {
+ continue;
+ }
+ for (cEdge = b.m_contactList;
+ cEdge; cEdge = cEdge.next) {
+ if (island.m_contactCount == island.m_contactCapacity) {
+ break;
+ }
+ if (cEdge.contact.m_flags & b2Contact.e_islandFlag) {
+ continue;
+ }
+ if (cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) {
+ continue;
+ }
+ island.AddContact(cEdge.contact);
+ cEdge.contact.m_flags |= b2Contact.e_islandFlag;
+ var other = cEdge.other;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ if (other.GetType() != b2Body.b2_staticBody) {
+ other.Advance(minTOI);
+ other.SetAwake(true);
+ }
+ queue[queueStart + queueSize] = other;
+ ++queueSize;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ for (var jEdge = b.m_jointList; jEdge; jEdge = jEdge.next) {
+ if (island.m_jointCount == island.m_jointCapacity) continue;
+ if (jEdge.joint.m_islandFlag == true) continue;
+ other = jEdge.other;
+ if (other.IsActive() == false) {
+ continue;
+ }
+ island.AddJoint(jEdge.joint);
+ jEdge.joint.m_islandFlag = true;
+ if (other.m_flags & b2Body.e_islandFlag) continue;
+ if (other.GetType() != b2Body.b2_staticBody) {
+ other.Advance(minTOI);
+ other.SetAwake(true);
+ }
+ queue[queueStart + queueSize] = other;
+ ++queueSize;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ }
+ var subStep = b2World.s_timestep;
+ subStep.warmStarting = false;
+ subStep.dt = (1.0 - minTOI) * step.dt;
+ subStep.inv_dt = 1.0 / subStep.dt;
+ subStep.dtRatio = 0.0;
+ subStep.velocityIterations = step.velocityIterations;
+ subStep.positionIterations = step.positionIterations;
+ island.SolveTOI(subStep);
+ var i = 0;
+ for (i = 0;
+ i < island.m_bodyCount; ++i) {
+ b = island.m_bodies[i];
+ b.m_flags &= ~b2Body.e_islandFlag;
+ if (b.IsAwake() == false) {
+ continue;
+ }
+ if (b.GetType() != b2Body.b2_dynamicBody) {
+ continue;
+ }
+ b.SynchronizeFixtures();
+ for (cEdge = b.m_contactList;
+ cEdge; cEdge = cEdge.next) {
+ cEdge.contact.m_flags &= ~b2Contact.e_toiFlag;
+ }
+ }
+ for (i = 0;
+ i < island.m_contactCount; ++i) {
+ c = island.m_contacts[i];
+ c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag);
+ }
+ for (i = 0;
+ i < island.m_jointCount; ++i) {
+ j = island.m_joints[i];
+ j.m_islandFlag = false;
+ }
+ this.m_contactManager.FindNewContacts();
+ }
+ }
+ b2World.prototype.DrawJoint = function (joint) {
+ var b1 = joint.GetBodyA();
+ var b2 = joint.GetBodyB();
+ var xf1 = b1.m_xf;
+ var xf2 = b2.m_xf;
+ var x1 = xf1.position;
+ var x2 = xf2.position;
+ var p1 = joint.GetAnchorA();
+ var p2 = joint.GetAnchorB();
+ var color = b2World.s_jointColor;
+ switch (joint.m_type) {
+ case b2Joint.e_distanceJoint:
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ break;
+ case b2Joint.e_pulleyJoint:
+ {
+ var pulley = ((joint instanceof b2PulleyJoint ? joint : null));
+ var s1 = pulley.GetGroundAnchorA();
+ var s2 = pulley.GetGroundAnchorB();
+ this.m_debugDraw.DrawSegment(s1, p1, color);
+ this.m_debugDraw.DrawSegment(s2, p2, color);
+ this.m_debugDraw.DrawSegment(s1, s2, color);
+ }
+ break;
+ case b2Joint.e_mouseJoint:
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ break;
+ default:
+ if (b1 != this.m_groundBody) this.m_debugDraw.DrawSegment(x1, p1, color);
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ if (b2 != this.m_groundBody) this.m_debugDraw.DrawSegment(x2, p2, color);
+ }
+ }
+ b2World.prototype.DrawShape = function (shape, xf, color) {
+ switch (shape.m_type) {
+ case b2Shape.e_circleShape:
+ {
+ var circle = ((shape instanceof b2CircleShape ? shape : null));
+ var center = b2Math.MulX(xf, circle.m_p);
+ var radius = circle.m_radius;
+ var axis = xf.R.col1;
+ this.m_debugDraw.DrawSolidCircle(center, radius, axis, color);
+ }
+ break;
+ case b2Shape.e_polygonShape:
+ {
+ var i = 0;
+ var poly = ((shape instanceof b2PolygonShape ? shape : null));
+ var vertexCount = parseInt(poly.GetVertexCount());
+ var localVertices = poly.GetVertices();
+ var vertices = new Vector(vertexCount);
+ for (i = 0;
+ i < vertexCount; ++i) {
+ vertices[i] = b2Math.MulX(xf, localVertices[i]);
+ }
+ this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color);
+ }
+ break;
+ case b2Shape.e_edgeShape:
+ {
+ var edge = (shape instanceof b2EdgeShape ? shape : null);
+ this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color);
+ }
+ break;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2World.s_timestep2 = new b2TimeStep();
+ Box2D.Dynamics.b2World.s_xf = new b2Transform();
+ Box2D.Dynamics.b2World.s_backupA = new b2Sweep();
+ Box2D.Dynamics.b2World.s_backupB = new b2Sweep();
+ Box2D.Dynamics.b2World.s_timestep = new b2TimeStep();
+ Box2D.Dynamics.b2World.s_queue = new Vector();
+ Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8);
+ Box2D.Dynamics.b2World.e_newFixture = 0x0001;
+ Box2D.Dynamics.b2World.e_locked = 0x0002;
+ });
+})();
+(function () {
+ var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact,
+ b2Contact = Box2D.Dynamics.Contacts.b2Contact,
+ b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint,
+ b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint,
+ b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge,
+ b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory,
+ b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister,
+ b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult,
+ b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver,
+ b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,
+ b2NullContact = Box2D.Dynamics.Contacts.b2NullContact,
+ b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact,
+ b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,
+ b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact,
+ b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ Box2D.inherit(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2CircleContact.b2CircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2CircleContact.Create = function (allocator) {
+ return new b2CircleContact();
+ }
+ b2CircleContact.Destroy = function (contact, allocator) {}
+ b2CircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2CircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ b2Collision.CollideCircles(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2CircleShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2Contact.b2Contact = function () {
+ this.m_nodeA = new b2ContactEdge();
+ this.m_nodeB = new b2ContactEdge();
+ this.m_manifold = new b2Manifold();
+ this.m_oldManifold = new b2Manifold();
+ };
+ b2Contact.prototype.GetManifold = function () {
+ return this.m_manifold;
+ }
+ b2Contact.prototype.GetWorldManifold = function (worldManifold) {
+ var bodyA = this.m_fixtureA.GetBody();
+ var bodyB = this.m_fixtureB.GetBody();
+ var shapeA = this.m_fixtureA.GetShape();
+ var shapeB = this.m_fixtureB.GetShape();
+ worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius);
+ }
+ b2Contact.prototype.IsTouching = function () {
+ return (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag;
+ }
+ b2Contact.prototype.IsContinuous = function () {
+ return (this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag;
+ }
+ b2Contact.prototype.SetSensor = function (sensor) {
+ if (sensor) {
+ this.m_flags |= b2Contact.e_sensorFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_sensorFlag;
+ }
+ }
+ b2Contact.prototype.IsSensor = function () {
+ return (this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag;
+ }
+ b2Contact.prototype.SetEnabled = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Contact.e_enabledFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_enabledFlag;
+ }
+ }
+ b2Contact.prototype.IsEnabled = function () {
+ return (this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag;
+ }
+ b2Contact.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Contact.prototype.GetFixtureA = function () {
+ return this.m_fixtureA;
+ }
+ b2Contact.prototype.GetFixtureB = function () {
+ return this.m_fixtureB;
+ }
+ b2Contact.prototype.FlagForFiltering = function () {
+ this.m_flags |= b2Contact.e_filterFlag;
+ }
+ b2Contact.prototype.b2Contact = function () {}
+ b2Contact.prototype.Reset = function (fixtureA, fixtureB) {
+ if (fixtureA === undefined) fixtureA = null;
+ if (fixtureB === undefined) fixtureB = null;
+ this.m_flags = b2Contact.e_enabledFlag;
+ if (!fixtureA || !fixtureB) {
+ this.m_fixtureA = null;
+ this.m_fixtureB = null;
+ return;
+ }
+ if (fixtureA.IsSensor() || fixtureB.IsSensor()) {
+ this.m_flags |= b2Contact.e_sensorFlag;
+ }
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) {
+ this.m_flags |= b2Contact.e_continuousFlag;
+ }
+ this.m_fixtureA = fixtureA;
+ this.m_fixtureB = fixtureB;
+ this.m_manifold.m_pointCount = 0;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_nodeA.contact = null;
+ this.m_nodeA.prev = null;
+ this.m_nodeA.next = null;
+ this.m_nodeA.other = null;
+ this.m_nodeB.contact = null;
+ this.m_nodeB.prev = null;
+ this.m_nodeB.next = null;
+ this.m_nodeB.other = null;
+ }
+ b2Contact.prototype.Update = function (listener) {
+ var tManifold = this.m_oldManifold;
+ this.m_oldManifold = this.m_manifold;
+ this.m_manifold = tManifold;
+ this.m_flags |= b2Contact.e_enabledFlag;
+ var touching = false;
+ var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag;
+ var bodyA = this.m_fixtureA.m_body;
+ var bodyB = this.m_fixtureB.m_body;
+ var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb);
+ if (this.m_flags & b2Contact.e_sensorFlag) {
+ if (aabbOverlap) {
+ var shapeA = this.m_fixtureA.GetShape();
+ var shapeB = this.m_fixtureB.GetShape();
+ var xfA = bodyA.GetTransform();
+ var xfB = bodyB.GetTransform();
+ touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB);
+ }
+ this.m_manifold.m_pointCount = 0;
+ }
+ else {
+ if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) {
+ this.m_flags |= b2Contact.e_continuousFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_continuousFlag;
+ }
+ if (aabbOverlap) {
+ this.Evaluate();
+ touching = this.m_manifold.m_pointCount > 0;
+ for (var i = 0; i < this.m_manifold.m_pointCount; ++i) {
+ var mp2 = this.m_manifold.m_points[i];
+ mp2.m_normalImpulse = 0.0;
+ mp2.m_tangentImpulse = 0.0;
+ var id2 = mp2.m_id;
+ for (var j = 0; j < this.m_oldManifold.m_pointCount; ++j) {
+ var mp1 = this.m_oldManifold.m_points[j];
+ if (mp1.m_id.key == id2.key) {
+ mp2.m_normalImpulse = mp1.m_normalImpulse;
+ mp2.m_tangentImpulse = mp1.m_tangentImpulse;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ this.m_manifold.m_pointCount = 0;
+ }
+ if (touching != wasTouching) {
+ bodyA.SetAwake(true);
+ bodyB.SetAwake(true);
+ }
+ }
+ if (touching) {
+ this.m_flags |= b2Contact.e_touchingFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_touchingFlag;
+ }
+ if (wasTouching == false && touching == true) {
+ listener.BeginContact(this);
+ }
+ if (wasTouching == true && touching == false) {
+ listener.EndContact(this);
+ }
+ if ((this.m_flags & b2Contact.e_sensorFlag) == 0) {
+ listener.PreSolve(this, this.m_oldManifold);
+ }
+ }
+ b2Contact.prototype.Evaluate = function () {}
+ b2Contact.prototype.ComputeTOI = function (sweepA, sweepB) {
+ b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape());
+ b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape());
+ b2Contact.s_input.sweepA = sweepA;
+ b2Contact.s_input.sweepB = sweepB;
+ b2Contact.s_input.tolerance = b2Settings.b2_linearSlop;
+ return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag = 0x0001;
+ Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag = 0x0002;
+ Box2D.Dynamics.Contacts.b2Contact.e_islandFlag = 0x0004;
+ Box2D.Dynamics.Contacts.b2Contact.e_toiFlag = 0x0008;
+ Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag = 0x0010;
+ Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag = 0x0020;
+ Box2D.Dynamics.Contacts.b2Contact.e_filterFlag = 0x0040;
+ Box2D.Dynamics.Contacts.b2Contact.s_input = new b2TOIInput();
+ });
+ b2ContactConstraint.b2ContactConstraint = function () {
+ this.localPlaneNormal = new b2Vec2();
+ this.localPoint = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.normalMass = new b2Mat22();
+ this.K = new b2Mat22();
+ };
+ b2ContactConstraint.prototype.b2ContactConstraint = function () {
+ this.points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.points[i] = new b2ContactConstraintPoint();
+ }
+ }
+ b2ContactConstraintPoint.b2ContactConstraintPoint = function () {
+ this.localPoint = new b2Vec2();
+ this.rA = new b2Vec2();
+ this.rB = new b2Vec2();
+ };
+ b2ContactEdge.b2ContactEdge = function () {};
+ b2ContactFactory.b2ContactFactory = function () {};
+ b2ContactFactory.prototype.b2ContactFactory = function (allocator) {
+ this.m_allocator = allocator;
+ this.InitializeRegisters();
+ }
+ b2ContactFactory.prototype.AddType = function (createFcn, destroyFcn, type1, type2) {
+ if (type1 === undefined) type1 = 0;
+ if (type2 === undefined) type2 = 0;
+ this.m_registers[type1][type2].createFcn = createFcn;
+ this.m_registers[type1][type2].destroyFcn = destroyFcn;
+ this.m_registers[type1][type2].primary = true;
+ if (type1 != type2) {
+ this.m_registers[type2][type1].createFcn = createFcn;
+ this.m_registers[type2][type1].destroyFcn = destroyFcn;
+ this.m_registers[type2][type1].primary = false;
+ }
+ }
+ b2ContactFactory.prototype.InitializeRegisters = function () {
+ this.m_registers = new Vector(b2Shape.e_shapeTypeCount);
+ for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) {
+ this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount);
+ for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) {
+ this.m_registers[i][j] = new b2ContactRegister();
+ }
+ }
+ this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape);
+ this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape);
+ this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape);
+ this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape);
+ this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape);
+ }
+ b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) {
+ var type1 = parseInt(fixtureA.GetType());
+ var type2 = parseInt(fixtureB.GetType());
+ var reg = this.m_registers[type1][type2];
+ var c;
+ if (reg.pool) {
+ c = reg.pool;
+ reg.pool = c.m_next;
+ reg.poolCount--;
+ c.Reset(fixtureA, fixtureB);
+ return c;
+ }
+ var createFcn = reg.createFcn;
+ if (createFcn != null) {
+ if (reg.primary) {
+ c = createFcn(this.m_allocator);
+ c.Reset(fixtureA, fixtureB);
+ return c;
+ }
+ else {
+ c = createFcn(this.m_allocator);
+ c.Reset(fixtureB, fixtureA);
+ return c;
+ }
+ }
+ else {
+ return null;
+ }
+ }
+ b2ContactFactory.prototype.Destroy = function (contact) {
+ if (contact.m_manifold.m_pointCount > 0) {
+ contact.m_fixtureA.m_body.SetAwake(true);
+ contact.m_fixtureB.m_body.SetAwake(true);
+ }
+ var type1 = parseInt(contact.m_fixtureA.GetType());
+ var type2 = parseInt(contact.m_fixtureB.GetType());
+ var reg = this.m_registers[type1][type2];
+ if (true) {
+ reg.poolCount++;
+ contact.m_next = reg.pool;
+ reg.pool = contact;
+ }
+ var destroyFcn = reg.destroyFcn;
+ destroyFcn(contact, this.m_allocator);
+ }
+ b2ContactRegister.b2ContactRegister = function () {};
+ b2ContactResult.b2ContactResult = function () {
+ this.position = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ b2ContactSolver.b2ContactSolver = function () {
+ this.m_step = new b2TimeStep();
+ this.m_constraints = new Vector();
+ };
+ b2ContactSolver.prototype.b2ContactSolver = function () {}
+ b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) {
+ if (contactCount === undefined) contactCount = 0;
+ var contact;
+ this.m_step.Set(step);
+ this.m_allocator = allocator;
+ var i = 0;
+ var tVec;
+ var tMat;
+ this.m_constraintCount = contactCount;
+ while (this.m_constraints.length < this.m_constraintCount) {
+ this.m_constraints[this.m_constraints.length] = new b2ContactConstraint();
+ }
+ for (i = 0;
+ i < contactCount; ++i) {
+ contact = contacts[i];
+ var fixtureA = contact.m_fixtureA;
+ var fixtureB = contact.m_fixtureB;
+ var shapeA = fixtureA.m_shape;
+ var shapeB = fixtureB.m_shape;
+ var radiusA = shapeA.m_radius;
+ var radiusB = shapeB.m_radius;
+ var bodyA = fixtureA.m_body;
+ var bodyB = fixtureB.m_body;
+ var manifold = contact.GetManifold();
+ var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction());
+ var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution());
+ var vAX = bodyA.m_linearVelocity.x;
+ var vAY = bodyA.m_linearVelocity.y;
+ var vBX = bodyB.m_linearVelocity.x;
+ var vBY = bodyB.m_linearVelocity.y;
+ var wA = bodyA.m_angularVelocity;
+ var wB = bodyB.m_angularVelocity;
+ b2Settings.b2Assert(manifold.m_pointCount > 0);
+ b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB);
+ var normalX = b2ContactSolver.s_worldManifold.m_normal.x;
+ var normalY = b2ContactSolver.s_worldManifold.m_normal.y;
+ var cc = this.m_constraints[i];
+ cc.bodyA = bodyA;
+ cc.bodyB = bodyB;
+ cc.manifold = manifold;
+ cc.normal.x = normalX;
+ cc.normal.y = normalY;
+ cc.pointCount = manifold.m_pointCount;
+ cc.friction = friction;
+ cc.restitution = restitution;
+ cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x;
+ cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y;
+ cc.localPoint.x = manifold.m_localPoint.x;
+ cc.localPoint.y = manifold.m_localPoint.y;
+ cc.radius = radiusA + radiusB;
+ cc.type = manifold.m_type;
+ for (var k = 0; k < cc.pointCount; ++k) {
+ var cp = manifold.m_points[k];
+ var ccp = cc.points[k];
+ ccp.normalImpulse = cp.m_normalImpulse;
+ ccp.tangentImpulse = cp.m_tangentImpulse;
+ ccp.localPoint.SetV(cp.m_localPoint);
+ var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x;
+ var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y;
+ var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x;
+ var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y;
+ var rnA = rAX * normalY - rAY * normalX;
+ var rnB = rBX * normalY - rBY * normalX;
+ rnA *= rnA;
+ rnB *= rnB;
+ var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB;
+ ccp.normalMass = 1.0 / kNormal;
+ var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass;
+ kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB;
+ ccp.equalizedMass = 1.0 / kEqualized;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var rtA = rAX * tangentY - rAY * tangentX;
+ var rtB = rBX * tangentY - rBY * tangentX;
+ rtA *= rtA;
+ rtB *= rtB;
+ var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB;
+ ccp.tangentMass = 1.0 / kTangent;
+ ccp.velocityBias = 0.0;
+ var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY));
+ var tY = vBY + (wB * rBX) - vAY - (wA * rAX);
+ var vRel = cc.normal.x * tX + cc.normal.y * tY;
+ if (vRel < (-b2Settings.b2_velocityThreshold)) {
+ ccp.velocityBias += (-cc.restitution * vRel);
+ }
+ }
+ if (cc.pointCount == 2) {
+ var ccp1 = cc.points[0];
+ var ccp2 = cc.points[1];
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX;
+ var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX;
+ var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX;
+ var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX;
+ var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B;
+ var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B;
+ var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B;
+ var k_maxConditionNumber = 100.0;
+ if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) {
+ cc.K.col1.Set(k11, k12);
+ cc.K.col2.Set(k12, k22);
+ cc.K.GetInverse(cc.normalMass);
+ }
+ else {
+ cc.pointCount = 1;
+ }
+ }
+ }
+ }
+ b2ContactSolver.prototype.InitVelocityConstraints = function (step) {
+ var tVec;
+ var tVec2;
+ var tMat;
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var normalX = c.normal.x;
+ var normalY = c.normal.y;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var tX = 0;
+ var j = 0;
+ var tCount = 0;
+ if (step.warmStarting) {
+ tCount = c.pointCount;
+ for (j = 0;
+ j < tCount; ++j) {
+ var ccp = c.points[j];
+ ccp.normalImpulse *= step.dtRatio;
+ ccp.tangentImpulse *= step.dtRatio;
+ var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX;
+ var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY;
+ bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ bodyA.m_linearVelocity.x -= invMassA * PX;
+ bodyA.m_linearVelocity.y -= invMassA * PY;
+ bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ bodyB.m_linearVelocity.x += invMassB * PX;
+ bodyB.m_linearVelocity.y += invMassB * PY;
+ }
+ }
+ else {
+ tCount = c.pointCount;
+ for (j = 0;
+ j < tCount; ++j) {
+ var ccp2 = c.points[j];
+ ccp2.normalImpulse = 0.0;
+ ccp2.tangentImpulse = 0.0;
+ }
+ }
+ }
+ }
+ b2ContactSolver.prototype.SolveVelocityConstraints = function () {
+ var j = 0;
+ var ccp;
+ var rAX = 0;
+ var rAY = 0;
+ var rBX = 0;
+ var rBY = 0;
+ var dvX = 0;
+ var dvY = 0;
+ var vn = 0;
+ var vt = 0;
+ var lambda = 0;
+ var maxFriction = 0;
+ var newImpulse = 0;
+ var PX = 0;
+ var PY = 0;
+ var dX = 0;
+ var dY = 0;
+ var P1X = 0;
+ var P1Y = 0;
+ var P2X = 0;
+ var P2Y = 0;
+ var tMat;
+ var tVec;
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var wA = bodyA.m_angularVelocity;
+ var wB = bodyB.m_angularVelocity;
+ var vA = bodyA.m_linearVelocity;
+ var vB = bodyB.m_linearVelocity;
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var normalX = c.normal.x;
+ var normalY = c.normal.y;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var friction = c.friction;
+ var tX = 0;
+ for (j = 0;
+ j < c.pointCount; j++) {
+ ccp = c.points[j];
+ dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y;
+ dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x;
+ vt = dvX * tangentX + dvY * tangentY;
+ lambda = ccp.tangentMass * (-vt);
+ maxFriction = friction * ccp.normalImpulse;
+ newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, (-maxFriction), maxFriction);
+ lambda = newImpulse - ccp.tangentImpulse;
+ PX = lambda * tangentX;
+ PY = lambda * tangentY;
+ vA.x -= invMassA * PX;
+ vA.y -= invMassA * PY;
+ wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ vB.x += invMassB * PX;
+ vB.y += invMassB * PY;
+ wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ ccp.tangentImpulse = newImpulse;
+ }
+ var tCount = parseInt(c.pointCount);
+ if (c.pointCount == 1) {
+ ccp = c.points[0];
+ dvX = vB.x + ((-wB * ccp.rB.y)) - vA.x - ((-wA * ccp.rA.y));
+ dvY = vB.y + (wB * ccp.rB.x) - vA.y - (wA * ccp.rA.x);
+ vn = dvX * normalX + dvY * normalY;
+ lambda = (-ccp.normalMass * (vn - ccp.velocityBias));
+ newImpulse = ccp.normalImpulse + lambda;
+ newImpulse = newImpulse > 0 ? newImpulse : 0.0;
+ lambda = newImpulse - ccp.normalImpulse;
+ PX = lambda * normalX;
+ PY = lambda * normalY;
+ vA.x -= invMassA * PX;
+ vA.y -= invMassA * PY;
+ wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ vB.x += invMassB * PX;
+ vB.y += invMassB * PY;
+ wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ ccp.normalImpulse = newImpulse;
+ }
+ else {
+ var cp1 = c.points[0];
+ var cp2 = c.points[1];
+ var aX = cp1.normalImpulse;
+ var aY = cp2.normalImpulse;
+ var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y;
+ var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x;
+ var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y;
+ var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x;
+ var vn1 = dv1X * normalX + dv1Y * normalY;
+ var vn2 = dv2X * normalX + dv2Y * normalY;
+ var bX = vn1 - cp1.velocityBias;
+ var bY = vn2 - cp2.velocityBias;
+ tMat = c.K;
+ bX -= tMat.col1.x * aX + tMat.col2.x * aY;
+ bY -= tMat.col1.y * aX + tMat.col2.y * aY;
+ var k_errorTol = 0.001;
+ for (;;) {
+ tMat = c.normalMass;
+ var xX = (-(tMat.col1.x * bX + tMat.col2.x * bY));
+ var xY = (-(tMat.col1.y * bX + tMat.col2.y * bY));
+ if (xX >= 0.0 && xY >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = (-cp1.normalMass * bX);
+ xY = 0.0;
+ vn1 = 0.0;
+ vn2 = c.K.col1.y * xX + bY;
+ if (xX >= 0.0 && vn2 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = 0.0;
+ xY = (-cp2.normalMass * bY);
+ vn1 = c.K.col2.x * xY + bX;
+ vn2 = 0.0;
+ if (xY >= 0.0 && vn1 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = 0.0;
+ xY = 0.0;
+ vn1 = bX;
+ vn2 = bY;
+ if (vn1 >= 0.0 && vn2 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ break;
+ }
+ }
+ bodyA.m_angularVelocity = wA;
+ bodyB.m_angularVelocity = wB;
+ }
+ }
+ b2ContactSolver.prototype.FinalizeVelocityConstraints = function () {
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var m = c.manifold;
+ for (var j = 0; j < c.pointCount; ++j) {
+ var point1 = m.m_points[j];
+ var point2 = c.points[j];
+ point1.m_normalImpulse = point2.normalImpulse;
+ point1.m_tangentImpulse = point2.tangentImpulse;
+ }
+ }
+ }
+ b2ContactSolver.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var minSeparation = 0.0;
+ for (var i = 0; i < this.m_constraintCount; i++) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var invMassA = bodyA.m_mass * bodyA.m_invMass;
+ var invIA = bodyA.m_mass * bodyA.m_invI;
+ var invMassB = bodyB.m_mass * bodyB.m_invMass;
+ var invIB = bodyB.m_mass * bodyB.m_invI;
+ b2ContactSolver.s_psm.Initialize(c);
+ var normal = b2ContactSolver.s_psm.m_normal;
+ for (var j = 0; j < c.pointCount; j++) {
+ var ccp = c.points[j];
+ var point = b2ContactSolver.s_psm.m_points[j];
+ var separation = b2ContactSolver.s_psm.m_separations[j];
+ var rAX = point.x - bodyA.m_sweep.c.x;
+ var rAY = point.y - bodyA.m_sweep.c.y;
+ var rBX = point.x - bodyB.m_sweep.c.x;
+ var rBY = point.y - bodyB.m_sweep.c.y;
+ minSeparation = minSeparation < separation ? minSeparation : separation;
+ var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), (-b2Settings.b2_maxLinearCorrection), 0.0);
+ var impulse = (-ccp.equalizedMass * C);
+ var PX = impulse * normal.x;
+ var PY = impulse * normal.y;bodyA.m_sweep.c.x -= invMassA * PX;
+ bodyA.m_sweep.c.y -= invMassA * PY;
+ bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX);
+ bodyA.SynchronizeTransform();
+ bodyB.m_sweep.c.x += invMassB * PX;
+ bodyB.m_sweep.c.y += invMassB * PY;
+ bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX);
+ bodyB.SynchronizeTransform();
+ }
+ }
+ return minSeparation > (-1.5 * b2Settings.b2_linearSlop);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold = new b2WorldManifold();
+ Box2D.Dynamics.Contacts.b2ContactSolver.s_psm = new b2PositionSolverManifold();
+ });
+ Box2D.inherit(b2EdgeAndCircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2EdgeAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2EdgeAndCircleContact.b2EdgeAndCircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2EdgeAndCircleContact.Create = function (allocator) {
+ return new b2EdgeAndCircleContact();
+ }
+ b2EdgeAndCircleContact.Destroy = function (contact, allocator) {}
+ b2EdgeAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2EdgeAndCircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ this.b2CollideEdgeAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2EdgeShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function (manifold, edge, xf1, circle, xf2) {}
+ Box2D.inherit(b2NullContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2NullContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2NullContact.b2NullContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2NullContact.prototype.b2NullContact = function () {
+ this.__super.b2Contact.call(this);
+ }
+ b2NullContact.prototype.Evaluate = function () {}
+ Box2D.inherit(b2PolyAndCircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolyAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolyAndCircleContact.b2PolyAndCircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolyAndCircleContact.Create = function (allocator) {
+ return new b2PolyAndCircleContact();
+ }
+ b2PolyAndCircleContact.Destroy = function (contact, allocator) {}
+ b2PolyAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape);
+ b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape);
+ }
+ b2PolyAndCircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.m_body;
+ var bB = this.m_fixtureB.m_body;
+ b2Collision.CollidePolygonAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ Box2D.inherit(b2PolyAndEdgeContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolyAndEdgeContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolyAndEdgeContact.b2PolyAndEdgeContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolyAndEdgeContact.Create = function (allocator) {
+ return new b2PolyAndEdgeContact();
+ }
+ b2PolyAndEdgeContact.Destroy = function (contact, allocator) {}
+ b2PolyAndEdgeContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape);
+ b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape);
+ }
+ b2PolyAndEdgeContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ this.b2CollidePolyAndEdge(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2EdgeShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function (manifold, polygon, xf1, edge, xf2) {}
+ Box2D.inherit(b2PolygonContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolygonContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolygonContact.b2PolygonContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolygonContact.Create = function (allocator) {
+ return new b2PolygonContact();
+ }
+ b2PolygonContact.Destroy = function (contact, allocator) {}
+ b2PolygonContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2PolygonContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ b2Collision.CollidePolygons(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2PolygonShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2PositionSolverManifold.b2PositionSolverManifold = function () {};
+ b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () {
+ this.m_normal = new b2Vec2();
+ this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2Vec2();
+ }
+ }
+ b2PositionSolverManifold.prototype.Initialize = function (cc) {
+ b2Settings.b2Assert(cc.pointCount > 0);
+ var i = 0;
+ var clipPointX = 0;
+ var clipPointY = 0;
+ var tMat;
+ var tVec;
+ var planePointX = 0;
+ var planePointY = 0;
+ switch (cc.type) {
+ case b2Manifold.e_circles:
+ {
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPoint;
+ var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.points[0].localPoint;
+ var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dX = pointBX - pointAX;
+ var dY = pointBY - pointAY;
+ var d2 = dX * dX + dY * dY;
+ if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) {
+ var d = Math.sqrt(d2);
+ this.m_normal.x = dX / d;
+ this.m_normal.y = dY / d;
+ }
+ else {
+ this.m_normal.x = 1.0;
+ this.m_normal.y = 0.0;
+ }
+ this.m_points[0].x = 0.5 * (pointAX + pointBX);
+ this.m_points[0].y = 0.5 * (pointAY + pointBY);
+ this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius;
+ }
+ break;
+ case b2Manifold.e_faceA:
+ {
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPlaneNormal;
+ this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPoint;
+ planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyB.m_xf.R;
+ for (i = 0;
+ i < cc.pointCount; ++i) {
+ tVec = cc.points[i].localPoint;
+ clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius;
+ this.m_points[i].x = clipPointX;
+ this.m_points[i].y = clipPointY;
+ }
+ }
+ break;
+ case b2Manifold.e_faceB:
+ {
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.localPlaneNormal;
+ this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.localPoint;
+ planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyA.m_xf.R;
+ for (i = 0;
+ i < cc.pointCount; ++i) {
+ tVec = cc.points[i].localPoint;
+ clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius;
+ this.m_points[i].Set(clipPointX, clipPointY);
+ }
+ this.m_normal.x *= (-1);
+ this.m_normal.y *= (-1);
+ }
+ break;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA = new b2Vec2();
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB = new b2Vec2();
+ });
+})();
+(function () {
+ var b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2BuoyancyController = Box2D.Dynamics.Controllers.b2BuoyancyController,
+ b2ConstantAccelController = Box2D.Dynamics.Controllers.b2ConstantAccelController,
+ b2ConstantForceController = Box2D.Dynamics.Controllers.b2ConstantForceController,
+ b2Controller = Box2D.Dynamics.Controllers.b2Controller,
+ b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge,
+ b2GravityController = Box2D.Dynamics.Controllers.b2GravityController,
+ b2TensorDampingController = Box2D.Dynamics.Controllers.b2TensorDampingController;
+
+ Box2D.inherit(b2BuoyancyController, Box2D.Dynamics.Controllers.b2Controller);
+ b2BuoyancyController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2BuoyancyController.b2BuoyancyController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.normal = new b2Vec2(0, (-1));
+ this.offset = 0;
+ this.density = 0;
+ this.velocity = new b2Vec2(0, 0);
+ this.linearDrag = 2;
+ this.angularDrag = 1;
+ this.useDensity = false;
+ this.useWorldGravity = true;
+ this.gravity = null;
+ };
+ b2BuoyancyController.prototype.Step = function (step) {
+ if (!this.m_bodyList) return;
+ if (this.useWorldGravity) {
+ this.gravity = this.GetWorld().GetGravity().Copy();
+ }
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (body.IsAwake() == false) {
+ continue;
+ }
+ var areac = new b2Vec2();
+ var massc = new b2Vec2();
+ var area = 0.0;
+ var mass = 0.0;
+ for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) {
+ var sc = new b2Vec2();
+ var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc);
+ area += sarea;
+ areac.x += sarea * sc.x;
+ areac.y += sarea * sc.y;
+ var shapeDensity = 0;
+ if (this.useDensity) {
+ shapeDensity = 1;
+ }
+ else {
+ shapeDensity = 1;
+ }
+ mass += sarea * shapeDensity;
+ massc.x += sarea * sc.x * shapeDensity;
+ massc.y += sarea * sc.y * shapeDensity;
+ }
+ areac.x /= area;
+ areac.y /= area;
+ massc.x /= mass;
+ massc.y /= mass;
+ if (area < Number.MIN_VALUE) continue;
+ var buoyancyForce = this.gravity.GetNegative();
+ buoyancyForce.Multiply(this.density * area);
+ body.ApplyForce(buoyancyForce, massc);
+ var dragForce = body.GetLinearVelocityFromWorldPoint(areac);
+ dragForce.Subtract(this.velocity);
+ dragForce.Multiply((-this.linearDrag * area));
+ body.ApplyForce(dragForce, areac);
+ body.ApplyTorque((-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag));
+ }
+ }
+ b2BuoyancyController.prototype.Draw = function (debugDraw) {
+ var r = 1000;
+ var p1 = new b2Vec2();
+ var p2 = new b2Vec2();
+ p1.x = this.normal.x * this.offset + this.normal.y * r;
+ p1.y = this.normal.y * this.offset - this.normal.x * r;
+ p2.x = this.normal.x * this.offset - this.normal.y * r;
+ p2.y = this.normal.y * this.offset + this.normal.x * r;
+ var color = new b2Color(0, 0, 1);
+ debugDraw.DrawSegment(p1, p2, color);
+ }
+ Box2D.inherit(b2ConstantAccelController, Box2D.Dynamics.Controllers.b2Controller);
+ b2ConstantAccelController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2ConstantAccelController.b2ConstantAccelController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.A = new b2Vec2(0, 0);
+ };
+ b2ConstantAccelController.prototype.Step = function (step) {
+ var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt);
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) continue;
+ body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y));
+ }
+ }
+ Box2D.inherit(b2ConstantForceController, Box2D.Dynamics.Controllers.b2Controller);
+ b2ConstantForceController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2ConstantForceController.b2ConstantForceController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.F = new b2Vec2(0, 0);
+ };
+ b2ConstantForceController.prototype.Step = function (step) {
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) continue;
+ body.ApplyForce(this.F, body.GetWorldCenter());
+ }
+ }
+ b2Controller.b2Controller = function () {};
+ b2Controller.prototype.Step = function (step) {}
+ b2Controller.prototype.Draw = function (debugDraw) {}
+ b2Controller.prototype.AddBody = function (body) {
+ var edge = new b2ControllerEdge();
+ edge.controller = this;
+ edge.body = body;
+ edge.nextBody = this.m_bodyList;
+ edge.prevBody = null;
+ this.m_bodyList = edge;
+ if (edge.nextBody) edge.nextBody.prevBody = edge;
+ this.m_bodyCount++;
+ edge.nextController = body.m_controllerList;
+ edge.prevController = null;
+ body.m_controllerList = edge;
+ if (edge.nextController) edge.nextController.prevController = edge;
+ body.m_controllerCount++;
+ }
+ b2Controller.prototype.RemoveBody = function (body) {
+ var edge = body.m_controllerList;
+ while (edge && edge.controller != this)
+ edge = edge.nextController;
+ if (edge.prevBody) edge.prevBody.nextBody = edge.nextBody;
+ if (edge.nextBody) edge.nextBody.prevBody = edge.prevBody;
+ if (edge.nextController) edge.nextController.prevController = edge.prevController;
+ if (edge.prevController) edge.prevController.nextController = edge.nextController;
+ if (this.m_bodyList == edge) this.m_bodyList = edge.nextBody;
+ if (body.m_controllerList == edge) body.m_controllerList = edge.nextController;
+ body.m_controllerCount--;
+ this.m_bodyCount--;
+ }
+ b2Controller.prototype.Clear = function () {
+ while (this.m_bodyList)
+ this.RemoveBody(this.m_bodyList.body);
+ }
+ b2Controller.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Controller.prototype.GetWorld = function () {
+ return this.m_world;
+ }
+ b2Controller.prototype.GetBodyList = function () {
+ return this.m_bodyList;
+ }
+ b2ControllerEdge.b2ControllerEdge = function () {};
+ Box2D.inherit(b2GravityController, Box2D.Dynamics.Controllers.b2Controller);
+ b2GravityController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2GravityController.b2GravityController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.G = 1;
+ this.invSqr = true;
+ };
+ b2GravityController.prototype.Step = function (step) {
+ var i = null;
+ var body1 = null;
+ var p1 = null;
+ var mass1 = 0;
+ var j = null;
+ var body2 = null;
+ var p2 = null;
+ var dx = 0;
+ var dy = 0;
+ var r2 = 0;
+ var f = null;
+ if (this.invSqr) {
+ for (i = this.m_bodyList;
+ i; i = i.nextBody) {
+ body1 = i.body;
+ p1 = body1.GetWorldCenter();
+ mass1 = body1.GetMass();
+ for (j = this.m_bodyList;
+ j != i; j = j.nextBody) {
+ body2 = j.body;
+ p2 = body2.GetWorldCenter();
+ dx = p2.x - p1.x;
+ dy = p2.y - p1.y;
+ r2 = dx * dx + dy * dy;
+ if (r2 < Number.MIN_VALUE) continue;
+ f = new b2Vec2(dx, dy);
+ f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass());
+ if (body1.IsAwake()) body1.ApplyForce(f, p1);
+ f.Multiply((-1));
+ if (body2.IsAwake()) body2.ApplyForce(f, p2);
+ }
+ }
+ }
+ else {
+ for (i = this.m_bodyList;
+ i; i = i.nextBody) {
+ body1 = i.body;
+ p1 = body1.GetWorldCenter();
+ mass1 = body1.GetMass();
+ for (j = this.m_bodyList;
+ j != i; j = j.nextBody) {
+ body2 = j.body;
+ p2 = body2.GetWorldCenter();
+ dx = p2.x - p1.x;
+ dy = p2.y - p1.y;
+ r2 = dx * dx + dy * dy;
+ if (r2 < Number.MIN_VALUE) continue;
+ f = new b2Vec2(dx, dy);
+ f.Multiply(this.G / r2 * mass1 * body2.GetMass());
+ if (body1.IsAwake()) body1.ApplyForce(f, p1);
+ f.Multiply((-1));
+ if (body2.IsAwake()) body2.ApplyForce(f, p2);
+ }
+ }
+ }
+ }
+ Box2D.inherit(b2TensorDampingController, Box2D.Dynamics.Controllers.b2Controller);
+ b2TensorDampingController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2TensorDampingController.b2TensorDampingController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.T = new b2Mat22();
+ this.maxTimestep = 0;
+ };
+ b2TensorDampingController.prototype.SetAxisAligned = function (xDamping, yDamping) {
+ if (xDamping === undefined) xDamping = 0;
+ if (yDamping === undefined) yDamping = 0;
+ this.T.col1.x = (-xDamping);
+ this.T.col1.y = 0;
+ this.T.col2.x = 0;
+ this.T.col2.y = (-yDamping);
+ if (xDamping > 0 || yDamping > 0) {
+ this.maxTimestep = 1 / Math.max(xDamping, yDamping);
+ }
+ else {
+ this.maxTimestep = 0;
+ }
+ }
+ b2TensorDampingController.prototype.Step = function (step) {
+ var timestep = step.dt;
+ if (timestep <= Number.MIN_VALUE) return;
+ if (timestep > this.maxTimestep && this.maxTimestep > 0) timestep = this.maxTimestep;
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) {
+ continue;
+ }
+ var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity())));
+ body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep));
+ }
+ }
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint,
+ b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef,
+ b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint,
+ b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef,
+ b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint,
+ b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef,
+ b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian,
+ b2Joint = Box2D.Dynamics.Joints.b2Joint,
+ b2JointDef = Box2D.Dynamics.Joints.b2JointDef,
+ b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge,
+ b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint,
+ b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef,
+ b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint,
+ b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
+ b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint,
+ b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef,
+ b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint,
+ b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef,
+ b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
+ b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef,
+ b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint,
+ b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World;
+
+ Box2D.inherit(b2DistanceJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2DistanceJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2DistanceJoint.b2DistanceJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_u = new b2Vec2();
+ };
+ b2DistanceJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2DistanceJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2DistanceJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y);
+ }
+ b2DistanceJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2DistanceJoint.prototype.GetLength = function () {
+ return this.m_length;
+ }
+ b2DistanceJoint.prototype.SetLength = function (length) {
+ if (length === undefined) length = 0;
+ this.m_length = length;
+ }
+ b2DistanceJoint.prototype.GetFrequency = function () {
+ return this.m_frequencyHz;
+ }
+ b2DistanceJoint.prototype.SetFrequency = function (hz) {
+ if (hz === undefined) hz = 0;
+ this.m_frequencyHz = hz;
+ }
+ b2DistanceJoint.prototype.GetDampingRatio = function () {
+ return this.m_dampingRatio;
+ }
+ b2DistanceJoint.prototype.SetDampingRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_dampingRatio = ratio;
+ }
+ b2DistanceJoint.prototype.b2DistanceJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_length = def.length;
+ this.m_frequencyHz = def.frequencyHz;
+ this.m_dampingRatio = def.dampingRatio;
+ this.m_impulse = 0.0;
+ this.m_gamma = 0.0;
+ this.m_bias = 0.0;
+ }
+ b2DistanceJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y);
+ if (length > b2Settings.b2_linearSlop) {
+ this.m_u.Multiply(1.0 / length);
+ }
+ else {
+ this.m_u.SetZero();
+ }
+ var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x);
+ var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x);
+ var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u;
+ this.m_mass = invMass != 0.0 ? 1.0 / invMass : 0.0;
+ if (this.m_frequencyHz > 0.0) {
+ var C = length - this.m_length;
+ var omega = 2.0 * Math.PI * this.m_frequencyHz;
+ var d = 2.0 * this.m_mass * this.m_dampingRatio * omega;
+ var k = this.m_mass * omega * omega;
+ this.m_gamma = step.dt * (d + step.dt * k);
+ this.m_gamma = this.m_gamma != 0.0 ? 1 / this.m_gamma : 0.0;
+ this.m_bias = C * step.dt * k * this.m_gamma;
+ this.m_mass = invMass + this.m_gamma;
+ this.m_mass = this.m_mass != 0.0 ? 1.0 / this.m_mass : 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse *= step.dtRatio;
+ var PX = this.m_impulse * this.m_u.x;
+ var PY = this.m_impulse * this.m_u.y;
+ bA.m_linearVelocity.x -= bA.m_invMass * PX;
+ bA.m_linearVelocity.y -= bA.m_invMass * PY;
+ bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_linearVelocity.x += bB.m_invMass * PX;
+ bB.m_linearVelocity.y += bB.m_invMass * PY;
+ bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX);
+ }
+ else {
+ this.m_impulse = 0.0;
+ }
+ }
+ b2DistanceJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ var v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ var v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ var v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y));
+ var impulse = (-this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse));
+ this.m_impulse += impulse;
+ var PX = impulse * this.m_u.x;
+ var PY = impulse * this.m_u.y;
+ bA.m_linearVelocity.x -= bA.m_invMass * PX;
+ bA.m_linearVelocity.y -= bA.m_invMass * PY;
+ bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_linearVelocity.x += bB.m_invMass * PX;
+ bB.m_linearVelocity.y += bB.m_invMass * PY;
+ bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX);
+ }
+ b2DistanceJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var tMat;
+ if (this.m_frequencyHz > 0.0) {
+ return true;
+ }
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var length = Math.sqrt(dX * dX + dY * dY);
+ dX /= length;
+ dY /= length;
+ var C = length - this.m_length;
+ C = b2Math.Clamp(C, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ var impulse = (-this.m_mass * C);
+ this.m_u.Set(dX, dY);
+ var PX = impulse * this.m_u.x;
+ var PY = impulse * this.m_u.y;
+ bA.m_sweep.c.x -= bA.m_invMass * PX;
+ bA.m_sweep.c.y -= bA.m_invMass * PY;
+ bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_sweep.c.x += bB.m_invMass * PX;
+ bB.m_sweep.c.y += bB.m_invMass * PY;
+ bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return b2Math.Abs(C) < b2Settings.b2_linearSlop;
+ }
+ Box2D.inherit(b2DistanceJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2DistanceJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2DistanceJointDef.b2DistanceJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2DistanceJointDef.prototype.b2DistanceJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_distanceJoint;
+ this.length = 1.0;
+ this.frequencyHz = 0.0;
+ this.dampingRatio = 0.0;
+ }
+ b2DistanceJointDef.prototype.Initialize = function (bA, bB, anchorA, anchorB) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB));
+ var dX = anchorB.x - anchorA.x;
+ var dY = anchorB.y - anchorA.y;
+ this.length = Math.sqrt(dX * dX + dY * dY);
+ this.frequencyHz = 0.0;
+ this.dampingRatio = 0.0;
+ }
+ Box2D.inherit(b2FrictionJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2FrictionJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2FrictionJoint.b2FrictionJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchorA = new b2Vec2();
+ this.m_localAnchorB = new b2Vec2();
+ this.m_linearMass = new b2Mat22();
+ this.m_linearImpulse = new b2Vec2();
+ };
+ b2FrictionJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchorA);
+ }
+ b2FrictionJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchorB);
+ }
+ b2FrictionJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y);
+ }
+ b2FrictionJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_angularImpulse;
+ }
+ b2FrictionJoint.prototype.SetMaxForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_maxForce = force;
+ }
+ b2FrictionJoint.prototype.GetMaxForce = function () {
+ return this.m_maxForce;
+ }
+ b2FrictionJoint.prototype.SetMaxTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ this.m_maxTorque = torque;
+ }
+ b2FrictionJoint.prototype.GetMaxTorque = function () {
+ return this.m_maxTorque;
+ }
+ b2FrictionJoint.prototype.b2FrictionJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchorA.SetV(def.localAnchorA);
+ this.m_localAnchorB.SetV(def.localAnchorB);
+ this.m_linearMass.SetZero();
+ this.m_angularMass = 0.0;
+ this.m_linearImpulse.SetZero();
+ this.m_angularImpulse = 0.0;
+ this.m_maxForce = def.maxForce;
+ this.m_maxTorque = def.maxTorque;
+ }
+ b2FrictionJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ var K = new b2Mat22();
+ K.col1.x = mA + mB;
+ K.col2.x = 0.0;
+ K.col1.y = 0.0;
+ K.col2.y = mA + mB;
+ K.col1.x += iA * rAY * rAY;
+ K.col2.x += (-iA * rAX * rAY);
+ K.col1.y += (-iA * rAX * rAY);
+ K.col2.y += iA * rAX * rAX;
+ K.col1.x += iB * rBY * rBY;
+ K.col2.x += (-iB * rBX * rBY);
+ K.col1.y += (-iB * rBX * rBY);
+ K.col2.y += iB * rBX * rBX;
+ K.GetInverse(this.m_linearMass);
+ this.m_angularMass = iA + iB;
+ if (this.m_angularMass > 0.0) {
+ this.m_angularMass = 1.0 / this.m_angularMass;
+ }
+ if (step.warmStarting) {
+ this.m_linearImpulse.x *= step.dtRatio;
+ this.m_linearImpulse.y *= step.dtRatio;
+ this.m_angularImpulse *= step.dtRatio;
+ var P = this.m_linearImpulse;
+ bA.m_linearVelocity.x -= mA * P.x;
+ bA.m_linearVelocity.y -= mA * P.y;
+ bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse);
+ bB.m_linearVelocity.x += mB * P.x;
+ bB.m_linearVelocity.y += mB * P.y;
+ bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse);
+ }
+ else {
+ this.m_linearImpulse.SetZero();
+ this.m_angularImpulse = 0.0;
+ }
+ }
+ b2FrictionJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var vA = bA.m_linearVelocity;
+ var wA = bA.m_angularVelocity;
+ var vB = bB.m_linearVelocity;
+ var wB = bB.m_angularVelocity;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var maxImpulse = 0; {
+ var Cdot = wB - wA;
+ var impulse = (-this.m_angularMass * Cdot);
+ var oldImpulse = this.m_angularImpulse;
+ maxImpulse = step.dt * this.m_maxTorque;
+ this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_angularImpulse - oldImpulse;
+ wA -= iA * impulse;
+ wB += iB * impulse;
+ } {
+ var CdotX = vB.x - wB * rBY - vA.x + wA * rAY;
+ var CdotY = vB.y + wB * rBX - vA.y - wA * rAX;
+ var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2((-CdotX), (-CdotY)));
+ var oldImpulseV = this.m_linearImpulse.Copy();
+ this.m_linearImpulse.Add(impulseV);
+ maxImpulse = step.dt * this.m_maxForce;
+ if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) {
+ this.m_linearImpulse.Normalize();
+ this.m_linearImpulse.Multiply(maxImpulse);
+ }
+ impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV);
+ vA.x -= mA * impulseV.x;
+ vA.y -= mA * impulseV.y;
+ wA -= iA * (rAX * impulseV.y - rAY * impulseV.x);
+ vB.x += mB * impulseV.x;
+ vB.y += mB * impulseV.y;
+ wB += iB * (rBX * impulseV.y - rBY * impulseV.x);
+ }
+ bA.m_angularVelocity = wA;
+ bB.m_angularVelocity = wB;
+ }
+ b2FrictionJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return true;
+ }
+ Box2D.inherit(b2FrictionJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2FrictionJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2FrictionJointDef.b2FrictionJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2FrictionJointDef.prototype.b2FrictionJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_frictionJoint;
+ this.maxForce = 0.0;
+ this.maxTorque = 0.0;
+ }
+ b2FrictionJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor));
+ }
+ Box2D.inherit(b2GearJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2GearJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2GearJoint.b2GearJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_groundAnchor1 = new b2Vec2();
+ this.m_groundAnchor2 = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_J = new b2Jacobian();
+ };
+ b2GearJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2GearJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2GearJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y);
+ }
+ b2GearJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ var tMat = this.m_bodyB.m_xf.R;
+ var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y;
+ var tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ var PX = this.m_impulse * this.m_J.linearB.x;
+ var PY = this.m_impulse * this.m_J.linearB.y;
+ return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX);
+ }
+ b2GearJoint.prototype.GetRatio = function () {
+ return this.m_ratio;
+ }
+ b2GearJoint.prototype.SetRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_ratio = ratio;
+ }
+ b2GearJoint.prototype.b2GearJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var type1 = parseInt(def.joint1.m_type);
+ var type2 = parseInt(def.joint2.m_type);
+ this.m_revolute1 = null;
+ this.m_prismatic1 = null;
+ this.m_revolute2 = null;
+ this.m_prismatic2 = null;
+ var coordinate1 = 0;
+ var coordinate2 = 0;
+ this.m_ground1 = def.joint1.GetBodyA();
+ this.m_bodyA = def.joint1.GetBodyB();
+ if (type1 == b2Joint.e_revoluteJoint) {
+ this.m_revolute1 = (def.joint1 instanceof b2RevoluteJoint ? def.joint1 : null);
+ this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1);
+ this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2);
+ coordinate1 = this.m_revolute1.GetJointAngle();
+ }
+ else {
+ this.m_prismatic1 = (def.joint1 instanceof b2PrismaticJoint ? def.joint1 : null);
+ this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1);
+ this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2);
+ coordinate1 = this.m_prismatic1.GetJointTranslation();
+ }
+ this.m_ground2 = def.joint2.GetBodyA();
+ this.m_bodyB = def.joint2.GetBodyB();
+ if (type2 == b2Joint.e_revoluteJoint) {
+ this.m_revolute2 = (def.joint2 instanceof b2RevoluteJoint ? def.joint2 : null);
+ this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1);
+ this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2);
+ coordinate2 = this.m_revolute2.GetJointAngle();
+ }
+ else {
+ this.m_prismatic2 = (def.joint2 instanceof b2PrismaticJoint ? def.joint2 : null);
+ this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1);
+ this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2);
+ coordinate2 = this.m_prismatic2.GetJointTranslation();
+ }
+ this.m_ratio = def.ratio;
+ this.m_constant = coordinate1 + this.m_ratio * coordinate2;
+ this.m_impulse = 0.0;
+ }
+ b2GearJoint.prototype.InitVelocityConstraints = function (step) {
+ var g1 = this.m_ground1;
+ var g2 = this.m_ground2;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var ugX = 0;
+ var ugY = 0;
+ var rX = 0;
+ var rY = 0;
+ var tMat;
+ var tVec;
+ var crug = 0;
+ var tX = 0;
+ var K = 0.0;
+ this.m_J.SetZero();
+ if (this.m_revolute1) {
+ this.m_J.angularA = (-1.0);
+ K += bA.m_invI;
+ }
+ else {
+ tMat = g1.m_xf.R;
+ tVec = this.m_prismatic1.m_localXAxis1;
+ ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = bA.m_xf.R;
+ rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ crug = rX * ugY - rY * ugX;
+ this.m_J.linearA.Set((-ugX), (-ugY));
+ this.m_J.angularA = (-crug);
+ K += bA.m_invMass + bA.m_invI * crug * crug;
+ }
+ if (this.m_revolute2) {
+ this.m_J.angularB = (-this.m_ratio);
+ K += this.m_ratio * this.m_ratio * bB.m_invI;
+ }
+ else {
+ tMat = g2.m_xf.R;
+ tVec = this.m_prismatic2.m_localXAxis1;
+ ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = bB.m_xf.R;
+ rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ crug = rX * ugY - rY * ugX;
+ this.m_J.linearB.Set((-this.m_ratio * ugX), (-this.m_ratio * ugY));
+ this.m_J.angularB = (-this.m_ratio * crug);
+ K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug);
+ }
+ this.m_mass = K > 0.0 ? 1.0 / K : 0.0;
+ if (step.warmStarting) {
+ bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x;
+ bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y;
+ bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA;
+ bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x;
+ bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y;
+ bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB;
+ }
+ else {
+ this.m_impulse = 0.0;
+ }
+ }
+ b2GearJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity);
+ var impulse = (-this.m_mass * Cdot);
+ this.m_impulse += impulse;
+ bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x;
+ bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y;
+ bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA;
+ bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x;
+ bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y;
+ bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB;
+ }
+ b2GearJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var linearError = 0.0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var coordinate1 = 0;
+ var coordinate2 = 0;
+ if (this.m_revolute1) {
+ coordinate1 = this.m_revolute1.GetJointAngle();
+ }
+ else {
+ coordinate1 = this.m_prismatic1.GetJointTranslation();
+ }
+ if (this.m_revolute2) {
+ coordinate2 = this.m_revolute2.GetJointAngle();
+ }
+ else {
+ coordinate2 = this.m_prismatic2.GetJointTranslation();
+ }
+ var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2);
+ var impulse = (-this.m_mass * C);
+ bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x;
+ bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y;
+ bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA;
+ bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x;
+ bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y;
+ bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return linearError < b2Settings.b2_linearSlop;
+ }
+ Box2D.inherit(b2GearJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2GearJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2GearJointDef.b2GearJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ };
+ b2GearJointDef.prototype.b2GearJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_gearJoint;
+ this.joint1 = null;
+ this.joint2 = null;
+ this.ratio = 1.0;
+ }
+ b2Jacobian.b2Jacobian = function () {
+ this.linearA = new b2Vec2();
+ this.linearB = new b2Vec2();
+ };
+ b2Jacobian.prototype.SetZero = function () {
+ this.linearA.SetZero();
+ this.angularA = 0.0;
+ this.linearB.SetZero();
+ this.angularB = 0.0;
+ }
+ b2Jacobian.prototype.Set = function (x1, a1, x2, a2) {
+ if (a1 === undefined) a1 = 0;
+ if (a2 === undefined) a2 = 0;
+ this.linearA.SetV(x1);
+ this.angularA = a1;
+ this.linearB.SetV(x2);
+ this.angularB = a2;
+ }
+ b2Jacobian.prototype.Compute = function (x1, a1, x2, a2) {
+ if (a1 === undefined) a1 = 0;
+ if (a2 === undefined) a2 = 0;
+ return (this.linearA.x * x1.x + this.linearA.y * x1.y) + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2;
+ }
+ b2Joint.b2Joint = function () {
+ this.m_edgeA = new b2JointEdge();
+ this.m_edgeB = new b2JointEdge();
+ this.m_localCenterA = new b2Vec2();
+ this.m_localCenterB = new b2Vec2();
+ };
+ b2Joint.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Joint.prototype.GetAnchorA = function () {
+ return null;
+ }
+ b2Joint.prototype.GetAnchorB = function () {
+ return null;
+ }
+ b2Joint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return null;
+ }
+ b2Joint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2Joint.prototype.GetBodyA = function () {
+ return this.m_bodyA;
+ }
+ b2Joint.prototype.GetBodyB = function () {
+ return this.m_bodyB;
+ }
+ b2Joint.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Joint.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Joint.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Joint.prototype.IsActive = function () {
+ return this.m_bodyA.IsActive() && this.m_bodyB.IsActive();
+ }
+ b2Joint.Create = function (def, allocator) {
+ var joint = null;
+ switch (def.type) {
+ case b2Joint.e_distanceJoint:
+ {
+ joint = new b2DistanceJoint((def instanceof b2DistanceJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_mouseJoint:
+ {
+ joint = new b2MouseJoint((def instanceof b2MouseJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_prismaticJoint:
+ {
+ joint = new b2PrismaticJoint((def instanceof b2PrismaticJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_revoluteJoint:
+ {
+ joint = new b2RevoluteJoint((def instanceof b2RevoluteJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_pulleyJoint:
+ {
+ joint = new b2PulleyJoint((def instanceof b2PulleyJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_gearJoint:
+ {
+ joint = new b2GearJoint((def instanceof b2GearJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_lineJoint:
+ {
+ joint = new b2LineJoint((def instanceof b2LineJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_weldJoint:
+ {
+ joint = new b2WeldJoint((def instanceof b2WeldJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_frictionJoint:
+ {
+ joint = new b2FrictionJoint((def instanceof b2FrictionJointDef ? def : null));
+ }
+ break;
+ default:
+ break;
+ }
+ return joint;
+ }
+ b2Joint.Destroy = function (joint, allocator) {}
+ b2Joint.prototype.b2Joint = function (def) {
+ b2Settings.b2Assert(def.bodyA != def.bodyB);
+ this.m_type = def.type;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_bodyA = def.bodyA;
+ this.m_bodyB = def.bodyB;
+ this.m_collideConnected = def.collideConnected;
+ this.m_islandFlag = false;
+ this.m_userData = def.userData;
+ }
+ b2Joint.prototype.InitVelocityConstraints = function (step) {}
+ b2Joint.prototype.SolveVelocityConstraints = function (step) {}
+ b2Joint.prototype.FinalizeVelocityConstraints = function () {}
+ b2Joint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return false;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2Joint.e_unknownJoint = 0;
+ Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint = 1;
+ Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint = 2;
+ Box2D.Dynamics.Joints.b2Joint.e_distanceJoint = 3;
+ Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint = 4;
+ Box2D.Dynamics.Joints.b2Joint.e_mouseJoint = 5;
+ Box2D.Dynamics.Joints.b2Joint.e_gearJoint = 6;
+ Box2D.Dynamics.Joints.b2Joint.e_lineJoint = 7;
+ Box2D.Dynamics.Joints.b2Joint.e_weldJoint = 8;
+ Box2D.Dynamics.Joints.b2Joint.e_frictionJoint = 9;
+ Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit = 0;
+ Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit = 1;
+ Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit = 2;
+ Box2D.Dynamics.Joints.b2Joint.e_equalLimits = 3;
+ });
+ b2JointDef.b2JointDef = function () {};
+ b2JointDef.prototype.b2JointDef = function () {
+ this.type = b2Joint.e_unknownJoint;
+ this.userData = null;
+ this.bodyA = null;
+ this.bodyB = null;
+ this.collideConnected = false;
+ }
+ b2JointEdge.b2JointEdge = function () {};
+ Box2D.inherit(b2LineJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2LineJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2LineJoint.b2LineJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_localXAxis1 = new b2Vec2();
+ this.m_localYAxis1 = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ this.m_perp = new b2Vec2();
+ this.m_K = new b2Mat22();
+ this.m_impulse = new b2Vec2();
+ };
+ b2LineJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2LineJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2LineJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y));
+ }
+ b2LineJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.y;
+ }
+ b2LineJoint.prototype.GetJointTranslation = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var p1 = bA.GetWorldPoint(this.m_localAnchor1);
+ var p2 = bB.GetWorldPoint(this.m_localAnchor2);
+ var dX = p2.x - p1.x;
+ var dY = p2.y - p1.y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var translation = axis.x * dX + axis.y * dY;
+ return translation;
+ }
+ b2LineJoint.prototype.GetJointSpeed = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var v1 = bA.m_linearVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var w2 = bB.m_angularVelocity;
+ var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X)));
+ return speed;
+ }
+ b2LineJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2LineJoint.prototype.EnableLimit = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableLimit = flag;
+ }
+ b2LineJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerTranslation;
+ }
+ b2LineJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperTranslation;
+ }
+ b2LineJoint.prototype.SetLimits = function (lower, upper) {
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_lowerTranslation = lower;
+ this.m_upperTranslation = upper;
+ }
+ b2LineJoint.prototype.IsMotorEnabled = function () {
+ return this.m_enableMotor;
+ }
+ b2LineJoint.prototype.EnableMotor = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableMotor = flag;
+ }
+ b2LineJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2LineJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2LineJoint.prototype.SetMaxMotorForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_maxMotorForce = force;
+ }
+ b2LineJoint.prototype.GetMaxMotorForce = function () {
+ return this.m_maxMotorForce;
+ }
+ b2LineJoint.prototype.GetMotorForce = function () {
+ return this.m_motorImpulse;
+ }
+ b2LineJoint.prototype.b2LineJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_localXAxis1.SetV(def.localAxisA);
+ this.m_localYAxis1.x = (-this.m_localXAxis1.y);
+ this.m_localYAxis1.y = this.m_localXAxis1.x;
+ this.m_impulse.SetZero();
+ this.m_motorMass = 0.0;
+ this.m_motorImpulse = 0.0;
+ this.m_lowerTranslation = def.lowerTranslation;
+ this.m_upperTranslation = def.upperTranslation;
+ this.m_maxMotorForce = def.maxMotorForce;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_axis.SetZero();
+ this.m_perp.SetZero();
+ }
+ b2LineJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ this.m_localCenterA.SetV(bA.GetLocalCenter());
+ this.m_localCenterB.SetV(bB.GetLocalCenter());
+ var xf1 = bA.GetTransform();
+ var xf2 = bB.GetTransform();
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ this.m_invMassA = bA.m_invMass;
+ this.m_invMassB = bB.m_invMass;
+ this.m_invIA = bA.m_invI;
+ this.m_invIB = bB.m_invI; {
+ this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1));
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2;
+ this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1.0 / this.m_motorMass : 0.0;
+ } {
+ this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1));
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var m1 = this.m_invMassA;
+ var m2 = this.m_invMassB;
+ var i1 = this.m_invIA;
+ var i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ }
+ if (this.m_enableLimit) {
+ var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointTransition <= this.m_lowerTranslation) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else if (jointTransition >= this.m_upperTranslation) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x;
+ var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y;
+ var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1;
+ var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2;
+ bA.m_linearVelocity.x -= this.m_invMassA * PX;
+ bA.m_linearVelocity.y -= this.m_invMassA * PY;
+ bA.m_angularVelocity -= this.m_invIA * L1;
+ bB.m_linearVelocity.x += this.m_invMassB * PX;
+ bB.m_linearVelocity.y += this.m_invMassB * PY;
+ bB.m_angularVelocity += this.m_invIB * L2;
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2LineJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var PX = 0;
+ var PY = 0;
+ var L1 = 0;
+ var L2 = 0;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot);
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorForce;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ PX = impulse * this.m_axis.x;
+ PY = impulse * this.m_axis.y;
+ L1 = impulse * this.m_a1;
+ L2 = impulse * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var f1 = this.m_impulse.Copy();
+ var df = this.m_K.Solve(new b2Vec2(), (-Cdot1), (-Cdot2));
+ this.m_impulse.Add(df);
+ if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0.0);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0.0);
+ }
+ var b = (-Cdot1) - (this.m_impulse.y - f1.y) * this.m_K.col2.x;
+ var f2r = 0;
+ if (this.m_K.col1.x != 0.0) {
+ f2r = b / this.m_K.col1.x + f1.x;
+ }
+ else {
+ f2r = f1.x;
+ }
+ this.m_impulse.x = f2r;
+ df.x = this.m_impulse.x - f1.x;
+ df.y = this.m_impulse.y - f1.y;
+ PX = df.x * this.m_perp.x + df.y * this.m_axis.x;
+ PY = df.x * this.m_perp.y + df.y * this.m_axis.y;
+ L1 = df.x * this.m_s1 + df.y * this.m_a1;
+ L2 = df.x * this.m_s2 + df.y * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ else {
+ var df2 = 0;
+ if (this.m_K.col1.x != 0.0) {
+ df2 = ((-Cdot1)) / this.m_K.col1.x;
+ }
+ else {
+ df2 = 0.0;
+ }
+ this.m_impulse.x += df2;
+ PX = df2 * this.m_perp.x;
+ PY = df2 * this.m_perp.y;
+ L1 = df2 * this.m_s1;
+ L2 = df2 * this.m_s2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2LineJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var limitC = 0;
+ var oldLimitImpulse = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var c1 = bA.m_sweep.c;
+ var a1 = bA.m_sweep.a;
+ var c2 = bB.m_sweep.c;
+ var a2 = bB.m_sweep.a;
+ var tMat;
+ var tX = 0;
+ var m1 = 0;
+ var m2 = 0;
+ var i1 = 0;
+ var i2 = 0;
+ var linearError = 0.0;
+ var angularError = 0.0;
+ var active = false;
+ var C2 = 0.0;
+ var R1 = b2Mat22.FromAngle(a1);
+ var R2 = b2Mat22.FromAngle(a2);
+ tMat = R1;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = R2;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = c2.x + r2X - c1.x - r1X;
+ var dY = c2.y + r2Y - c1.y - r1Y;
+ if (this.m_enableLimit) {
+ this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1);
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ var translation = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ linearError = b2Math.Abs(translation);
+ active = true;
+ }
+ else if (translation <= this.m_lowerTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ linearError = this.m_lowerTranslation - translation;
+ active = true;
+ }
+ else if (translation >= this.m_upperTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection);
+ linearError = translation - this.m_upperTranslation;
+ active = true;
+ }
+ }
+ this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1);
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var impulse = new b2Vec2();
+ var C1 = this.m_perp.x * dX + this.m_perp.y * dY;
+ linearError = b2Math.Max(linearError, b2Math.Abs(C1));
+ angularError = 0.0;
+ if (active) {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ this.m_K.Solve(impulse, (-C1), (-C2));
+ }
+ else {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ var impulse1 = 0;
+ if (k11 != 0.0) {
+ impulse1 = ((-C1)) / k11;
+ }
+ else {
+ impulse1 = 0.0;
+ }
+ impulse.x = impulse1;
+ impulse.y = 0.0;
+ }
+ var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x;
+ var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y;
+ var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1;
+ var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2;
+ c1.x -= this.m_invMassA * PX;
+ c1.y -= this.m_invMassA * PY;
+ a1 -= this.m_invIA * L1;
+ c2.x += this.m_invMassB * PX;
+ c2.y += this.m_invMassB * PY;
+ a2 += this.m_invIB * L2;
+ bA.m_sweep.a = a1;
+ bB.m_sweep.a = a2;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+
+ return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2LineJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2LineJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2LineJointDef.b2LineJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ this.localAxisA = new b2Vec2();
+ };
+ b2LineJointDef.prototype.b2LineJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_lineJoint;
+ this.localAxisA.Set(1.0, 0.0);
+ this.enableLimit = false;
+ this.lowerTranslation = 0.0;
+ this.upperTranslation = 0.0;
+ this.enableMotor = false;
+ this.maxMotorForce = 0.0;
+ this.motorSpeed = 0.0;
+ }
+ b2LineJointDef.prototype.Initialize = function (bA, bB, anchor, axis) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.localAxisA = this.bodyA.GetLocalVector(axis);
+ }
+ Box2D.inherit(b2MouseJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2MouseJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2MouseJoint.b2MouseJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.K = new b2Mat22();
+ this.K1 = new b2Mat22();
+ this.K2 = new b2Mat22();
+ this.m_localAnchor = new b2Vec2();
+ this.m_target = new b2Vec2();
+ this.m_impulse = new b2Vec2();
+ this.m_mass = new b2Mat22();
+ this.m_C = new b2Vec2();
+ };
+ b2MouseJoint.prototype.GetAnchorA = function () {
+ return this.m_target;
+ }
+ b2MouseJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor);
+ }
+ b2MouseJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2MouseJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2MouseJoint.prototype.GetTarget = function () {
+ return this.m_target;
+ }
+ b2MouseJoint.prototype.SetTarget = function (target) {
+ if (this.m_bodyB.IsAwake() == false) {
+ this.m_bodyB.SetAwake(true);
+ }
+ this.m_target = target;
+ }
+ b2MouseJoint.prototype.GetMaxForce = function () {
+ return this.m_maxForce;
+ }
+ b2MouseJoint.prototype.SetMaxForce = function (maxForce) {
+ if (maxForce === undefined) maxForce = 0;
+ this.m_maxForce = maxForce;
+ }
+ b2MouseJoint.prototype.GetFrequency = function () {
+ return this.m_frequencyHz;
+ }
+ b2MouseJoint.prototype.SetFrequency = function (hz) {
+ if (hz === undefined) hz = 0;
+ this.m_frequencyHz = hz;
+ }
+ b2MouseJoint.prototype.GetDampingRatio = function () {
+ return this.m_dampingRatio;
+ }
+ b2MouseJoint.prototype.SetDampingRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_dampingRatio = ratio;
+ }
+ b2MouseJoint.prototype.b2MouseJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_target.SetV(def.target);
+ var tX = this.m_target.x - this.m_bodyB.m_xf.position.x;
+ var tY = this.m_target.y - this.m_bodyB.m_xf.position.y;
+ var tMat = this.m_bodyB.m_xf.R;
+ this.m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y);
+ this.m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ this.m_maxForce = def.maxForce;
+ this.m_impulse.SetZero();
+ this.m_frequencyHz = def.frequencyHz;
+ this.m_dampingRatio = def.dampingRatio;
+ this.m_beta = 0.0;
+ this.m_gamma = 0.0;
+ }
+ b2MouseJoint.prototype.InitVelocityConstraints = function (step) {
+ var b = this.m_bodyB;
+ var mass = b.GetMass();
+ var omega = 2.0 * Math.PI * this.m_frequencyHz;
+ var d = 2.0 * mass * this.m_dampingRatio * omega;
+ var k = mass * omega * omega;
+ this.m_gamma = step.dt * (d + step.dt * k);
+ this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0.0;
+ this.m_beta = step.dt * k * this.m_gamma;
+ var tMat;tMat = b.m_xf.R;
+ var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * rX + tMat.col2.x * rY);rY = (tMat.col1.y * rX + tMat.col2.y * rY);
+ rX = tX;
+ var invMass = b.m_invMass;
+ var invI = b.m_invI;this.K1.col1.x = invMass;
+ this.K1.col2.x = 0.0;
+ this.K1.col1.y = 0.0;
+ this.K1.col2.y = invMass;
+ this.K2.col1.x = invI * rY * rY;
+ this.K2.col2.x = (-invI * rX * rY);
+ this.K2.col1.y = (-invI * rX * rY);
+ this.K2.col2.y = invI * rX * rX;
+ this.K.SetM(this.K1);
+ this.K.AddM(this.K2);
+ this.K.col1.x += this.m_gamma;
+ this.K.col2.y += this.m_gamma;
+ this.K.GetInverse(this.m_mass);
+ this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x;
+ this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y;
+ b.m_angularVelocity *= 0.98;
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ b.m_linearVelocity.x += invMass * this.m_impulse.x;
+ b.m_linearVelocity.y += invMass * this.m_impulse.y;
+ b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x);
+ }
+ b2MouseJoint.prototype.SolveVelocityConstraints = function (step) {
+ var b = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ tMat = b.m_xf.R;
+ var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rX + tMat.col2.x * rY);
+ rY = (tMat.col1.y * rX + tMat.col2.y * rY);
+ rX = tX;
+ var CdotX = b.m_linearVelocity.x + ((-b.m_angularVelocity * rY));
+ var CdotY = b.m_linearVelocity.y + (b.m_angularVelocity * rX);
+ tMat = this.m_mass;
+ tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x;
+ tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y;
+ var impulseX = (-(tMat.col1.x * tX + tMat.col2.x * tY));
+ var impulseY = (-(tMat.col1.y * tX + tMat.col2.y * tY));
+ var oldImpulseX = this.m_impulse.x;
+ var oldImpulseY = this.m_impulse.y;
+ this.m_impulse.x += impulseX;
+ this.m_impulse.y += impulseY;
+ var maxImpulse = step.dt * this.m_maxForce;
+ if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) {
+ this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length());
+ }
+ impulseX = this.m_impulse.x - oldImpulseX;
+ impulseY = this.m_impulse.y - oldImpulseY;
+ b.m_linearVelocity.x += b.m_invMass * impulseX;
+ b.m_linearVelocity.y += b.m_invMass * impulseY;
+ b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX);
+ }
+ b2MouseJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return true;
+ }
+ Box2D.inherit(b2MouseJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2MouseJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2MouseJointDef.b2MouseJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.target = new b2Vec2();
+ };
+ b2MouseJointDef.prototype.b2MouseJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_mouseJoint;
+ this.maxForce = 0.0;
+ this.frequencyHz = 5.0;
+ this.dampingRatio = 0.7;
+ }
+ Box2D.inherit(b2PrismaticJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2PrismaticJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2PrismaticJoint.b2PrismaticJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_localXAxis1 = new b2Vec2();
+ this.m_localYAxis1 = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ this.m_perp = new b2Vec2();
+ this.m_K = new b2Mat33();
+ this.m_impulse = new b2Vec3();
+ };
+ b2PrismaticJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2PrismaticJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2PrismaticJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y));
+ }
+ b2PrismaticJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.y;
+ }
+ b2PrismaticJoint.prototype.GetJointTranslation = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var p1 = bA.GetWorldPoint(this.m_localAnchor1);
+ var p2 = bB.GetWorldPoint(this.m_localAnchor2);
+ var dX = p2.x - p1.x;
+ var dY = p2.y - p1.y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var translation = axis.x * dX + axis.y * dY;
+ return translation;
+ }
+ b2PrismaticJoint.prototype.GetJointSpeed = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var v1 = bA.m_linearVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var w2 = bB.m_angularVelocity;
+ var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X)));
+ return speed;
+ }
+ b2PrismaticJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2PrismaticJoint.prototype.EnableLimit = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableLimit = flag;
+ }
+ b2PrismaticJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerTranslation;
+ }
+ b2PrismaticJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperTranslation;
+ }
+ b2PrismaticJoint.prototype.SetLimits = function (lower, upper) {
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_lowerTranslation = lower;
+ this.m_upperTranslation = upper;
+ }
+ b2PrismaticJoint.prototype.IsMotorEnabled = function () {
+ return this.m_enableMotor;
+ }
+ b2PrismaticJoint.prototype.EnableMotor = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableMotor = flag;
+ }
+ b2PrismaticJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2PrismaticJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2PrismaticJoint.prototype.SetMaxMotorForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_maxMotorForce = force;
+ }
+ b2PrismaticJoint.prototype.GetMotorForce = function () {
+ return this.m_motorImpulse;
+ }
+ b2PrismaticJoint.prototype.b2PrismaticJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_localXAxis1.SetV(def.localAxisA);
+ this.m_localYAxis1.x = (-this.m_localXAxis1.y);
+ this.m_localYAxis1.y = this.m_localXAxis1.x;
+ this.m_refAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_motorMass = 0.0;
+ this.m_motorImpulse = 0.0;
+ this.m_lowerTranslation = def.lowerTranslation;
+ this.m_upperTranslation = def.upperTranslation;
+ this.m_maxMotorForce = def.maxMotorForce;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_axis.SetZero();
+ this.m_perp.SetZero();
+ }
+ b2PrismaticJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ this.m_localCenterA.SetV(bA.GetLocalCenter());
+ this.m_localCenterB.SetV(bB.GetLocalCenter());
+ var xf1 = bA.GetTransform();
+ var xf2 = bB.GetTransform();
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ this.m_invMassA = bA.m_invMass;
+ this.m_invMassB = bB.m_invMass;
+ this.m_invIA = bA.m_invI;
+ this.m_invIB = bB.m_invI; {
+ this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1));
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2;
+ if (this.m_motorMass > Number.MIN_VALUE) this.m_motorMass = 1.0 / this.m_motorMass;
+ } {
+ this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1));
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var m1 = this.m_invMassA;
+ var m2 = this.m_invMassB;
+ var i1 = this.m_invIA;
+ var i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2;
+ this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = i1 + i2;
+ this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2;
+ this.m_K.col3.x = this.m_K.col1.z;
+ this.m_K.col3.y = this.m_K.col2.z;
+ this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ }
+ if (this.m_enableLimit) {
+ var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointTransition <= this.m_lowerTranslation) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else if (jointTransition >= this.m_upperTranslation) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x;
+ var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y;
+ var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1;
+ var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2;
+ bA.m_linearVelocity.x -= this.m_invMassA * PX;
+ bA.m_linearVelocity.y -= this.m_invMassA * PY;
+ bA.m_angularVelocity -= this.m_invIA * L1;
+ bB.m_linearVelocity.x += this.m_invMassB * PX;
+ bB.m_linearVelocity.y += this.m_invMassB * PY;
+ bB.m_angularVelocity += this.m_invIB * L2;
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2PrismaticJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var PX = 0;
+ var PY = 0;
+ var L1 = 0;
+ var L2 = 0;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot);
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorForce;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ PX = impulse * this.m_axis.x;
+ PY = impulse * this.m_axis.y;
+ L1 = impulse * this.m_a1;
+ L2 = impulse * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1;
+ var Cdot1Y = w2 - w1;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var f1 = this.m_impulse.Copy();
+ var df = this.m_K.Solve33(new b2Vec3(), (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ this.m_impulse.Add(df);
+ if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0.0);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0.0);
+ }
+ var bX = (-Cdot1X) - (this.m_impulse.z - f1.z) * this.m_K.col3.x;
+ var bY = (-Cdot1Y) - (this.m_impulse.z - f1.z) * this.m_K.col3.y;
+ var f2r = this.m_K.Solve22(new b2Vec2(), bX, bY);
+ f2r.x += f1.x;
+ f2r.y += f1.y;
+ this.m_impulse.x = f2r.x;
+ this.m_impulse.y = f2r.y;
+ df.x = this.m_impulse.x - f1.x;
+ df.y = this.m_impulse.y - f1.y;
+ df.z = this.m_impulse.z - f1.z;
+ PX = df.x * this.m_perp.x + df.z * this.m_axis.x;
+ PY = df.x * this.m_perp.y + df.z * this.m_axis.y;
+ L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1;
+ L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ else {
+ var df2 = this.m_K.Solve22(new b2Vec2(), (-Cdot1X), (-Cdot1Y));
+ this.m_impulse.x += df2.x;
+ this.m_impulse.y += df2.y;
+ PX = df2.x * this.m_perp.x;
+ PY = df2.x * this.m_perp.y;
+ L1 = df2.x * this.m_s1 + df2.y;
+ L2 = df2.x * this.m_s2 + df2.y;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2PrismaticJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var limitC = 0;
+ var oldLimitImpulse = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var c1 = bA.m_sweep.c;
+ var a1 = bA.m_sweep.a;
+ var c2 = bB.m_sweep.c;
+ var a2 = bB.m_sweep.a;
+ var tMat;
+ var tX = 0;
+ var m1 = 0;
+ var m2 = 0;
+ var i1 = 0;
+ var i2 = 0;
+ var linearError = 0.0;
+ var angularError = 0.0;
+ var active = false;
+ var C2 = 0.0;
+ var R1 = b2Mat22.FromAngle(a1);
+ var R2 = b2Mat22.FromAngle(a2);
+ tMat = R1;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = R2;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = c2.x + r2X - c1.x - r1X;
+ var dY = c2.y + r2Y - c1.y - r1Y;
+ if (this.m_enableLimit) {
+ this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1);
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ var translation = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ linearError = b2Math.Abs(translation);
+ active = true;
+ }
+ else if (translation <= this.m_lowerTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ linearError = this.m_lowerTranslation - translation;
+ active = true;
+ }
+ else if (translation >= this.m_upperTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection);
+ linearError = translation - this.m_upperTranslation;
+ active = true;
+ }
+ }
+ this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1);
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var impulse = new b2Vec3();
+ var C1X = this.m_perp.x * dX + this.m_perp.y * dY;
+ var C1Y = a2 - a1 - this.m_refAngle;
+ linearError = b2Math.Max(linearError, b2Math.Abs(C1X));
+ angularError = b2Math.Abs(C1Y);
+ if (active) {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2;
+ this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = i1 + i2;
+ this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2;
+ this.m_K.col3.x = this.m_K.col1.z;
+ this.m_K.col3.y = this.m_K.col2.z;
+ this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ this.m_K.Solve33(impulse, (-C1X), (-C1Y), (-C2));
+ }
+ else {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ var k12 = i1 * this.m_s1 + i2 * this.m_s2;
+ var k22 = i1 + i2;
+ this.m_K.col1.Set(k11, k12, 0.0);
+ this.m_K.col2.Set(k12, k22, 0.0);
+ var impulse1 = this.m_K.Solve22(new b2Vec2(), (-C1X), (-C1Y));
+ impulse.x = impulse1.x;
+ impulse.y = impulse1.y;
+ impulse.z = 0.0;
+ }
+ var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x;
+ var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y;
+ var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1;
+ var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2;
+ c1.x -= this.m_invMassA * PX;
+ c1.y -= this.m_invMassA * PY;
+ a1 -= this.m_invIA * L1;
+ c2.x += this.m_invMassB * PX;
+ c2.y += this.m_invMassB * PY;
+ a2 += this.m_invIB * L2;
+ bA.m_sweep.a = a1;
+ bB.m_sweep.a = a2;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2PrismaticJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2PrismaticJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2PrismaticJointDef.b2PrismaticJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ this.localAxisA = new b2Vec2();
+ };
+ b2PrismaticJointDef.prototype.b2PrismaticJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_prismaticJoint;
+ this.localAxisA.Set(1.0, 0.0);
+ this.referenceAngle = 0.0;
+ this.enableLimit = false;
+ this.lowerTranslation = 0.0;
+ this.upperTranslation = 0.0;
+ this.enableMotor = false;
+ this.maxMotorForce = 0.0;
+ this.motorSpeed = 0.0;
+ }
+ b2PrismaticJointDef.prototype.Initialize = function (bA, bB, anchor, axis) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.localAxisA = this.bodyA.GetLocalVector(axis);
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+ Box2D.inherit(b2PulleyJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2PulleyJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2PulleyJoint.b2PulleyJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_groundAnchor1 = new b2Vec2();
+ this.m_groundAnchor2 = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_u1 = new b2Vec2();
+ this.m_u2 = new b2Vec2();
+ };
+ b2PulleyJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2PulleyJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2PulleyJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y);
+ }
+ b2PulleyJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2PulleyJoint.prototype.GetGroundAnchorA = function () {
+ var a = this.m_ground.m_xf.position.Copy();
+ a.Add(this.m_groundAnchor1);
+ return a;
+ }
+ b2PulleyJoint.prototype.GetGroundAnchorB = function () {
+ var a = this.m_ground.m_xf.position.Copy();
+ a.Add(this.m_groundAnchor2);
+ return a;
+ }
+ b2PulleyJoint.prototype.GetLength1 = function () {
+ var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var dX = p.x - sX;
+ var dY = p.y - sY;
+ return Math.sqrt(dX * dX + dY * dY);
+ }
+ b2PulleyJoint.prototype.GetLength2 = function () {
+ var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ var dX = p.x - sX;
+ var dY = p.y - sY;
+ return Math.sqrt(dX * dX + dY * dY);
+ }
+ b2PulleyJoint.prototype.GetRatio = function () {
+ return this.m_ratio;
+ }
+ b2PulleyJoint.prototype.b2PulleyJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_ground = this.m_bodyA.m_world.m_groundBody;
+ this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x;
+ this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y;
+ this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x;
+ this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_ratio = def.ratio;
+ this.m_constant = def.lengthA + this.m_ratio * def.lengthB;
+ this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength);
+ this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio);
+ this.m_impulse = 0.0;
+ this.m_limitImpulse1 = 0.0;
+ this.m_limitImpulse2 = 0.0;
+ }
+ b2PulleyJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ var length1 = this.m_u1.Length();
+ var length2 = this.m_u2.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.Multiply(1.0 / length1);
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.Multiply(1.0 / length2);
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ var C = this.m_constant - length1 - this.m_ratio * length2;
+ if (C > 0.0) {
+ this.m_state = b2Joint.e_inactiveLimit;
+ this.m_impulse = 0.0;
+ }
+ else {
+ this.m_state = b2Joint.e_atUpperLimit;
+ }
+ if (length1 < this.m_maxLength1) {
+ this.m_limitState1 = b2Joint.e_inactiveLimit;
+ this.m_limitImpulse1 = 0.0;
+ }
+ else {
+ this.m_limitState1 = b2Joint.e_atUpperLimit;
+ }
+ if (length2 < this.m_maxLength2) {
+ this.m_limitState2 = b2Joint.e_inactiveLimit;
+ this.m_limitImpulse2 = 0.0;
+ }
+ else {
+ this.m_limitState2 = b2Joint.e_atUpperLimit;
+ }
+ var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x;
+ var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x;
+ this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1;
+ this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2;
+ this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2;
+ this.m_limitMass1 = 1.0 / this.m_limitMass1;
+ this.m_limitMass2 = 1.0 / this.m_limitMass2;
+ this.m_pulleyMass = 1.0 / this.m_pulleyMass;
+ if (step.warmStarting) {
+ this.m_impulse *= step.dtRatio;
+ this.m_limitImpulse1 *= step.dtRatio;
+ this.m_limitImpulse2 *= step.dtRatio;
+ var P1X = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.x;
+ var P1Y = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.y;
+ var P2X = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.x;
+ var P2Y = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.y;
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ else {
+ this.m_impulse = 0.0;
+ this.m_limitImpulse1 = 0.0;
+ this.m_limitImpulse2 = 0.0;
+ }
+ }
+ b2PulleyJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var v1X = 0;
+ var v1Y = 0;
+ var v2X = 0;
+ var v2Y = 0;
+ var P1X = 0;
+ var P1Y = 0;
+ var P2X = 0;
+ var P2Y = 0;
+ var Cdot = 0;
+ var impulse = 0;
+ var oldImpulse = 0;
+ if (this.m_state == b2Joint.e_atUpperLimit) {
+ v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y);
+ impulse = this.m_pulleyMass * ((-Cdot));
+ oldImpulse = this.m_impulse;
+ this.m_impulse = b2Math.Max(0.0, this.m_impulse + impulse);
+ impulse = this.m_impulse - oldImpulse;
+ P1X = (-impulse * this.m_u1.x);
+ P1Y = (-impulse * this.m_u1.y);
+ P2X = (-this.m_ratio * impulse * this.m_u2.x);
+ P2Y = (-this.m_ratio * impulse * this.m_u2.y);
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ if (this.m_limitState1 == b2Joint.e_atUpperLimit) {
+ v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y));
+ impulse = (-this.m_limitMass1 * Cdot);
+ oldImpulse = this.m_limitImpulse1;
+ this.m_limitImpulse1 = b2Math.Max(0.0, this.m_limitImpulse1 + impulse);
+ impulse = this.m_limitImpulse1 - oldImpulse;
+ P1X = (-impulse * this.m_u1.x);
+ P1Y = (-impulse * this.m_u1.y);
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ }
+ if (this.m_limitState2 == b2Joint.e_atUpperLimit) {
+ v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ Cdot = (-(this.m_u2.x * v2X + this.m_u2.y * v2Y));
+ impulse = (-this.m_limitMass2 * Cdot);
+ oldImpulse = this.m_limitImpulse2;
+ this.m_limitImpulse2 = b2Math.Max(0.0, this.m_limitImpulse2 + impulse);
+ impulse = this.m_limitImpulse2 - oldImpulse;
+ P2X = (-impulse * this.m_u2.x);
+ P2Y = (-impulse * this.m_u2.y);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ }
+ b2PulleyJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ var r1X = 0;
+ var r1Y = 0;
+ var r2X = 0;
+ var r2Y = 0;
+ var p1X = 0;
+ var p1Y = 0;
+ var p2X = 0;
+ var p2Y = 0;
+ var length1 = 0;
+ var length2 = 0;
+ var C = 0;
+ var impulse = 0;
+ var oldImpulse = 0;
+ var oldLimitPositionImpulse = 0;
+ var tX = 0;
+ var linearError = 0.0;
+ if (this.m_state == b2Joint.e_atUpperLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ p1X = bA.m_sweep.c.x + r1X;
+ p1Y = bA.m_sweep.c.y + r1Y;
+ p2X = bB.m_sweep.c.x + r2X;
+ p2Y = bB.m_sweep.c.y + r2Y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ length1 = this.m_u1.Length();
+ length2 = this.m_u2.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.Multiply(1.0 / length1);
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.Multiply(1.0 / length2);
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ C = this.m_constant - length1 - this.m_ratio * length2;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_pulleyMass * C);
+ p1X = (-impulse * this.m_u1.x);
+ p1Y = (-impulse * this.m_u1.y);
+ p2X = (-this.m_ratio * impulse * this.m_u2.x);
+ p2Y = (-this.m_ratio * impulse * this.m_u2.y);
+ bA.m_sweep.c.x += bA.m_invMass * p1X;
+ bA.m_sweep.c.y += bA.m_invMass * p1Y;
+ bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X);
+ bB.m_sweep.c.x += bB.m_invMass * p2X;
+ bB.m_sweep.c.y += bB.m_invMass * p2Y;
+ bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ }
+ if (this.m_limitState1 == b2Joint.e_atUpperLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ p1X = bA.m_sweep.c.x + r1X;
+ p1Y = bA.m_sweep.c.y + r1Y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ length1 = this.m_u1.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.x *= 1.0 / length1;
+ this.m_u1.y *= 1.0 / length1;
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ C = this.m_maxLength1 - length1;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_limitMass1 * C);
+ p1X = (-impulse * this.m_u1.x);
+ p1Y = (-impulse * this.m_u1.y);
+ bA.m_sweep.c.x += bA.m_invMass * p1X;
+ bA.m_sweep.c.y += bA.m_invMass * p1Y;
+ bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X);
+ bA.SynchronizeTransform();
+ }
+ if (this.m_limitState2 == b2Joint.e_atUpperLimit) {
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ p2X = bB.m_sweep.c.x + r2X;
+ p2Y = bB.m_sweep.c.y + r2Y;
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ length2 = this.m_u2.Length();
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.x *= 1.0 / length2;
+ this.m_u2.y *= 1.0 / length2;
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ C = this.m_maxLength2 - length2;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_limitMass2 * C);
+ p2X = (-impulse * this.m_u2.x);
+ p2Y = (-impulse * this.m_u2.y);
+ bB.m_sweep.c.x += bB.m_invMass * p2X;
+ bB.m_sweep.c.y += bB.m_invMass * p2Y;
+ bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X);
+ bB.SynchronizeTransform();
+ }
+ return linearError < b2Settings.b2_linearSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength = 2.0;
+ });
+ Box2D.inherit(b2PulleyJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2PulleyJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2PulleyJointDef.b2PulleyJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.groundAnchorA = new b2Vec2();
+ this.groundAnchorB = new b2Vec2();
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2PulleyJointDef.prototype.b2PulleyJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_pulleyJoint;
+ this.groundAnchorA.Set((-1.0), 1.0);
+ this.groundAnchorB.Set(1.0, 1.0);
+ this.localAnchorA.Set((-1.0), 0.0);
+ this.localAnchorB.Set(1.0, 0.0);
+ this.lengthA = 0.0;
+ this.maxLengthA = 0.0;
+ this.lengthB = 0.0;
+ this.maxLengthB = 0.0;
+ this.ratio = 1.0;
+ this.collideConnected = true;
+ }
+ b2PulleyJointDef.prototype.Initialize = function (bA, bB, gaA, gaB, anchorA, anchorB, r) {
+ if (r === undefined) r = 0;
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.groundAnchorA.SetV(gaA);
+ this.groundAnchorB.SetV(gaB);
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchorA);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchorB);
+ var d1X = anchorA.x - gaA.x;
+ var d1Y = anchorA.y - gaA.y;
+ this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y);
+ var d2X = anchorB.x - gaB.x;
+ var d2Y = anchorB.y - gaB.y;
+ this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y);
+ this.ratio = r;
+ var C = this.lengthA + this.ratio * this.lengthB;
+ this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength;
+ this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio;
+ }
+ Box2D.inherit(b2RevoluteJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2RevoluteJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2RevoluteJoint.b2RevoluteJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.K = new b2Mat22();
+ this.K1 = new b2Mat22();
+ this.K2 = new b2Mat22();
+ this.K3 = new b2Mat22();
+ this.impulse3 = new b2Vec3();
+ this.impulse2 = new b2Vec2();
+ this.reduced = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_impulse = new b2Vec3();
+ this.m_mass = new b2Mat33();
+ };
+ b2RevoluteJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2RevoluteJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2RevoluteJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2RevoluteJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.z;
+ }
+ b2RevoluteJoint.prototype.GetJointAngle = function () {
+ return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle;
+ }
+ b2RevoluteJoint.prototype.GetJointSpeed = function () {
+ return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity;
+ }
+ b2RevoluteJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2RevoluteJoint.prototype.EnableLimit = function (flag) {
+ this.m_enableLimit = flag;
+ }
+ b2RevoluteJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerAngle;
+ }
+ b2RevoluteJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperAngle;
+ }
+ b2RevoluteJoint.prototype.SetLimits = function (lower, upper) {
+
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_lowerAngle = lower;
+ this.m_upperAngle = upper;
+ }
+ b2RevoluteJoint.prototype.IsMotorEnabled = function () {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ return this.m_enableMotor;
+ }
+ b2RevoluteJoint.prototype.EnableMotor = function (flag) {
+ this.m_enableMotor = flag;
+ }
+ b2RevoluteJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2RevoluteJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2RevoluteJoint.prototype.SetMaxMotorTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ this.m_maxMotorTorque = torque;
+ }
+ b2RevoluteJoint.prototype.GetMotorTorque = function () {
+ return this.m_maxMotorTorque;
+ }
+ b2RevoluteJoint.prototype.b2RevoluteJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_referenceAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ this.m_lowerAngle = def.lowerAngle;
+ this.m_upperAngle = def.upperAngle;
+ this.m_maxMotorTorque = def.maxMotorTorque;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ b2RevoluteJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ if (this.m_enableMotor || this.m_enableLimit) {}
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var m1 = bA.m_invMass;
+ var m2 = bB.m_invMass;
+ var i1 = bA.m_invI;
+ var i2 = bB.m_invI;
+ this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2;
+ this.m_mass.col2.x = (-r1Y * r1X * i1) - r2Y * r2X * i2;
+ this.m_mass.col3.x = (-r1Y * i1) - r2Y * i2;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2;
+ this.m_mass.col3.y = r1X * i1 + r2X * i2;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = i1 + i2;
+ this.m_motorMass = 1.0 / (i1 + i2);
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (this.m_enableLimit) {
+ var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ if (b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointAngle <= this.m_lowerAngle) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_impulse.z = 0.0;
+ }
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ }
+ else if (jointAngle >= this.m_upperAngle) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_impulse.z = 0.0;
+ }
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x;
+ var PY = this.m_impulse.y;
+ bA.m_linearVelocity.x -= m1 * PX;
+ bA.m_linearVelocity.y -= m1 * PY;
+ bA.m_angularVelocity -= i1 * ((r1X * PY - r1Y * PX) + this.m_motorImpulse + this.m_impulse.z);
+ bB.m_linearVelocity.x += m2 * PX;
+ bB.m_linearVelocity.y += m2 * PY;
+ bB.m_angularVelocity += i2 * ((r2X * PY - r2Y * PX) + this.m_motorImpulse + this.m_impulse.z);
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2RevoluteJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ var newImpulse = 0;
+ var r1X = 0;
+ var r1Y = 0;
+ var r2X = 0;
+ var r2Y = 0;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var m1 = bA.m_invMass;
+ var m2 = bB.m_invMass;
+ var i1 = bA.m_invI;
+ var i2 = bB.m_invI;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = w2 - w1 - this.m_motorSpeed;
+ var impulse = this.m_motorMass * ((-Cdot));
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorTorque;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ w1 -= i1 * impulse;
+ w2 += i2 * impulse;
+ }
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var Cdot1X = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y));
+ var Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
+ var Cdot2 = w2 - w1;
+ this.m_mass.Solve33(this.impulse3, (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ if (this.m_limitState == b2Joint.e_equalLimits) {
+ this.m_impulse.Add(this.impulse3);
+ }
+ else if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ newImpulse = this.m_impulse.z + this.impulse3.z;
+ if (newImpulse < 0.0) {
+ this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y));
+ this.impulse3.x = this.reduced.x;
+ this.impulse3.y = this.reduced.y;
+ this.impulse3.z = (-this.m_impulse.z);
+ this.m_impulse.x += this.reduced.x;
+ this.m_impulse.y += this.reduced.y;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ newImpulse = this.m_impulse.z + this.impulse3.z;
+ if (newImpulse > 0.0) {
+ this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y));
+ this.impulse3.x = this.reduced.x;
+ this.impulse3.y = this.reduced.y;
+ this.impulse3.z = (-this.m_impulse.z);
+ this.m_impulse.x += this.reduced.x;
+ this.m_impulse.y += this.reduced.y;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ v1.x -= m1 * this.impulse3.x;
+ v1.y -= m1 * this.impulse3.y;
+ w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z);
+ v2.x += m2 * this.impulse3.x;
+ v2.y += m2 * this.impulse3.y;
+ w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z);
+ }
+ else {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var CdotX = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y));
+ var CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
+ this.m_mass.Solve22(this.impulse2, (-CdotX), (-CdotY));
+ this.m_impulse.x += this.impulse2.x;
+ this.m_impulse.y += this.impulse2.y;
+ v1.x -= m1 * this.impulse2.x;
+ v1.y -= m1 * this.impulse2.y;
+ w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x);
+ v2.x += m2 * this.impulse2.x;
+ v2.y += m2 * this.impulse2.y;
+ w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x);
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2RevoluteJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var oldLimitImpulse = 0;
+ var C = 0;
+ var tMat;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var angularError = 0.0;
+ var positionError = 0.0;
+ var tX = 0;
+ var impulseX = 0;
+ var impulseY = 0;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ var limitImpulse = 0.0;
+ if (this.m_limitState == b2Joint.e_equalLimits) {
+ C = b2Math.Clamp(angle - this.m_lowerAngle, (-b2Settings.b2_maxAngularCorrection), b2Settings.b2_maxAngularCorrection);
+ limitImpulse = (-this.m_motorMass * C);
+ angularError = b2Math.Abs(C);
+ }
+ else if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ C = angle - this.m_lowerAngle;
+ angularError = (-C);
+ C = b2Math.Clamp(C + b2Settings.b2_angularSlop, (-b2Settings.b2_maxAngularCorrection), 0.0);
+ limitImpulse = (-this.m_motorMass * C);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ C = angle - this.m_upperAngle;
+ angularError = C;
+ C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection);
+ limitImpulse = (-this.m_motorMass * C);
+ }
+ bA.m_sweep.a -= bA.m_invI * limitImpulse;
+ bB.m_sweep.a += bB.m_invI * limitImpulse;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ } {
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var CLengthSquared = CX * CX + CY * CY;
+ var CLength = Math.sqrt(CLengthSquared);
+ positionError = CLength;
+ var invMass1 = bA.m_invMass;
+ var invMass2 = bB.m_invMass;
+ var invI1 = bA.m_invI;
+ var invI2 = bB.m_invI;
+ var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop;
+ if (CLengthSquared > k_allowedStretch * k_allowedStretch) {
+ var uX = CX / CLength;
+ var uY = CY / CLength;
+ var k = invMass1 + invMass2;
+ var m = 1.0 / k;
+ impulseX = m * ((-CX));
+ impulseY = m * ((-CY));
+ var k_beta = 0.5;
+ bA.m_sweep.c.x -= k_beta * invMass1 * impulseX;
+ bA.m_sweep.c.y -= k_beta * invMass1 * impulseY;
+ bB.m_sweep.c.x += k_beta * invMass2 * impulseX;
+ bB.m_sweep.c.y += k_beta * invMass2 * impulseY;
+ CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ }
+ this.K1.col1.x = invMass1 + invMass2;
+ this.K1.col2.x = 0.0;
+ this.K1.col1.y = 0.0;
+ this.K1.col2.y = invMass1 + invMass2;
+ this.K2.col1.x = invI1 * r1Y * r1Y;
+ this.K2.col2.x = (-invI1 * r1X * r1Y);
+ this.K2.col1.y = (-invI1 * r1X * r1Y);
+ this.K2.col2.y = invI1 * r1X * r1X;
+ this.K3.col1.x = invI2 * r2Y * r2Y;
+ this.K3.col2.x = (-invI2 * r2X * r2Y);
+ this.K3.col1.y = (-invI2 * r2X * r2Y);
+ this.K3.col2.y = invI2 * r2X * r2X;
+ this.K.SetM(this.K1);
+ this.K.AddM(this.K2);
+ this.K.AddM(this.K3);
+ this.K.Solve(b2RevoluteJoint.tImpulse, (-CX), (-CY));
+ impulseX = b2RevoluteJoint.tImpulse.x;
+ impulseY = b2RevoluteJoint.tImpulse.y;
+ bA.m_sweep.c.x -= bA.m_invMass * impulseX;
+ bA.m_sweep.c.y -= bA.m_invMass * impulseY;
+ bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX);
+ bB.m_sweep.c.x += bB.m_invMass * impulseX;
+ bB.m_sweep.c.y += bB.m_invMass * impulseY;
+ bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ }
+ return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse = new b2Vec2();
+ });
+ Box2D.inherit(b2RevoluteJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2RevoluteJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2RevoluteJointDef.b2RevoluteJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2RevoluteJointDef.prototype.b2RevoluteJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_revoluteJoint;
+ this.localAnchorA.Set(0.0, 0.0);
+ this.localAnchorB.Set(0.0, 0.0);
+ this.referenceAngle = 0.0;
+ this.lowerAngle = 0.0;
+ this.upperAngle = 0.0;
+ this.maxMotorTorque = 0.0;
+ this.motorSpeed = 0.0;
+ this.enableLimit = false;
+ this.enableMotor = false;
+ }
+ b2RevoluteJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+ Box2D.inherit(b2WeldJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2WeldJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2WeldJoint.b2WeldJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchorA = new b2Vec2();
+ this.m_localAnchorB = new b2Vec2();
+ this.m_impulse = new b2Vec3();
+ this.m_mass = new b2Mat33();
+ };
+ b2WeldJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchorA);
+ }
+ b2WeldJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchorB);
+ }
+ b2WeldJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2WeldJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.z;
+ }
+ b2WeldJoint.prototype.b2WeldJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchorA.SetV(def.localAnchorA);
+ this.m_localAnchorB.SetV(def.localAnchorB);
+ this.m_referenceAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_mass = new b2Mat33();
+ }
+ b2WeldJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB;
+ this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB;
+ this.m_mass.col3.x = (-rAY * iA) - rBY * iB;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB;
+ this.m_mass.col3.y = rAX * iA + rBX * iB;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = iA + iB;
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_impulse.z *= step.dtRatio;
+ bA.m_linearVelocity.x -= mA * this.m_impulse.x;
+ bA.m_linearVelocity.y -= mA * this.m_impulse.y;
+ bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z);
+ bB.m_linearVelocity.x += mB * this.m_impulse.x;
+ bB.m_linearVelocity.y += mB * this.m_impulse.y;
+ bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z);
+ }
+ else {
+ this.m_impulse.SetZero();
+ }
+ }
+ b2WeldJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var vA = bA.m_linearVelocity;
+ var wA = bA.m_angularVelocity;
+ var vB = bB.m_linearVelocity;
+ var wB = bB.m_angularVelocity;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY;
+ var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX;
+ var Cdot2 = wB - wA;
+ var impulse = new b2Vec3();
+ this.m_mass.Solve33(impulse, (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ this.m_impulse.Add(impulse);
+ vA.x -= mA * impulse.x;
+ vA.y -= mA * impulse.y;
+ wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z);
+ vB.x += mB * impulse.x;
+ vB.y += mB * impulse.y;
+ wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z);
+ bA.m_angularVelocity = wA;
+ bB.m_angularVelocity = wB;
+ }
+ b2WeldJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX;
+ var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY;
+ var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop;
+ var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y);
+ var angularError = b2Math.Abs(C2);
+ if (positionError > k_allowedStretch) {
+ iA *= 1.0;
+ iB *= 1.0;
+ }
+ this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB;
+ this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB;
+ this.m_mass.col3.x = (-rAY * iA) - rBY * iB;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB;
+ this.m_mass.col3.y = rAX * iA + rBX * iB;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = iA + iB;
+ var impulse = new b2Vec3();
+ this.m_mass.Solve33(impulse, (-C1X), (-C1Y), (-C2));
+ bA.m_sweep.c.x -= mA * impulse.x;
+ bA.m_sweep.c.y -= mA * impulse.y;
+ bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z);
+ bB.m_sweep.c.x += mB * impulse.x;
+ bB.m_sweep.c.y += mB * impulse.y;
+ bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2WeldJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2WeldJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2WeldJointDef.b2WeldJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2WeldJointDef.prototype.b2WeldJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_weldJoint;
+ this.referenceAngle = 0.0;
+ }
+ b2WeldJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor));
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+})();
+(function () {
+ var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
+ b2DebugDraw.b2DebugDraw = function () {
+ this.m_drawScale = 1.0;
+ this.m_lineThickness = 1.0;
+ this.m_alpha = 1.0;
+ this.m_fillAlpha = 1.0;
+ this.m_xformScale = 1.0;
+ var __this = this;
+ //#WORKAROUND
+ this.m_sprite = {
+ graphics: {
+ clear: function () {
+ __this.m_ctx.clearRect(0, 0, __this.m_ctx.canvas.width, __this.m_ctx.canvas.height)
+ }
+ }
+ };
+ };
+ b2DebugDraw.prototype._color = function (color, alpha) {
+ return "rgba(" + ((color & 0xFF0000) >> 16) + "," + ((color & 0xFF00) >> 8) + "," + (color & 0xFF) + "," + alpha + ")";
+ };
+ b2DebugDraw.prototype.b2DebugDraw = function () {
+ this.m_drawFlags = 0;
+ };
+ b2DebugDraw.prototype.SetFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags = flags;
+ };
+ b2DebugDraw.prototype.GetFlags = function () {
+ return this.m_drawFlags;
+ };
+ b2DebugDraw.prototype.AppendFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags |= flags;
+ };
+ b2DebugDraw.prototype.ClearFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags &= ~flags;
+ };
+ b2DebugDraw.prototype.SetSprite = function (sprite) {
+ this.m_ctx = sprite;
+ };
+ b2DebugDraw.prototype.GetSprite = function () {
+ return this.m_ctx;
+ };
+ b2DebugDraw.prototype.SetDrawScale = function (drawScale) {
+ if (drawScale === undefined) drawScale = 0;
+ this.m_drawScale = drawScale;
+ };
+ b2DebugDraw.prototype.GetDrawScale = function () {
+ return this.m_drawScale;
+ };
+ b2DebugDraw.prototype.SetLineThickness = function (lineThickness) {
+ if (lineThickness === undefined) lineThickness = 0;
+ this.m_lineThickness = lineThickness;
+ this.m_ctx.strokeWidth = lineThickness;
+ };
+ b2DebugDraw.prototype.GetLineThickness = function () {
+ return this.m_lineThickness;
+ };
+ b2DebugDraw.prototype.SetAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ this.m_alpha = alpha;
+ };
+ b2DebugDraw.prototype.GetAlpha = function () {
+ return this.m_alpha;
+ };
+ b2DebugDraw.prototype.SetFillAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ this.m_fillAlpha = alpha;
+ };
+ b2DebugDraw.prototype.GetFillAlpha = function () {
+ return this.m_fillAlpha;
+ };
+ b2DebugDraw.prototype.SetXFormScale = function (xformScale) {
+ if (xformScale === undefined) xformScale = 0;
+ this.m_xformScale = xformScale;
+ };
+ b2DebugDraw.prototype.GetXFormScale = function () {
+ return this.m_xformScale;
+ };
+ b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
+ if (!vertexCount) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ for (var i = 1; i < vertexCount; i++) {
+ s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
+ }
+ s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
+ if (!vertexCount) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.fillStyle = this._color(color.color, this.m_fillAlpha);
+ s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ for (var i = 1; i < vertexCount; i++) {
+ s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
+ }
+ s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ s.closePath();
+ s.fill();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawCircle = function (center, radius, color) {
+ if (!radius) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI * 2, true);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
+ if (!radius) return;
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale,
+ cx = center.x * drawScale,
+ cy = center.y * drawScale;
+ s.moveTo(0, 0);
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.fillStyle = this._color(color.color, this.m_fillAlpha);
+ s.arc(cx, cy, radius * drawScale, 0, Math.PI * 2, true);
+ s.moveTo(cx, cy);
+ s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale);
+ s.closePath();
+ s.fill();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale;
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.beginPath();
+ s.moveTo(p1.x * drawScale, p1.y * drawScale);
+ s.lineTo(p2.x * drawScale, p2.y * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawTransform = function (xf) {
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(0xff0000, this.m_alpha);
+ s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
+ s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale);
+
+ s.strokeStyle = this._color(0xff00, this.m_alpha);
+ s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
+ s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+})(); //post-definitions
+var i;
+for (i = 0; i < Box2D.postDefs.length; ++i) Box2D.postDefs[i]();
+delete Box2D.postDefs;
+
+
+ return Box2D;
+});
\ No newline at end of file
diff --git a/lib/Chuck/Chuck.js b/lib/Chuck/Chuck.js
new file mode 100644
index 0000000..f0b8334
--- /dev/null
+++ b/lib/Chuck/Chuck.js
@@ -0,0 +1,13 @@
+define(["Chuck/Processor"], function(Processor){
+ var Chuck = {};
+
+ Chuck.init = function(){
+ var processor = new Processor();
+ }
+
+ Chuck.processRequest = function(package){
+ console.log(package);
+ }
+
+ return Chuck;
+});
\ No newline at end of file
diff --git a/lib/Chuck/Physics/Engine.js b/lib/Chuck/Physics/Engine.js
new file mode 100644
index 0000000..e67ab38
--- /dev/null
+++ b/lib/Chuck/Physics/Engine.js
@@ -0,0 +1,67 @@
+define(["Chuck/Settings", "Box2D/Box2D"], function(Settings, Box2D){
+
+ function Engine () {
+ this._world;
+ this.init();
+ }
+
+ Engine.prototype.init = function() {
+ this._world = new Box2D.Dynamics.b2World(new Box2D.Common.Math.b2Vec2(0, Settings.Box2D_GRAVITY), Settings.Box2D_ALLOW_SLEEP);
+
+ if(Settings.IS_BROWSER_ENVIRONMENT) {
+ this.setupDebugDraw();
+ }
+ }
+
+ Engine.prototype.getWorld = function() {
+ return this._world;
+ }
+
+ Engine.prototype.setCollisionDetector = function(me) {
+ /*
+ var cd = new Chuck.Collision.Detector(me);
+ var listener = cd.getListener();
+ this._world.SetContactListener(listener);*/
+ }
+
+ Engine.prototype.setupDebugDraw = function() {
+ var debugSprite = Settings.DEBUG_DRAW_CANVAS_SPRITE;
+ console.log(debugSprite);
+
+ // set debug draw
+ var dbgDraw = new Box2D.Dynamics.b2DebugDraw();
+
+ dbgDraw.SetSprite(debugSprite);
+ dbgDraw.SetDrawScale(Settings.RATIO);
+ dbgDraw.SetAlpha(0.5);
+ dbgDraw.SetFillAlpha(0.1);
+ dbgDraw.SetLineThickness(0);
+
+ dbgDraw.SetFlags(null
+ | dbgDraw.e_shapeBit
+ //| b2DebugDraw.e_jointBit
+ //| b2DebugDraw.e_coreShapeBit
+ //| b2DebugDraw.e_aabbBit
+ //| b2DebugDraw.e_centerOfMassBit
+ //| b2DebugDraw.e_obbBit
+ //| b2DebugDraw.e_pairBit
+ );
+
+ this._world.SetDebugDraw(dbgDraw);
+
+ this._world.SetWarmStarting(true);
+ console.log('Debug Draw was set up');
+ }
+
+ Engine.prototype.createBody = function(bodyDef) {
+ return this._world.CreateBody(bodyDef);
+ }
+
+ Engine.prototype.update = function() {
+ this._world.Step(Settings.Box2D_TIME_STEP, Settings.Box2D_VELOCITY_ITERATIONS, Settings.Box2D_POSITION_ITERATIONS);
+ this._world.ClearForces();
+ this._world.DrawDebugData();
+ }
+
+ return Engine;
+})
\ No newline at end of file
diff --git a/lib/Chuck/Processor.js b/lib/Chuck/Processor.js
new file mode 100644
index 0000000..b77824f
--- /dev/null
+++ b/lib/Chuck/Processor.js
@@ -0,0 +1,118 @@
+define(["Chuck/Physics/Engine", "Box2D/Box2D"], function(PhysicsEngine, Box2D){
+
+ function Processor () {
+ this._me;
+ this._physicsEngine;
+ this._camera;
+ this._repository;
+ this._inputControlUnit;
+ this._keyboardInput;
+
+ this.init();
+ };
+
+ Processor.prototype.init = function() {
+
+ this._physicsEngine = new PhysicsEngine();
+
+/*
+ var fixDef = new Box2D.Dynamics.b2FixtureDef;
+ fixDef.density = 1.0;
+ fixDef.friction = 0.99;
+ fixDef.restitution = .51;
+
+ var bodyDef = new Box2D.Dynamics.b2BodyDef;
+ bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
+ fixDef.shape = new Box2D.Collision.Shapes.b2PolygonShape;
+ fixDef.shape.SetAsBox(0.4, 0.4);
+
+ this._physicsEngine.createBody(bodyDef).CreateFixture(fixDef);
+ bodyDef.position.x = 2;
+ bodyDef.position.y = 3;
+
+ console.log('bodying');*/
+
+
+ ///------
+
+ var world = this._physicsEngine.getWorld();
+
+ var fixDef = new Box2D.Dynamics.b2FixtureDef;
+ fixDef.density = 1.0;
+ fixDef.friction = 0.99;
+ fixDef.restitution = .51;
+
+ var bodyDef = new Box2D.Dynamics.b2BodyDef;
+
+ // create ground
+ bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody;
+ fixDef.shape = new Box2D.Collision.Shapes.b2PolygonShape;
+ fixDef.shape.SetAsBox(20, 2);
+
+ bodyDef.position.Set(10, 400 / 30 + 1.8);
+
+ world.CreateBody(bodyDef).CreateFixture(fixDef);
+ bodyDef.position.Set(10, -1.8);
+
+ world.CreateBody(bodyDef).CreateFixture(fixDef);
+ fixDef.shape.SetAsBox(2, 14);
+
+ bodyDef.position.Set(-1.8, 13);
+ world.CreateBody(bodyDef).CreateFixture(fixDef);
+
+ bodyDef.position.Set(21.8, 13);
+ world.CreateBody(bodyDef).CreateFixture(fixDef);
+
+ // create some objects
+ bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
+
+ for(var i = 0; i < 5; i++) {
+ fixDef.shape = new Box2D.Collision.Shapes.b2PolygonShape;
+ fixDef.shape.SetAsBox(0.4, 0.4);
+
+ bodyDef.position.x = ((i + 1) * 2) % 8;
+ bodyDef.position.y = 3;
+
+ bodyDef.userData = {
+ 'bodyId': i + ''
+ };
+
+ world.CreateBody(bodyDef).CreateFixture(fixDef);
+ }
+
+ /*
+ this._me = new Chuck.Player(this._physicsEngine, this._repository);
+ //this._camera = Camera.getInstance()
+ //this._repository = Repository.getInstance();
+ this._physicsEngine.setCollisionDetector(this._me);
+ this._keyboardInput = new Chuck.Control.KeyboardInput();
+ this._inputControlUnit = new Chuck.Control.InputControlUnit(this._keyboardInput, this._me);
+
+ new Chuck.Loader.Level(this._physicsEngine);
+ //new Items();
+
+ this._me.spawn(100, 0);
+ //this._camera.follow(this._me);
+*/
+ setInterval(this._update, 1000/60, this);
+ //View.getInstance().getSprite().addEventListener(Event.ENTER_FRAME, this._update)
+ }
+
+ Processor.prototype.getPhysicsEngine = function() {
+ return this._physicsEngine;
+ }
+
+ Processor.prototype.getMe = function() {
+ return this._me;
+ }
+
+ Processor.prototype._update = function(self) {
+ self._physicsEngine.update();
+ //self._repository.update();
+ //self._keyboardInput.update();
+ //self._me.update();
+ //self._camera.update();
+ }
+
+ return Processor;
+});
diff --git a/lib/Chuck/Settings.js b/lib/Chuck/Settings.js
new file mode 100644
index 0000000..7b15e18
--- /dev/null
+++ b/lib/Chuck/Settings.js
@@ -0,0 +1,54 @@
+define(function() {
+
+ var Settings = {
+ STAGE_WIDTH : 600,
+ STAGE_HEIGHT : 400,
+
+ // BOX2D INITIALATORS
+ RATIO : 35,
+ BOX2D_WORLD_AABB_SIZE : 3000,
+ BOX2D_ALLOW_SLEEP : true,
+ BOX2D_GRAVITY : 16,
+ BOX2D_VELOCITY_ITERATIONS : 5,
+ BOX2D_POSITION_ITERATIONS : 5,
+ BOX2D_TIME_STEP : 1 / 30,
+
+ // GRAPHIC PATHS
+ GRAPHICS_PATH : 'img',
+ GRAPHICS_SUBPATH_ITEMS : 'Items',
+ GRAPHICS_SUBPATH_CHARACTERS : 'Characters',
+
+ TILE_SIZE : 15,
+
+ // GAME PLAY
+ WALK_SPEED : 2.5,
+ RUN_SPEED : 4.0,
+ FLY_SPEED : 3.2,
+ JUMP_SPEED : 3.0,
+
+ // restitution : bouncyness, friction : rubbing, density : mass
+ TILE_FRICTION : 0.99,
+ TILE_RESTITUTION : 0.1,
+
+ PLAYER_DENSITY : 0.96,
+ PLAYER_FRICTION : 5,
+ PLAYER_MOTION_FRICTION : 0.1,
+ PLAYER_RESTITUTION : 0.0,
+ PLAYER_LINEAR_DAMPING : .5,
+
+
+ ITEM_DENSITY : 0.9,
+ ITEM_FRICTION : 0.99,
+ ITEM_RESTITUTION : 0.02,
+
+ // debug draw
+ DEBUG_DRAW_CANVAS_SPRITE: isBrowserEnvironment() ? document.getElementById("canvas").getContext("2d") : undefined,
+ IS_BROWSER_ENVIRONMENT: isBrowserEnvironment()
+ };
+
+ function isBrowserEnvironment(){
+ return typeof window !== 'undefined';
+ }
+
+ return Settings;
+})
\ No newline at end of file
diff --git a/node_modules/.bin/r.js b/node_modules/.bin/r.js
new file mode 120000
index 0000000..2075b60
--- /dev/null
+++ b/node_modules/.bin/r.js
@@ -0,0 +1 @@
+../requirejs/bin/r.js
\ No newline at end of file
diff --git a/node_modules/node-static/LICENSE b/node_modules/node-static/LICENSE
new file mode 100644
index 0000000..91f6632
--- /dev/null
+++ b/node_modules/node-static/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Alexis Sellier
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/node-static/README.md b/node_modules/node-static/README.md
new file mode 100644
index 0000000..013bde1
--- /dev/null
+++ b/node_modules/node-static/README.md
@@ -0,0 +1,141 @@
+node-static
+===========
+
+> a simple, *rfc 2616 compliant* file streaming module for [node](http://nodejs.org)
+
+node-static has an in-memory file cache, making it highly efficient.
+node-static understands and supports *conditional GET* and *HEAD* requests.
+node-static was inspired by some of the other static-file serving modules out there,
+such as node-paperboy and antinode.
+
+synopsis
+--------
+
+ var static = require('node-static');
+
+ //
+ // Create a node-static server instance to serve the './public' folder
+ //
+ var file = new(static.Server)('./public');
+
+ require('http').createServer(function (request, response) {
+ request.addListener('end', function () {
+ //
+ // Serve files!
+ //
+ file.serve(request, response);
+ });
+ }).listen(8080);
+
+API
+---
+
+### Creating a node-static Server #
+
+Creating a file server instance is as simple as:
+
+ new static.Server();
+
+This will serve files in the current directory. If you want to serve files in a specific
+directory, pass it as the first argument:
+
+ new static.Server('./public');
+
+You can also specify how long the client is supposed to cache the files node-static serves:
+
+ new static.Server('./public', { cache: 3600 });
+
+This will set the `Cache-Control` header, telling clients to cache the file for an hour.
+This is the default setting.
+
+### Serving files under a directory #
+
+To serve files under a directory, simply call the `serve` method on a `Server` instance, passing it
+the HTTP request and response object:
+
+ var fileServer = new static.Server('./public');
+
+ require('http').createServer(function (request, response) {
+ request.addListener('end', function () {
+ fileServer.serve(request, response);
+ });
+ }).listen(8080);
+
+### Serving specific files #
+
+If you want to serve a specific file, like an error page for example, use the `serveFile` method:
+
+ fileServer.serveFile('/error.html', 500, {}, request, response);
+
+This will serve the `error.html` file, from under the file root directory, with a `500` status code.
+For example, you could serve an error page, when the initial request wasn't found:
+
+ require('http').createServer(function (request, response) {
+ request.addListener('end', function () {
+ fileServer.serve(request, response, function (e, res) {
+ if (e && (e.status === 404)) { // If the file wasn't found
+ fileServer.serveFile('/not-found.html', 404, {}, request, response);
+ }
+ });
+ });
+ }).listen(8080);
+
+More on intercepting errors bellow.
+
+### Intercepting errors & Listening #
+
+An optional callback can be passed as last argument, it will be called every time a file
+has been served successfully, or if there was an error serving the file:
+
+ var fileServer = new static.Server('./public');
+
+ require('http').createServer(function (request, response) {
+ request.addListener('end', function () {
+ fileServer.serve(request, response, function (err, result) {
+ if (err) { // There was an error serving the file
+ sys.error("Error serving " + request.url + " - " + err.message);
+
+ // Respond to the client
+ response.writeHead(err.status, err.headers);
+ response.end();
+ }
+ });
+ });
+ }).listen(8080);
+
+Note that if you pass a callback, and there is an error serving the file, node-static
+*will not* respond to the client. This gives you the opportunity to re-route the request,
+or handle it differently.
+
+For example, you may want to interpret a request as a static request, but if the file isn't found,
+send it to an application.
+
+If you only want to *listen* for errors, you can use *event listeners*:
+
+ fileServer.serve(request, response).addListener('error', function (err) {
+ sys.error("Error serving " + request.url + " - " + err.message);
+ });
+
+With this method, you don't have to explicitly send the response back, in case of an error.
+
+### Options when creating an instance of `Server` #
+
+#### `cache` #
+
+Sets the `Cache-Control` header.
+
+example: `{ cache: 7200 }`
+
+Passing a number will set the cache duration to that number of seconds.
+Passing `false` will disable the `Cache-Control` header.
+
+> Defaults to `3600`
+
+#### `headers` #
+
+Sets response headers.
+
+example: `{ 'X-Hello': 'World!' }`
+
+> defaults to `{}`
+
diff --git a/node_modules/node-static/benchmark/node-static-0.3.0.txt b/node_modules/node-static/benchmark/node-static-0.3.0.txt
new file mode 100644
index 0000000..c6083ea
--- /dev/null
+++ b/node_modules/node-static/benchmark/node-static-0.3.0.txt
@@ -0,0 +1,43 @@
+This is ApacheBench, Version 2.3 <$Revision: 655654 $>
+Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
+Licensed to The Apache Software Foundation, http://www.apache.org/
+
+Benchmarking 127.0.0.1 (be patient)
+
+
+Server Software: node-static/0.3.0
+Server Hostname: 127.0.0.1
+Server Port: 8080
+
+Document Path: /lib/node-static.js
+Document Length: 6038 bytes
+
+Concurrency Level: 20
+Time taken for tests: 2.323 seconds
+Complete requests: 10000
+Failed requests: 0
+Write errors: 0
+Total transferred: 63190000 bytes
+HTML transferred: 60380000 bytes
+Requests per second: 4304.67 [#/sec] (mean)
+Time per request: 4.646 [ms] (mean)
+Time per request: 0.232 [ms] (mean, across all concurrent requests)
+Transfer rate: 26563.66 [Kbytes/sec] received
+
+Connection Times (ms)
+ min mean[+/-sd] median max
+Connect: 0 0 0.2 0 3
+Processing: 1 4 1.4 4 28
+Waiting: 1 4 1.3 4 18
+Total: 2 5 1.5 4 28
+
+Percentage of the requests served within a certain time (ms)
+ 50% 4
+ 66% 5
+ 75% 5
+ 80% 5
+ 90% 5
+ 95% 6
+ 98% 8
+ 99% 9
+ 100% 28 (longest request)
diff --git a/node_modules/node-static/examples/file-server.js b/node_modules/node-static/examples/file-server.js
new file mode 100644
index 0000000..f133b80
--- /dev/null
+++ b/node_modules/node-static/examples/file-server.js
@@ -0,0 +1,25 @@
+var static = require('../lib/node-static');
+
+//
+// Create a node-static server to serve the current directory
+//
+var file = new(static.Server)('.', { cache: 7200, headers: {'X-Hello':'World!'} });
+
+require('http').createServer(function (request, response) {
+ request.addListener('end', function () {
+ //
+ // Serve files!
+ //
+ file.serve(request, response, function (err, res) {
+ if (err) { // An error as occured
+ console.error("> Error serving " + request.url + " - " + err.message);
+ response.writeHead(err.status, err.headers);
+ response.end();
+ } else { // The file was served successfully
+ console.log("> " + request.url + " - " + res.message);
+ }
+ });
+ });
+}).listen(8080);
+
+console.log("> node-static is listening on http://127.0.0.1:8080");
diff --git a/node_modules/node-static/lib/node-static.js b/node_modules/node-static/lib/node-static.js
new file mode 100644
index 0000000..6c668b1
--- /dev/null
+++ b/node_modules/node-static/lib/node-static.js
@@ -0,0 +1,252 @@
+var fs = require('fs'),
+ events = require('events'),
+ buffer = require('buffer'),
+ http = require('http'),
+ url = require('url'),
+ path = require('path');
+
+this.version = [0, 6, 0];
+
+var mime = require('./node-static/mime');
+var util = require('./node-static/util');
+
+var serverInfo = 'node-static/' + this.version.join('.');
+
+// In-memory file store
+this.store = {};
+this.indexStore = {};
+
+this.Server = function (root, options) {
+ if (root && (typeof(root) === 'object')) { options = root, root = null }
+
+ this.root = path.resolve(root || '.');
+ this.options = options || {};
+ this.cache = 3600;
+
+ this.defaultHeaders = {};
+ this.options.headers = this.options.headers || {};
+
+ if ('cache' in this.options) {
+ if (typeof(this.options.cache) === 'number') {
+ this.cache = this.options.cache;
+ } else if (! this.options.cache) {
+ this.cache = false;
+ }
+ }
+
+ if (this.cache !== false) {
+ this.defaultHeaders['Cache-Control'] = 'max-age=' + this.cache;
+ }
+ this.defaultHeaders['Server'] = serverInfo;
+
+ for (var k in this.defaultHeaders) {
+ this.options.headers[k] = this.options.headers[k] ||
+ this.defaultHeaders[k];
+ }
+};
+
+this.Server.prototype.serveDir = function (pathname, req, res, finish) {
+ var htmlIndex = path.join(pathname, 'index.html'),
+ that = this;
+
+ fs.stat(htmlIndex, function (e, stat) {
+ if (!e) {
+ that.respond(null, 200, {}, [htmlIndex], stat, req, res, finish);
+ } else {
+ if (pathname in exports.store) {
+ streamFiles(exports.indexStore[pathname].files);
+ } else {
+ // Stream a directory of files as a single file.
+ fs.readFile(path.join(pathname, 'index.json'), function (e, contents) {
+ if (e) { return finish(404, {}) }
+ var index = JSON.parse(contents);
+ exports.indexStore[pathname] = index;
+ streamFiles(index.files);
+ });
+ }
+ }
+ });
+ function streamFiles(files) {
+ util.mstat(pathname, files, function (e, stat) {
+ that.respond(pathname, 200, {}, files, stat, req, res, finish);
+ });
+ }
+};
+this.Server.prototype.serveFile = function (pathname, status, headers, req, res) {
+ var that = this;
+ var promise = new(events.EventEmitter);
+
+ pathname = this.resolve(pathname);
+
+ fs.stat(pathname, function (e, stat) {
+ if (e) {
+ return promise.emit('error', e);
+ }
+ that.respond(null, status, headers, [pathname], stat, req, res, function (status, headers) {
+ that.finish(status, headers, req, res, promise);
+ });
+ });
+ return promise;
+};
+this.Server.prototype.finish = function (status, headers, req, res, promise, callback) {
+ var result = {
+ status: status,
+ headers: headers,
+ message: http.STATUS_CODES[status]
+ };
+
+ headers['Server'] = serverInfo;
+
+ if (!status || status >= 400) {
+ if (callback) {
+ callback(result);
+ } else {
+ if (promise.listeners('error').length > 0) {
+ promise.emit('error', result);
+ }
+ res.writeHead(status, headers);
+ res.end();
+ }
+ } else {
+ // Don't end the request here, if we're streaming;
+ // it's taken care of in `prototype.stream`.
+ if (status !== 200 || req.method !== 'GET') {
+ res.writeHead(status, headers);
+ res.end();
+ }
+ callback && callback(null, result);
+ promise.emit('success', result);
+ }
+};
+
+this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) {
+ var that = this,
+ promise = new(events.EventEmitter);
+
+ pathname = this.resolve(pathname);
+
+ // Only allow GET and HEAD requests
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
+ finish(405, { 'Allow': 'GET, HEAD' });
+ return promise;
+ }
+
+ // Make sure we're not trying to access a
+ // file outside of the root.
+ if (pathname.indexOf(that.root) === 0) {
+ fs.stat(pathname, function (e, stat) {
+ if (e) {
+ finish(404, {});
+ } else if (stat.isFile()) { // Stream a single file.
+ that.respond(null, status, headers, [pathname], stat, req, res, finish);
+ } else if (stat.isDirectory()) { // Stream a directory of files.
+ that.serveDir(pathname, req, res, finish);
+ } else {
+ finish(400, {});
+ }
+ });
+ } else {
+ // Forbidden
+ finish(403, {});
+ }
+ return promise;
+};
+this.Server.prototype.resolve = function (pathname) {
+ return path.resolve(path.join(this.root, pathname));
+};
+this.Server.prototype.serve = function (req, res, callback) {
+ var that = this,
+ promise = new(events.EventEmitter);
+
+ var pathname = decodeURI(url.parse(req.url).pathname);
+
+ var finish = function (status, headers) {
+ that.finish(status, headers, req, res, promise, callback);
+ };
+
+ process.nextTick(function () {
+ that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) {
+ promise.emit('success', result);
+ }).on('error', function (err) {
+ promise.emit('error');
+ });
+ });
+ if (! callback) { return promise }
+};
+
+this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
+ var mtime = Date.parse(stat.mtime),
+ key = pathname || files[0],
+ headers = {};
+
+ // Copy default headers
+ for (var k in this.options.headers) { headers[k] = this.options.headers[k] }
+
+ headers['Etag'] = JSON.stringify([stat.ino, stat.size, mtime].join('-'));
+ headers['Date'] = new(Date)().toUTCString();
+ headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString();
+
+ // Conditional GET
+ // If the "If-Modified-Since" or "If-None-Match" headers
+ // match the conditions, send a 304 Not Modified.
+ if (req.headers['if-none-match'] === headers['Etag'] ||
+ Date.parse(req.headers['if-modified-since']) >= mtime) {
+ finish(304, headers);
+ } else if (req.method === 'HEAD') {
+ finish(200, headers);
+ } else {
+ var fileExtension = path.extname(files[0]).slice(1).toLowerCase();
+ headers['Content-Length'] = stat.size;
+ headers['Content-Type'] = mime.contentTypes[fileExtension] ||
+ 'application/octet-stream';
+
+ for (var k in _headers) { headers[k] = _headers[k] }
+
+ res.writeHead(status, headers);
+
+ // If the file was cached and it's not older
+ // than what's on disk, serve the cached version.
+ if (this.cache && (key in exports.store) &&
+ exports.store[key].stat.mtime >= stat.mtime) {
+ res.end(exports.store[key].buffer);
+ finish(status, headers);
+ } else {
+ this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
+ if (e) { return finish(500, {}) }
+ exports.store[key] = {
+ stat: stat,
+ buffer: buffer,
+ timestamp: Date.now()
+ };
+ finish(status, headers);
+ });
+ }
+ }
+};
+
+this.Server.prototype.stream = function (pathname, files, buffer, res, callback) {
+ (function streamFile(files, offset) {
+ var file = files.shift();
+
+ if (file) {
+ file = file[0] === '/' ? file : path.join(pathname || '.', file);
+
+ // Stream the file to the client
+ fs.createReadStream(file, {
+ flags: 'r',
+ mode: 0666
+ }).on('data', function (chunk) {
+ chunk.copy(buffer, offset);
+ offset += chunk.length;
+ }).on('close', function () {
+ streamFile(files, offset);
+ }).on('error', function (err) {
+ callback(err);
+ console.error(err);
+ }).pipe(res, { end: false });
+ } else {
+ res.end();
+ callback(null, buffer, offset);
+ }
+ })(files.slice(0), 0);
+};
diff --git a/node_modules/node-static/lib/node-static/mime.js b/node_modules/node-static/lib/node-static/mime.js
new file mode 100644
index 0000000..dc2f79b
--- /dev/null
+++ b/node_modules/node-static/lib/node-static/mime.js
@@ -0,0 +1,140 @@
+this.contentTypes = {
+ "aiff": "audio/x-aiff",
+ "arj": "application/x-arj-compressed",
+ "asf": "video/x-ms-asf",
+ "asx": "video/x-ms-asx",
+ "au": "audio/ulaw",
+ "avi": "video/x-msvideo",
+ "bcpio": "application/x-bcpio",
+ "ccad": "application/clariscad",
+ "cod": "application/vnd.rim.cod",
+ "com": "application/x-msdos-program",
+ "cpio": "application/x-cpio",
+ "cpt": "application/mac-compactpro",
+ "csh": "application/x-csh",
+ "css": "text/css",
+ "deb": "application/x-debian-package",
+ "dl": "video/dl",
+ "doc": "application/msword",
+ "drw": "application/drafting",
+ "dvi": "application/x-dvi",
+ "dwg": "application/acad",
+ "dxf": "application/dxf",
+ "dxr": "application/x-director",
+ "etx": "text/x-setext",
+ "ez": "application/andrew-inset",
+ "fli": "video/x-fli",
+ "flv": "video/x-flv",
+ "gif": "image/gif",
+ "gl": "video/gl",
+ "gtar": "application/x-gtar",
+ "gz": "application/x-gzip",
+ "hdf": "application/x-hdf",
+ "hqx": "application/mac-binhex40",
+ "htm": "text/html",
+ "html": "text/html",
+ "ice": "x-conference/x-cooltalk",
+ "ico": "image/x-icon",
+ "ief": "image/ief",
+ "igs": "model/iges",
+ "ips": "application/x-ipscript",
+ "ipx": "application/x-ipix",
+ "jad": "text/vnd.sun.j2me.app-descriptor",
+ "jar": "application/java-archive",
+ "jpeg": "image/jpeg",
+ "jpg": "image/jpeg",
+ "js": "text/javascript",
+ "json": "application/json",
+ "latex": "application/x-latex",
+ "less": "text/css",
+ "lsp": "application/x-lisp",
+ "lzh": "application/octet-stream",
+ "m": "text/plain",
+ "m3u": "audio/x-mpegurl",
+ "man": "application/x-troff-man",
+ "manifest": "text/cache-manifest",
+ "me": "application/x-troff-me",
+ "midi": "audio/midi",
+ "mif": "application/x-mif",
+ "mime": "www/mime",
+ "movie": "video/x-sgi-movie",
+ "mp4": "video/mp4",
+ "mpg": "video/mpeg",
+ "mpga": "audio/mpeg",
+ "ms": "application/x-troff-ms",
+ "nc": "application/x-netcdf",
+ "oda": "application/oda",
+ "ogm": "application/ogg",
+ "pbm": "image/x-portable-bitmap",
+ "pdf": "application/pdf",
+ "pgm": "image/x-portable-graymap",
+ "pgn": "application/x-chess-pgn",
+ "pgp": "application/pgp",
+ "pm": "application/x-perl",
+ "png": "image/png",
+ "pnm": "image/x-portable-anymap",
+ "ppm": "image/x-portable-pixmap",
+ "ppz": "application/vnd.ms-powerpoint",
+ "pre": "application/x-freelance",
+ "prt": "application/pro_eng",
+ "ps": "application/postscript",
+ "qt": "video/quicktime",
+ "ra": "audio/x-realaudio",
+ "rar": "application/x-rar-compressed",
+ "ras": "image/x-cmu-raster",
+ "rgb": "image/x-rgb",
+ "rm": "audio/x-pn-realaudio",
+ "rpm": "audio/x-pn-realaudio-plugin",
+ "rtf": "text/rtf",
+ "rtx": "text/richtext",
+ "scm": "application/x-lotusscreencam",
+ "set": "application/set",
+ "sgml": "text/sgml",
+ "sh": "application/x-sh",
+ "shar": "application/x-shar",
+ "silo": "model/mesh",
+ "sit": "application/x-stuffit",
+ "skt": "application/x-koan",
+ "smil": "application/smil",
+ "snd": "audio/basic",
+ "sol": "application/solids",
+ "spl": "application/x-futuresplash",
+ "src": "application/x-wais-source",
+ "stl": "application/SLA",
+ "stp": "application/STEP",
+ "sv4cpio": "application/x-sv4cpio",
+ "sv4crc": "application/x-sv4crc",
+ "svg": "image/svg+xml",
+ "swf": "application/x-shockwave-flash",
+ "tar": "application/x-tar",
+ "tcl": "application/x-tcl",
+ "tex": "application/x-tex",
+ "texinfo": "application/x-texinfo",
+ "tgz": "application/x-tar-gz",
+ "tiff": "image/tiff",
+ "tr": "application/x-troff",
+ "tsi": "audio/TSP-audio",
+ "tsp": "application/dsptype",
+ "tsv": "text/tab-separated-values",
+ "txt": "text/plain",
+ "unv": "application/i-deas",
+ "ustar": "application/x-ustar",
+ "vcd": "application/x-cdlink",
+ "vda": "application/vda",
+ "vivo": "video/vnd.vivo",
+ "vrm": "x-world/x-vrml",
+ "wav": "audio/x-wav",
+ "wax": "audio/x-ms-wax",
+ "wma": "audio/x-ms-wma",
+ "wmv": "video/x-ms-wmv",
+ "wmx": "video/x-ms-wmx",
+ "wrl": "model/vrml",
+ "wvx": "video/x-ms-wvx",
+ "xbm": "image/x-xbitmap",
+ "xlw": "application/vnd.ms-excel",
+ "xml": "text/xml",
+ "xpm": "image/x-xpixmap",
+ "xwd": "image/x-xwindowdump",
+ "xyz": "chemical/x-pdb",
+ "zip": "application/zip"
+};
diff --git a/node_modules/node-static/lib/node-static/util.js b/node_modules/node-static/lib/node-static/util.js
new file mode 100644
index 0000000..8dd8e04
--- /dev/null
+++ b/node_modules/node-static/lib/node-static/util.js
@@ -0,0 +1,30 @@
+var fs = require('fs'),
+ path = require('path');
+
+this.mstat = function (dir, files, callback) {
+ (function mstat(files, stats) {
+ var file = files.shift();
+
+ if (file) {
+ fs.stat(path.join(dir, file), function (e, stat) {
+ if (e) {
+ callback(e);
+ } else {
+ mstat(files, stats.concat([stat]));
+ }
+ });
+ } else {
+ callback(null, {
+ size: stats.reduce(function (total, stat) {
+ return total + stat.size;
+ }, 0),
+ mtime: stats.reduce(function (latest, stat) {
+ return latest > stat.mtime ? latest : stat.mtime;
+ }, 0),
+ ino: stats.reduce(function (total, stat) {
+ return total + stat.ino;
+ }, 0)
+ });
+ }
+ })(files.slice(0), []);
+};
diff --git a/node_modules/node-static/package.json b/node_modules/node-static/package.json
new file mode 100644
index 0000000..0835ec0
--- /dev/null
+++ b/node_modules/node-static/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "node-static",
+ "description": "simple, compliant file streaming module for node",
+ "url": "http://github.com/cloudhead/node-static",
+ "keywords": [
+ "http",
+ "static",
+ "file",
+ "server"
+ ],
+ "author": {
+ "name": "Alexis Sellier",
+ "email": "self@cloudhead.net"
+ },
+ "contributors": [
+ {
+ "name": "Pablo Cantero",
+ "email": "pablo@pablocantero.com"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/cloudhead/node-static.git"
+ },
+ "main": "./lib/node-static",
+ "license": "MIT",
+ "dependencies": {},
+ "version": "0.6.0",
+ "engines": {
+ "node": ">= 0.4.1"
+ },
+ "_id": "node-static@0.6.0",
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "_engineSupported": true,
+ "_npmVersion": "1.1.9",
+ "_nodeVersion": "v0.6.13",
+ "_defaultsLoaded": true,
+ "dist": {
+ "shasum": "25024f29b5177b69afdbde315fcebdf9563ce072"
+ },
+ "_from": "node-static@>= 0.6.0"
+}
diff --git a/node_modules/requirejs/.npmignore b/node_modules/requirejs/.npmignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/node_modules/requirejs/.npmignore
@@ -0,0 +1 @@
+README.md
diff --git a/node_modules/requirejs/bin/r.js b/node_modules/requirejs/bin/r.js
new file mode 100755
index 0000000..1047972
--- /dev/null
+++ b/node_modules/requirejs/bin/r.js
@@ -0,0 +1,15472 @@
+#!/usr/bin/env node
+/**
+ * @license r.js 2.0.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*
+ * This is a bootstrap script to allow running RequireJS in the command line
+ * in either a Java/Rhino or Node environment. It is modified by the top-level
+ * dist.js file to inject other files to completely enable this file. It is
+ * the shell of the r.js file.
+ */
+
+/*jslint evil: true, nomen: true, sloppy: true */
+/*global readFile: true, process: false, Packages: false, print: false,
+console: false, java: false, module: false, requirejsVars */
+
+var requirejs, require, define;
+(function (console, args, readFileFunc) {
+
+ var fileName, env, fs, vm, path, exec, rhinoContext, dir, nodeRequire,
+ nodeDefine, exists, reqMain, loadedOptimizedLib, existsForNode,
+ version = '2.0.2',
+ jsSuffixRegExp = /\.js$/,
+ commandOption = '',
+ useLibLoaded = {},
+ //Used by jslib/rhino/args.js
+ rhinoArgs = args,
+ readFile = typeof readFileFunc !== 'undefined' ? readFileFunc : null;
+
+ function showHelp() {
+ console.log('See https://github.com/jrburke/r.js for usage.');
+ }
+
+ if (typeof Packages !== 'undefined') {
+ env = 'rhino';
+
+ fileName = args[0];
+
+ if (fileName && fileName.indexOf('-') === 0) {
+ commandOption = fileName.substring(1);
+ fileName = args[1];
+ }
+
+ //Set up execution context.
+ rhinoContext = Packages.org.mozilla.javascript.ContextFactory.getGlobal().enterContext();
+
+ exec = function (string, name) {
+ return rhinoContext.evaluateString(this, string, name, 0, null);
+ };
+
+ exists = function (fileName) {
+ return (new java.io.File(fileName)).exists();
+ };
+
+ //Define a console.log for easier logging. Don't
+ //get fancy though.
+ if (typeof console === 'undefined') {
+ console = {
+ log: function () {
+ print.apply(undefined, arguments);
+ }
+ };
+ }
+ } else if (typeof process !== 'undefined') {
+ env = 'node';
+
+ //Get the fs module via Node's require before it
+ //gets replaced. Used in require/node.js
+ fs = require('fs');
+ vm = require('vm');
+ path = require('path');
+ //In Node 0.7+ existsSync is on fs.
+ existsForNode = fs.existsSync || path.existsSync;
+
+ nodeRequire = require;
+ nodeDefine = define;
+ reqMain = require.main;
+
+ //Temporarily hide require and define to allow require.js to define
+ //them.
+ require = undefined;
+ define = undefined;
+
+ readFile = function (path) {
+ return fs.readFileSync(path, 'utf8');
+ };
+
+ exec = function (string, name) {
+ return vm.runInThisContext(this.requirejsVars.require.makeNodeWrapper(string),
+ name ? fs.realpathSync(name) : '');
+ };
+
+ exists = function (fileName) {
+ return existsForNode(fileName);
+ };
+
+
+ fileName = process.argv[2];
+
+ if (fileName && fileName.indexOf('-') === 0) {
+ commandOption = fileName.substring(1);
+ fileName = process.argv[3];
+ }
+ }
+
+ /** vim: et:ts=4:sw=4:sts=4
+ * @license RequireJS 2.0.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+/*jslint regexp: true, nomen: true */
+/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
+
+
+(function (global) {
+ 'use strict';
+
+ var version = '2.0.2',
+ commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
+ cjsRequireRegExp = /require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
+ jsSuffixRegExp = /\.js$/,
+ currDirRegExp = /^\.\//,
+ ostring = Object.prototype.toString,
+ ap = Array.prototype,
+ aps = ap.slice,
+ apsp = ap.splice,
+ isBrowser = !!(typeof window !== 'undefined' && navigator && document),
+ isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
+ //PS3 indicates loaded and complete, but need to wait for complete
+ //specifically. Sequence is 'loading', 'loaded', execution,
+ // then 'complete'. The UA check is unfortunate, but not sure how
+ //to feature test w/o causing perf issues.
+ readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
+ /^complete$/ : /^(complete|loaded)$/,
+ defContextName = '_',
+ //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
+ isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
+ contexts = {},
+ cfg = {},
+ globalDefQueue = [],
+ useInteractive = false,
+ req, s, head, baseElement, dataMain, src,
+ interactiveScript, currentlyAddingScript, mainScript, subPath;
+
+ function isFunction(it) {
+ return ostring.call(it) === '[object Function]';
+ }
+
+ function isArray(it) {
+ return ostring.call(it) === '[object Array]';
+ }
+
+ /**
+ * Helper function for iterating over an array. If the func returns
+ * a true value, it will break out of the loop.
+ */
+ function each(ary, func) {
+ if (ary) {
+ var i;
+ for (i = 0; i < ary.length; i += 1) {
+ if (ary[i] && func(ary[i], i, ary)) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper function for iterating over an array backwards. If the func
+ * returns a true value, it will break out of the loop.
+ */
+ function eachReverse(ary, func) {
+ if (ary) {
+ var i;
+ for (i = ary.length - 1; i > -1; i -= 1) {
+ if (ary[i] && func(ary[i], i, ary)) {
+ break;
+ }
+ }
+ }
+ }
+
+ function hasProp(obj, prop) {
+ return obj.hasOwnProperty(prop);
+ }
+
+ /**
+ * Cycles over properties in an object and calls a function for each
+ * property value. If the function returns a truthy value, then the
+ * iteration is stopped.
+ */
+ function eachProp(obj, func) {
+ var prop;
+ for (prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ if (func(obj[prop], prop)) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Simple function to mix in properties from source into target,
+ * but only if target does not already have a property of the same name.
+ * This is not robust in IE for transferring methods that match
+ * Object.prototype names, but the uses of mixin here seem unlikely to
+ * trigger a problem related to that.
+ */
+ function mixin(target, source, force, deepStringMixin) {
+ if (source) {
+ eachProp(source, function (value, prop) {
+ if (force || !hasProp(target, prop)) {
+ if (deepStringMixin && typeof value !== 'string') {
+ if (!target[prop]) {
+ target[prop] = {};
+ }
+ mixin(target[prop], value, force, deepStringMixin);
+ } else {
+ target[prop] = value;
+ }
+ }
+ });
+ }
+ return target;
+ }
+
+ //Similar to Function.prototype.bind, but the 'this' object is specified
+ //first, since it is easier to read/figure out what 'this' will be.
+ function bind(obj, fn) {
+ return function () {
+ return fn.apply(obj, arguments);
+ };
+ }
+
+ function scripts() {
+ return document.getElementsByTagName('script');
+ }
+
+ //Allow getting a global that expressed in
+ //dot notation, like 'a.b.c'.
+ function getGlobal(value) {
+ if (!value) {
+ return value;
+ }
+ var g = global;
+ each(value.split('.'), function (part) {
+ g = g[part];
+ });
+ return g;
+ }
+
+ function makeContextModuleFunc(func, relMap, enableBuildCallback) {
+ return function () {
+ //A version of a require function that passes a moduleName
+ //value for items that may need to
+ //look up paths relative to the moduleName
+ var args = aps.call(arguments, 0), lastArg;
+ if (enableBuildCallback &&
+ isFunction((lastArg = args[args.length - 1]))) {
+ lastArg.__requireJsBuild = true;
+ }
+ args.push(relMap);
+ return func.apply(null, args);
+ };
+ }
+
+ function addRequireMethods(req, context, relMap) {
+ each([
+ ['toUrl'],
+ ['undef'],
+ ['defined', 'requireDefined'],
+ ['specified', 'requireSpecified']
+ ], function (item) {
+ var prop = item[1] || item[0];
+ req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) :
+ //If no context, then use default context. Reference from
+ //contexts instead of early binding to default context, so
+ //that during builds, the latest instance of the default
+ //context with its config gets used.
+ function () {
+ var ctx = contexts[defContextName];
+ return ctx[prop].apply(ctx, arguments);
+ };
+ });
+ }
+
+ /**
+ * Constructs an error with a pointer to an URL with more information.
+ * @param {String} id the error ID that maps to an ID on a web page.
+ * @param {String} message human readable error.
+ * @param {Error} [err] the original error, if there is one.
+ *
+ * @returns {Error}
+ */
+ function makeError(id, msg, err, requireModules) {
+ var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
+ e.requireType = id;
+ e.requireModules = requireModules;
+ if (err) {
+ e.originalError = err;
+ }
+ return e;
+ }
+
+ if (typeof define !== 'undefined') {
+ //If a define is already in play via another AMD loader,
+ //do not overwrite.
+ return;
+ }
+
+ if (typeof requirejs !== 'undefined') {
+ if (isFunction(requirejs)) {
+ //Do not overwrite and existing requirejs instance.
+ return;
+ }
+ cfg = requirejs;
+ requirejs = undefined;
+ }
+
+ //Allow for a require config object
+ if (typeof require !== 'undefined' && !isFunction(require)) {
+ //assume it is a config object.
+ cfg = require;
+ require = undefined;
+ }
+
+ function newContext(contextName) {
+ var config = {
+ waitSeconds: 7,
+ baseUrl: './',
+ paths: {},
+ pkgs: {},
+ shim: {}
+ },
+ registry = {},
+ undefEvents = {},
+ defQueue = [],
+ defined = {},
+ urlFetched = {},
+ requireCounter = 1,
+ unnormalizedCounter = 1,
+ //Used to track the order in which modules
+ //should be executed, by the order they
+ //load. Important for consistent cycle resolution
+ //behavior.
+ waitAry = [],
+ inCheckLoaded, Module, context, handlers,
+ checkLoadedTimeoutId;
+
+ /**
+ * Trims the . and .. from an array of path segments.
+ * It will keep a leading path segment if a .. will become
+ * the first path segment, to help with module name lookups,
+ * which act like paths, but can be remapped. But the end result,
+ * all paths that use this function should look normalized.
+ * NOTE: this method MODIFIES the input array.
+ * @param {Array} ary the array of path segments.
+ */
+ function trimDots(ary) {
+ var i, part;
+ for (i = 0; ary[i]; i+= 1) {
+ part = ary[i];
+ if (part === '.') {
+ ary.splice(i, 1);
+ i -= 1;
+ } else if (part === '..') {
+ if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
+ //End of the line. Keep at least one non-dot
+ //path segment at the front so it can be mapped
+ //correctly to disk. Otherwise, there is likely
+ //no path mapping for a path starting with '..'.
+ //This can still fail, but catches the most reasonable
+ //uses of ..
+ break;
+ } else if (i > 0) {
+ ary.splice(i - 1, 2);
+ i -= 2;
+ }
+ }
+ }
+ }
+
+ /**
+ * Given a relative module name, like ./something, normalize it to
+ * a real name that can be mapped to a path.
+ * @param {String} name the relative name
+ * @param {String} baseName a real name that the name arg is relative
+ * to.
+ * @param {Boolean} applyMap apply the map config to the value. Should
+ * only be done if this normalization is for a dependency ID.
+ * @returns {String} normalized name
+ */
+ function normalize(name, baseName, applyMap) {
+ var baseParts = baseName && baseName.split('/'),
+ map = config.map,
+ starMap = map && map['*'],
+ pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
+ foundMap;
+
+ //Adjust any relative paths.
+ if (name && name.charAt(0) === '.') {
+ //If have a base name, try to normalize against it,
+ //otherwise, assume it is a top-level require that will
+ //be relative to baseUrl in the end.
+ if (baseName) {
+ if (config.pkgs[baseName]) {
+ //If the baseName is a package name, then just treat it as one
+ //name to concat the name with.
+ baseParts = [baseName];
+ } else {
+ //Convert baseName to array, and lop off the last part,
+ //so that . matches that 'directory' and not name of the baseName's
+ //module. For instance, baseName of 'one/two/three', maps to
+ //'one/two/three.js', but we want the directory, 'one/two' for
+ //this normalization.
+ baseParts = baseParts.slice(0, baseParts.length - 1);
+ }
+
+ name = baseParts.concat(name.split('/'));
+ trimDots(name);
+
+ //Some use of packages may use a . path to reference the
+ //'main' module name, so normalize for that.
+ pkgConfig = config.pkgs[(pkgName = name[0])];
+ name = name.join('/');
+ if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
+ name = pkgName;
+ }
+ } else if (name.indexOf('./') === 0) {
+ // No baseName, so this is ID is resolved relative
+ // to baseUrl, pull off the leading dot.
+ name = name.substring(2);
+ }
+ }
+
+ //Apply map config if available.
+ if (applyMap && (baseParts || starMap) && map) {
+ nameParts = name.split('/');
+
+ for (i = nameParts.length; i > 0; i -= 1) {
+ nameSegment = nameParts.slice(0, i).join('/');
+
+ if (baseParts) {
+ //Find the longest baseName segment match in the config.
+ //So, do joins on the biggest to smallest lengths of baseParts.
+ for (j = baseParts.length; j > 0; j -= 1) {
+ mapValue = map[baseParts.slice(0, j).join('/')];
+
+ //baseName segment has config, find if it has one for
+ //this name.
+ if (mapValue) {
+ mapValue = mapValue[nameSegment];
+ if (mapValue) {
+ //Match, update name to the new value.
+ foundMap = mapValue;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!foundMap && starMap && starMap[nameSegment]) {
+ foundMap = starMap[nameSegment];
+ }
+
+ if (foundMap) {
+ nameParts.splice(0, i, foundMap);
+ name = nameParts.join('/');
+ break;
+ }
+ }
+ }
+
+ return name;
+ }
+
+ function removeScript(name) {
+ if (isBrowser) {
+ each(scripts(), function (scriptNode) {
+ if (scriptNode.getAttribute('data-requiremodule') === name &&
+ scriptNode.getAttribute('data-requirecontext') === context.contextName) {
+ scriptNode.parentNode.removeChild(scriptNode);
+ return true;
+ }
+ });
+ }
+ }
+
+ function hasPathFallback(id) {
+ var pathConfig = config.paths[id];
+ if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
+ removeScript(id);
+ //Pop off the first array value, since it failed, and
+ //retry
+ pathConfig.shift();
+ context.undef(id);
+ context.require([id]);
+ return true;
+ }
+ }
+
+ /**
+ * Creates a module mapping that includes plugin prefix, module
+ * name, and path. If parentModuleMap is provided it will
+ * also normalize the name via require.normalize()
+ *
+ * @param {String} name the module name
+ * @param {String} [parentModuleMap] parent module map
+ * for the module name, used to resolve relative names.
+ * @param {Boolean} isNormalized: is the ID already normalized.
+ * This is true if this call is done for a define() module ID.
+ * @param {Boolean} applyMap: apply the map config to the ID.
+ * Should only be true if this map is for a dependency.
+ *
+ * @returns {Object}
+ */
+ function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
+ var index = name ? name.indexOf('!') : -1,
+ prefix = null,
+ parentName = parentModuleMap ? parentModuleMap.name : null,
+ originalName = name,
+ isDefine = true,
+ normalizedName = '',
+ url, pluginModule, suffix;
+
+ //If no name, then it means it is a require call, generate an
+ //internal name.
+ if (!name) {
+ isDefine = false;
+ name = '_@r' + (requireCounter += 1);
+ }
+
+ if (index !== -1) {
+ prefix = name.substring(0, index);
+ name = name.substring(index + 1, name.length);
+ }
+
+ if (prefix) {
+ prefix = normalize(prefix, parentName, applyMap);
+ pluginModule = defined[prefix];
+ }
+
+ //Account for relative paths if there is a base name.
+ if (name) {
+ if (prefix) {
+ if (pluginModule && pluginModule.normalize) {
+ //Plugin is loaded, use its normalize method.
+ normalizedName = pluginModule.normalize(name, function (name) {
+ return normalize(name, parentName, applyMap);
+ });
+ } else {
+ normalizedName = normalize(name, parentName, applyMap);
+ }
+ } else {
+ //A regular module.
+ normalizedName = normalize(name, parentName, applyMap);
+
+ //Calculate url for the module, if it has a name.
+ //Use name here since nameToUrl also calls normalize,
+ //and for relative names that are outside the baseUrl
+ //this causes havoc. Was thinking of just removing
+ //parentModuleMap to avoid extra normalization, but
+ //normalize() still does a dot removal because of
+ //issue #142, so just pass in name here and redo
+ //the normalization. Paths outside baseUrl are just
+ //messy to support.
+ url = context.nameToUrl(name, null, parentModuleMap);
+ }
+ }
+
+ //If the id is a plugin id that cannot be determined if it needs
+ //normalization, stamp it with a unique ID so two matching relative
+ //ids that may conflict can be separate.
+ suffix = prefix && !pluginModule && !isNormalized ?
+ '_unnormalized' + (unnormalizedCounter += 1) :
+ '';
+
+ return {
+ prefix: prefix,
+ name: normalizedName,
+ parentMap: parentModuleMap,
+ unnormalized: !!suffix,
+ url: url,
+ originalName: originalName,
+ isDefine: isDefine,
+ id: (prefix ?
+ prefix + '!' + normalizedName :
+ normalizedName) + suffix
+ };
+ }
+
+ function getModule(depMap) {
+ var id = depMap.id,
+ mod = registry[id];
+
+ if (!mod) {
+ mod = registry[id] = new context.Module(depMap);
+ }
+
+ return mod;
+ }
+
+ function on(depMap, name, fn) {
+ var id = depMap.id,
+ mod = registry[id];
+
+ if (hasProp(defined, id) &&
+ (!mod || mod.defineEmitComplete)) {
+ if (name === 'defined') {
+ fn(defined[id]);
+ }
+ } else {
+ getModule(depMap).on(name, fn);
+ }
+ }
+
+ function onError(err, errback) {
+ var ids = err.requireModules,
+ notified = false;
+
+ if (errback) {
+ errback(err);
+ } else {
+ each(ids, function (id) {
+ var mod = registry[id];
+ if (mod) {
+ //Set error on module, so it skips timeout checks.
+ mod.error = err;
+ if (mod.events.error) {
+ notified = true;
+ mod.emit('error', err);
+ }
+ }
+ });
+
+ if (!notified) {
+ req.onError(err);
+ }
+ }
+ }
+
+ /**
+ * Internal method to transfer globalQueue items to this context's
+ * defQueue.
+ */
+ function takeGlobalQueue() {
+ //Push all the globalDefQueue items into the context's defQueue
+ if (globalDefQueue.length) {
+ //Array splice in the values since the context code has a
+ //local var ref to defQueue, so cannot just reassign the one
+ //on context.
+ apsp.apply(defQueue,
+ [defQueue.length - 1, 0].concat(globalDefQueue));
+ globalDefQueue = [];
+ }
+ }
+
+ /**
+ * Helper function that creates a require function object to give to
+ * modules that ask for it as a dependency. It needs to be specific
+ * per module because of the implication of path mappings that may
+ * need to be relative to the module name.
+ */
+ function makeRequire(mod, enableBuildCallback, altRequire) {
+ var relMap = mod && mod.map,
+ modRequire = makeContextModuleFunc(altRequire || context.require,
+ relMap,
+ enableBuildCallback);
+
+ addRequireMethods(modRequire, context, relMap);
+ modRequire.isBrowser = isBrowser;
+
+ return modRequire;
+ }
+
+ handlers = {
+ 'require': function (mod) {
+ return makeRequire(mod);
+ },
+ 'exports': function (mod) {
+ mod.usingExports = true;
+ if (mod.map.isDefine) {
+ return (mod.exports = defined[mod.map.id] = {});
+ }
+ },
+ 'module': function (mod) {
+ return (mod.module = {
+ id: mod.map.id,
+ uri: mod.map.url,
+ config: function () {
+ return (config.config && config.config[mod.map.id]) || {};
+ },
+ exports: defined[mod.map.id]
+ });
+ }
+ };
+
+ function removeWaiting(id) {
+ //Clean up machinery used for waiting modules.
+ delete registry[id];
+
+ each(waitAry, function (mod, i) {
+ if (mod.map.id === id) {
+ waitAry.splice(i, 1);
+ if (!mod.defined) {
+ context.waitCount -= 1;
+ }
+ return true;
+ }
+ });
+ }
+
+ function findCycle(mod, traced) {
+ var id = mod.map.id,
+ depArray = mod.depMaps,
+ foundModule;
+
+ //Do not bother with unitialized modules or not yet enabled
+ //modules.
+ if (!mod.inited) {
+ return;
+ }
+
+ //Found the cycle.
+ if (traced[id]) {
+ return mod;
+ }
+
+ traced[id] = true;
+
+ //Trace through the dependencies.
+ each(depArray, function (depMap) {
+ var depId = depMap.id,
+ depMod = registry[depId];
+
+ if (!depMod) {
+ return;
+ }
+
+ if (!depMod.inited || !depMod.enabled) {
+ //Dependency is not inited, so this cannot
+ //be used to determine a cycle.
+ foundModule = null;
+ delete traced[id];
+ return true;
+ }
+
+ //mixin traced to a new object for each dependency, so that
+ //sibling dependencies in this object to not generate a
+ //false positive match on a cycle. Ideally an Object.create
+ //type of prototype delegation would be used here, but
+ //optimizing for file size vs. execution speed since hopefully
+ //the trees are small for circular dependency scans relative
+ //to the full app perf.
+ return (foundModule = findCycle(depMod, mixin({}, traced)));
+ });
+
+ return foundModule;
+ }
+
+ function forceExec(mod, traced, uninited) {
+ var id = mod.map.id,
+ depArray = mod.depMaps;
+
+ if (!mod.inited || !mod.map.isDefine) {
+ return;
+ }
+
+ if (traced[id]) {
+ return defined[id];
+ }
+
+ traced[id] = mod;
+
+ each(depArray, function(depMap) {
+ var depId = depMap.id,
+ depMod = registry[depId],
+ value;
+
+ if (handlers[depId]) {
+ return;
+ }
+
+ if (depMod) {
+ if (!depMod.inited || !depMod.enabled) {
+ //Dependency is not inited,
+ //so this module cannot be
+ //given a forced value yet.
+ uninited[id] = true;
+ return;
+ }
+
+ //Get the value for the current dependency
+ value = forceExec(depMod, traced, uninited);
+
+ //Even with forcing it may not be done,
+ //in particular if the module is waiting
+ //on a plugin resource.
+ if (!uninited[depId]) {
+ mod.defineDepById(depId, value);
+ }
+ }
+ });
+
+ mod.check(true);
+
+ return defined[id];
+ }
+
+ function modCheck(mod) {
+ mod.check();
+ }
+
+ function checkLoaded() {
+ var waitInterval = config.waitSeconds * 1000,
+ //It is possible to disable the wait interval by using waitSeconds of 0.
+ expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
+ noLoads = [],
+ stillLoading = false,
+ needCycleCheck = true,
+ map, modId, err, usingPathFallback;
+
+ //Do not bother if this call was a result of a cycle break.
+ if (inCheckLoaded) {
+ return;
+ }
+
+ inCheckLoaded = true;
+
+ //Figure out the state of all the modules.
+ eachProp(registry, function (mod) {
+ map = mod.map;
+ modId = map.id;
+
+ //Skip things that are not enabled or in error state.
+ if (!mod.enabled) {
+ return;
+ }
+
+ if (!mod.error) {
+ //If the module should be executed, and it has not
+ //been inited and time is up, remember it.
+ if (!mod.inited && expired) {
+ if (hasPathFallback(modId)) {
+ usingPathFallback = true;
+ stillLoading = true;
+ } else {
+ noLoads.push(modId);
+ removeScript(modId);
+ }
+ } else if (!mod.inited && mod.fetched && map.isDefine) {
+ stillLoading = true;
+ if (!map.prefix) {
+ //No reason to keep looking for unfinished
+ //loading. If the only stillLoading is a
+ //plugin resource though, keep going,
+ //because it may be that a plugin resource
+ //is waiting on a non-plugin cycle.
+ return (needCycleCheck = false);
+ }
+ }
+ }
+ });
+
+ if (expired && noLoads.length) {
+ //If wait time expired, throw error of unloaded modules.
+ err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
+ err.contextName = context.contextName;
+ return onError(err);
+ }
+
+ //Not expired, check for a cycle.
+ if (needCycleCheck) {
+
+ each(waitAry, function (mod) {
+ if (mod.defined) {
+ return;
+ }
+
+ var cycleMod = findCycle(mod, {}),
+ traced = {};
+
+ if (cycleMod) {
+ forceExec(cycleMod, traced, {});
+
+ //traced modules may have been
+ //removed from the registry, but
+ //their listeners still need to
+ //be called.
+ eachProp(traced, modCheck);
+ }
+ });
+
+ //Now that dependencies have
+ //been satisfied, trigger the
+ //completion check that then
+ //notifies listeners.
+ eachProp(registry, modCheck);
+ }
+
+ //If still waiting on loads, and the waiting load is something
+ //other than a plugin resource, or there are still outstanding
+ //scripts, then just try back later.
+ if ((!expired || usingPathFallback) && stillLoading) {
+ //Something is still waiting to load. Wait for it, but only
+ //if a timeout is not already in effect.
+ if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
+ checkLoadedTimeoutId = setTimeout(function () {
+ checkLoadedTimeoutId = 0;
+ checkLoaded();
+ }, 50);
+ }
+ }
+
+ inCheckLoaded = false;
+ }
+
+ Module = function (map) {
+ this.events = undefEvents[map.id] || {};
+ this.map = map;
+ this.shim = config.shim[map.id];
+ this.depExports = [];
+ this.depMaps = [];
+ this.depMatched = [];
+ this.pluginMaps = {};
+ this.depCount = 0;
+
+ /* this.exports this.factory
+ this.depMaps = [],
+ this.enabled, this.fetched
+ */
+ };
+
+ Module.prototype = {
+ init: function(depMaps, factory, errback, options) {
+ options = options || {};
+
+ //Do not do more inits if already done. Can happen if there
+ //are multiple define calls for the same module. That is not
+ //a normal, common case, but it is also not unexpected.
+ if (this.inited) {
+ return;
+ }
+
+ this.factory = factory;
+
+ if (errback) {
+ //Register for errors on this module.
+ this.on('error', errback);
+ } else if (this.events.error) {
+ //If no errback already, but there are error listeners
+ //on this module, set up an errback to pass to the deps.
+ errback = bind(this, function (err) {
+ this.emit('error', err);
+ });
+ }
+
+ //Do a copy of the dependency array, so that
+ //source inputs are not modified. For example
+ //"shim" deps are passed in here directly, and
+ //doing a direct modification of the depMaps array
+ //would affect that config.
+ this.depMaps = depMaps && depMaps.slice(0);
+ this.depMaps.rjsSkipMap = depMaps.rjsSkipMap;
+
+ this.errback = errback;
+
+ //Indicate this module has be initialized
+ this.inited = true;
+
+ this.ignore = options.ignore;
+
+ //Could have option to init this module in enabled mode,
+ //or could have been previously marked as enabled. However,
+ //the dependencies are not known until init is called. So
+ //if enabled previously, now trigger dependencies as enabled.
+ if (options.enabled || this.enabled) {
+ //Enable this module and dependencies.
+ //Will call this.check()
+ this.enable();
+ } else {
+ this.check();
+ }
+ },
+
+ defineDepById: function (id, depExports) {
+ var i;
+
+ //Find the index for this dependency.
+ each(this.depMaps, function (map, index) {
+ if (map.id === id) {
+ i = index;
+ return true;
+ }
+ });
+
+ return this.defineDep(i, depExports);
+ },
+
+ defineDep: function (i, depExports) {
+ //Because of cycles, defined callback for a given
+ //export can be called more than once.
+ if (!this.depMatched[i]) {
+ this.depMatched[i] = true;
+ this.depCount -= 1;
+ this.depExports[i] = depExports;
+ }
+ },
+
+ fetch: function () {
+ if (this.fetched) {
+ return;
+ }
+ this.fetched = true;
+
+ context.startTime = (new Date()).getTime();
+
+ var map = this.map;
+
+ //If the manager is for a plugin managed resource,
+ //ask the plugin to load it now.
+ if (this.shim) {
+ makeRequire(this, true)(this.shim.deps || [], bind(this, function () {
+ return map.prefix ? this.callPlugin() : this.load();
+ }));
+ } else {
+ //Regular dependency.
+ return map.prefix ? this.callPlugin() : this.load();
+ }
+ },
+
+ load: function() {
+ var url = this.map.url;
+
+ //Regular dependency.
+ if (!urlFetched[url]) {
+ urlFetched[url] = true;
+ context.load(this.map.id, url);
+ }
+ },
+
+ /**
+ * Checks is the module is ready to define itself, and if so,
+ * define it. If the silent argument is true, then it will just
+ * define, but not notify listeners, and not ask for a context-wide
+ * check of all loaded modules. That is useful for cycle breaking.
+ */
+ check: function (silent) {
+ if (!this.enabled || this.enabling) {
+ return;
+ }
+
+ var id = this.map.id,
+ depExports = this.depExports,
+ exports = this.exports,
+ factory = this.factory,
+ err, cjsModule;
+
+ if (!this.inited) {
+ this.fetch();
+ } else if (this.error) {
+ this.emit('error', this.error);
+ } else if (!this.defining) {
+ //The factory could trigger another require call
+ //that would result in checking this module to
+ //define itself again. If already in the process
+ //of doing that, skip this work.
+ this.defining = true;
+
+ if (this.depCount < 1 && !this.defined) {
+ if (isFunction(factory)) {
+ //If there is an error listener, favor passing
+ //to that instead of throwing an error.
+ if (this.events.error) {
+ try {
+ exports = context.execCb(id, factory, depExports, exports);
+ } catch (e) {
+ err = e;
+ }
+ } else {
+ exports = context.execCb(id, factory, depExports, exports);
+ }
+
+ if (this.map.isDefine) {
+ //If setting exports via 'module' is in play,
+ //favor that over return value and exports. After that,
+ //favor a non-undefined return value over exports use.
+ cjsModule = this.module;
+ if (cjsModule &&
+ cjsModule.exports !== undefined &&
+ //Make sure it is not already the exports value
+ cjsModule.exports !== this.exports) {
+ exports = cjsModule.exports;
+ } else if (exports === undefined && this.usingExports) {
+ //exports already set the defined value.
+ exports = this.exports;
+ }
+ }
+
+ if (err) {
+ err.requireMap = this.map;
+ err.requireModules = [this.map.id];
+ err.requireType = 'define';
+ return onError((this.error = err));
+ }
+
+ } else {
+ //Just a literal value
+ exports = factory;
+ }
+
+ this.exports = exports;
+
+ if (this.map.isDefine && !this.ignore) {
+ defined[id] = exports;
+
+ if (req.onResourceLoad) {
+ req.onResourceLoad(context, this.map, this.depMaps);
+ }
+ }
+
+ //Clean up
+ delete registry[id];
+
+ this.defined = true;
+ context.waitCount -= 1;
+ if (context.waitCount === 0) {
+ //Clear the wait array used for cycles.
+ waitAry = [];
+ }
+ }
+
+ //Finished the define stage. Allow calling check again
+ //to allow define notifications below in the case of a
+ //cycle.
+ this.defining = false;
+
+ if (!silent) {
+ if (this.defined && !this.defineEmitted) {
+ this.defineEmitted = true;
+ this.emit('defined', this.exports);
+ this.defineEmitComplete = true;
+ }
+ }
+ }
+ },
+
+ callPlugin: function() {
+ var map = this.map,
+ id = map.id,
+ pluginMap = makeModuleMap(map.prefix, null, false, true);
+
+ on(pluginMap, 'defined', bind(this, function (plugin) {
+ var name = this.map.name,
+ parentName = this.map.parentMap ? this.map.parentMap.name : null,
+ load, normalizedMap, normalizedMod;
+
+ //If current map is not normalized, wait for that
+ //normalized name to load instead of continuing.
+ if (this.map.unnormalized) {
+ //Normalize the ID if the plugin allows it.
+ if (plugin.normalize) {
+ name = plugin.normalize(name, function (name) {
+ return normalize(name, parentName, true);
+ }) || '';
+ }
+
+ normalizedMap = makeModuleMap(map.prefix + '!' + name,
+ this.map.parentMap,
+ false,
+ true);
+ on(normalizedMap,
+ 'defined', bind(this, function (value) {
+ this.init([], function () { return value; }, null, {
+ enabled: true,
+ ignore: true
+ });
+ }));
+ normalizedMod = registry[normalizedMap.id];
+ if (normalizedMod) {
+ if (this.events.error) {
+ normalizedMod.on('error', bind(this, function (err) {
+ this.emit('error', err);
+ }));
+ }
+ normalizedMod.enable();
+ }
+
+ return;
+ }
+
+ load = bind(this, function (value) {
+ this.init([], function () { return value; }, null, {
+ enabled: true
+ });
+ });
+
+ load.error = bind(this, function (err) {
+ this.inited = true;
+ this.error = err;
+ err.requireModules = [id];
+
+ //Remove temp unnormalized modules for this module,
+ //since they will never be resolved otherwise now.
+ eachProp(registry, function (mod) {
+ if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
+ removeWaiting(mod.map.id);
+ }
+ });
+
+ onError(err);
+ });
+
+ //Allow plugins to load other code without having to know the
+ //context or how to 'complete' the load.
+ load.fromText = function (moduleName, text) {
+ /*jslint evil: true */
+ var hasInteractive = useInteractive;
+
+ //Turn off interactive script matching for IE for any define
+ //calls in the text, then turn it back on at the end.
+ if (hasInteractive) {
+ useInteractive = false;
+ }
+
+ //Prime the system by creating a module instance for
+ //it.
+ getModule(makeModuleMap(moduleName));
+
+ req.exec(text);
+
+ if (hasInteractive) {
+ useInteractive = true;
+ }
+
+ //Support anonymous modules.
+ context.completeLoad(moduleName);
+ };
+
+ //Use parentName here since the plugin's name is not reliable,
+ //could be some weird string with no path that actually wants to
+ //reference the parentName's path.
+ plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb) {
+ deps.rjsSkipMap = true;
+ return context.require(deps, cb);
+ }), load, config);
+ }));
+
+ context.enable(pluginMap, this);
+ this.pluginMaps[pluginMap.id] = pluginMap;
+ },
+
+ enable: function () {
+ this.enabled = true;
+
+ if (!this.waitPushed) {
+ waitAry.push(this);
+ context.waitCount += 1;
+ this.waitPushed = true;
+ }
+
+ //Set flag mentioning that the module is enabling,
+ //so that immediate calls to the defined callbacks
+ //for dependencies do not trigger inadvertent load
+ //with the depCount still being zero.
+ this.enabling = true;
+
+ //Enable each dependency
+ each(this.depMaps, bind(this, function (depMap, i) {
+ var id, mod, handler;
+
+ if (typeof depMap === 'string') {
+ //Dependency needs to be converted to a depMap
+ //and wired up to this module.
+ depMap = makeModuleMap(depMap,
+ (this.map.isDefine ? this.map : this.map.parentMap),
+ false,
+ !this.depMaps.rjsSkipMap);
+ this.depMaps[i] = depMap;
+
+ handler = handlers[depMap.id];
+
+ if (handler) {
+ this.depExports[i] = handler(this);
+ return;
+ }
+
+ this.depCount += 1;
+
+ on(depMap, 'defined', bind(this, function (depExports) {
+ this.defineDep(i, depExports);
+ this.check();
+ }));
+
+ if (this.errback) {
+ on(depMap, 'error', this.errback);
+ }
+ }
+
+ id = depMap.id;
+ mod = registry[id];
+
+ //Skip special modules like 'require', 'exports', 'module'
+ //Also, don't call enable if it is already enabled,
+ //important in circular dependency cases.
+ if (!handlers[id] && mod && !mod.enabled) {
+ context.enable(depMap, this);
+ }
+ }));
+
+ //Enable each plugin that is used in
+ //a dependency
+ eachProp(this.pluginMaps, bind(this, function (pluginMap) {
+ var mod = registry[pluginMap.id];
+ if (mod && !mod.enabled) {
+ context.enable(pluginMap, this);
+ }
+ }));
+
+ this.enabling = false;
+
+ this.check();
+ },
+
+ on: function(name, cb) {
+ var cbs = this.events[name];
+ if (!cbs) {
+ cbs = this.events[name] = [];
+ }
+ cbs.push(cb);
+ },
+
+ emit: function (name, evt) {
+ each(this.events[name], function (cb) {
+ cb(evt);
+ });
+ if (name === 'error') {
+ //Now that the error handler was triggered, remove
+ //the listeners, since this broken Module instance
+ //can stay around for a while in the registry/waitAry.
+ delete this.events[name];
+ }
+ }
+ };
+
+ function callGetModule(args) {
+ getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
+ }
+
+ function removeListener(node, func, name, ieName) {
+ //Favor detachEvent because of IE9
+ //issue, see attachEvent/addEventListener comment elsewhere
+ //in this file.
+ if (node.detachEvent && !isOpera) {
+ //Probably IE. If not it will throw an error, which will be
+ //useful to know.
+ if (ieName) {
+ node.detachEvent(ieName, func);
+ }
+ } else {
+ node.removeEventListener(name, func, false);
+ }
+ }
+
+ /**
+ * Given an event from a script node, get the requirejs info from it,
+ * and then removes the event listeners on the node.
+ * @param {Event} evt
+ * @returns {Object}
+ */
+ function getScriptData(evt) {
+ //Using currentTarget instead of target for Firefox 2.0's sake. Not
+ //all old browsers will be supported, but this one was easy enough
+ //to support and still makes sense.
+ var node = evt.currentTarget || evt.srcElement;
+
+ //Remove the listeners once here.
+ removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
+ removeListener(node, context.onScriptError, 'error');
+
+ return {
+ node: node,
+ id: node && node.getAttribute('data-requiremodule')
+ };
+ }
+
+ return (context = {
+ config: config,
+ contextName: contextName,
+ registry: registry,
+ defined: defined,
+ urlFetched: urlFetched,
+ waitCount: 0,
+ defQueue: defQueue,
+ Module: Module,
+ makeModuleMap: makeModuleMap,
+
+ /**
+ * Set a configuration for the context.
+ * @param {Object} cfg config object to integrate.
+ */
+ configure: function (cfg) {
+ //Make sure the baseUrl ends in a slash.
+ if (cfg.baseUrl) {
+ if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
+ cfg.baseUrl += '/';
+ }
+ }
+
+ //Save off the paths and packages since they require special processing,
+ //they are additive.
+ var pkgs = config.pkgs,
+ shim = config.shim,
+ paths = config.paths,
+ map = config.map;
+
+ //Mix in the config values, favoring the new values over
+ //existing ones in context.config.
+ mixin(config, cfg, true);
+
+ //Merge paths.
+ config.paths = mixin(paths, cfg.paths, true);
+
+ //Merge map
+ if (cfg.map) {
+ config.map = mixin(map || {}, cfg.map, true, true);
+ }
+
+ //Merge shim
+ if (cfg.shim) {
+ eachProp(cfg.shim, function (value, id) {
+ //Normalize the structure
+ if (isArray(value)) {
+ value = {
+ deps: value
+ };
+ }
+ if (value.exports && !value.exports.__buildReady) {
+ value.exports = context.makeShimExports(value.exports);
+ }
+ shim[id] = value;
+ });
+ config.shim = shim;
+ }
+
+ //Adjust packages if necessary.
+ if (cfg.packages) {
+ each(cfg.packages, function (pkgObj) {
+ var location;
+
+ pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
+ location = pkgObj.location;
+
+ //Create a brand new object on pkgs, since currentPackages can
+ //be passed in again, and config.pkgs is the internal transformed
+ //state for all package configs.
+ pkgs[pkgObj.name] = {
+ name: pkgObj.name,
+ location: location || pkgObj.name,
+ //Remove leading dot in main, so main paths are normalized,
+ //and remove any trailing .js, since different package
+ //envs have different conventions: some use a module name,
+ //some use a file name.
+ main: (pkgObj.main || 'main')
+ .replace(currDirRegExp, '')
+ .replace(jsSuffixRegExp, '')
+ };
+ });
+
+ //Done with modifications, assing packages back to context config
+ config.pkgs = pkgs;
+ }
+
+ //If there are any "waiting to execute" modules in the registry,
+ //update the maps for them, since their info, like URLs to load,
+ //may have changed.
+ eachProp(registry, function (mod, id) {
+ mod.map = makeModuleMap(id);
+ });
+
+ //If a deps array or a config callback is specified, then call
+ //require with those args. This is useful when require is defined as a
+ //config object before require.js is loaded.
+ if (cfg.deps || cfg.callback) {
+ context.require(cfg.deps || [], cfg.callback);
+ }
+ },
+
+ makeShimExports: function (exports) {
+ var func;
+ if (typeof exports === 'string') {
+ func = function () {
+ return getGlobal(exports);
+ };
+ //Save the exports for use in nodefine checking.
+ func.exports = exports;
+ return func;
+ } else {
+ return function () {
+ return exports.apply(global, arguments);
+ };
+ }
+ },
+
+ requireDefined: function (id, relMap) {
+ return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
+ },
+
+ requireSpecified: function (id, relMap) {
+ id = makeModuleMap(id, relMap, false, true).id;
+ return hasProp(defined, id) || hasProp(registry, id);
+ },
+
+ require: function (deps, callback, errback, relMap) {
+ var moduleName, id, map, requireMod, args;
+ if (typeof deps === 'string') {
+ if (isFunction(callback)) {
+ //Invalid call
+ return onError(makeError('requireargs', 'Invalid require call'), errback);
+ }
+
+ //Synchronous access to one module. If require.get is
+ //available (as in the Node adapter), prefer that.
+ //In this case deps is the moduleName and callback is
+ //the relMap
+ if (req.get) {
+ return req.get(context, deps, callback);
+ }
+
+ //Just return the module wanted. In this scenario, the
+ //second arg (if passed) is just the relMap.
+ moduleName = deps;
+ relMap = callback;
+
+ //Normalize module name, if it contains . or ..
+ map = makeModuleMap(moduleName, relMap, false, true);
+ id = map.id;
+
+ if (!hasProp(defined, id)) {
+ return onError(makeError('notloaded', 'Module name "' +
+ id +
+ '" has not been loaded yet for context: ' +
+ contextName));
+ }
+ return defined[id];
+ }
+
+ //Callback require. Normalize args. if callback or errback is
+ //not a function, it means it is a relMap. Test errback first.
+ if (errback && !isFunction(errback)) {
+ relMap = errback;
+ errback = undefined;
+ }
+ if (callback && !isFunction(callback)) {
+ relMap = callback;
+ callback = undefined;
+ }
+
+ //Any defined modules in the global queue, intake them now.
+ takeGlobalQueue();
+
+ //Make sure any remaining defQueue items get properly processed.
+ while (defQueue.length) {
+ args = defQueue.shift();
+ if (args[0] === null) {
+ return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
+ } else {
+ //args are id, deps, factory. Should be normalized by the
+ //define() function.
+ callGetModule(args);
+ }
+ }
+
+ //Mark all the dependencies as needing to be loaded.
+ requireMod = getModule(makeModuleMap(null, relMap));
+
+ requireMod.init(deps, callback, errback, {
+ enabled: true
+ });
+
+ checkLoaded();
+
+ return context.require;
+ },
+
+ undef: function (id) {
+ var map = makeModuleMap(id, null, true),
+ mod = registry[id];
+
+ delete defined[id];
+ delete urlFetched[map.url];
+ delete undefEvents[id];
+
+ if (mod) {
+ //Hold on to listeners in case the
+ //module will be attempted to be reloaded
+ //using a different config.
+ if (mod.events.defined) {
+ undefEvents[id] = mod.events;
+ }
+
+ removeWaiting(id);
+ }
+ },
+
+ /**
+ * Called to enable a module if it is still in the registry
+ * awaiting enablement. parent module is passed in for context,
+ * used by the optimizer.
+ */
+ enable: function (depMap, parent) {
+ var mod = registry[depMap.id];
+ if (mod) {
+ getModule(depMap).enable();
+ }
+ },
+
+ /**
+ * Internal method used by environment adapters to complete a load event.
+ * A load event could be a script load or just a load pass from a synchronous
+ * load call.
+ * @param {String} moduleName the name of the module to potentially complete.
+ */
+ completeLoad: function (moduleName) {
+ var shim = config.shim[moduleName] || {},
+ shExports = shim.exports && shim.exports.exports,
+ found, args, mod;
+
+ takeGlobalQueue();
+
+ while (defQueue.length) {
+ args = defQueue.shift();
+ if (args[0] === null) {
+ args[0] = moduleName;
+ //If already found an anonymous module and bound it
+ //to this name, then this is some other anon module
+ //waiting for its completeLoad to fire.
+ if (found) {
+ break;
+ }
+ found = true;
+ } else if (args[0] === moduleName) {
+ //Found matching define call for this script!
+ found = true;
+ }
+
+ callGetModule(args);
+ }
+
+ //Do this after the cycle of callGetModule in case the result
+ //of those calls/init calls changes the registry.
+ mod = registry[moduleName];
+
+ if (!found &&
+ !defined[moduleName] &&
+ mod && !mod.inited) {
+ if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
+ if (hasPathFallback(moduleName)) {
+ return;
+ } else {
+ return onError(makeError('nodefine',
+ 'No define call for ' + moduleName,
+ null,
+ [moduleName]));
+ }
+ } else {
+ //A script that does not call define(), so just simulate
+ //the call for it.
+ callGetModule([moduleName, (shim.deps || []), shim.exports]);
+ }
+ }
+
+ checkLoaded();
+ },
+
+ /**
+ * Converts a module name + .extension into an URL path.
+ * *Requires* the use of a module name. It does not support using
+ * plain URLs like nameToUrl.
+ */
+ toUrl: function (moduleNamePlusExt, relModuleMap) {
+ var index = moduleNamePlusExt.lastIndexOf('.'),
+ ext = null;
+
+ if (index !== -1) {
+ ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
+ moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
+ }
+
+ return context.nameToUrl(moduleNamePlusExt, ext, relModuleMap);
+ },
+
+ /**
+ * Converts a module name to a file path. Supports cases where
+ * moduleName may actually be just an URL.
+ */
+ nameToUrl: function (moduleName, ext, relModuleMap) {
+ var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
+ parentPath;
+
+ //Normalize module name if have a base relative module name to work from.
+ moduleName = normalize(moduleName, relModuleMap && relModuleMap.id, true);
+
+ //If a colon is in the URL, it indicates a protocol is used and it is just
+ //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
+ //or ends with .js, then assume the user meant to use an url and not a module id.
+ //The slash is important for protocol-less URLs as well as full paths.
+ if (req.jsExtRegExp.test(moduleName)) {
+ //Just a plain path, not module name lookup, so just return it.
+ //Add extension if it is included. This is a bit wonky, only non-.js things pass
+ //an extension, this method probably needs to be reworked.
+ url = moduleName + (ext || '');
+ } else {
+ //A module that needs to be converted to a path.
+ paths = config.paths;
+ pkgs = config.pkgs;
+
+ syms = moduleName.split('/');
+ //For each module name segment, see if there is a path
+ //registered for it. Start with most specific name
+ //and work up from it.
+ for (i = syms.length; i > 0; i -= 1) {
+ parentModule = syms.slice(0, i).join('/');
+ pkg = pkgs[parentModule];
+ parentPath = paths[parentModule];
+ if (parentPath) {
+ //If an array, it means there are a few choices,
+ //Choose the one that is desired
+ if (isArray(parentPath)) {
+ parentPath = parentPath[0];
+ }
+ syms.splice(0, i, parentPath);
+ break;
+ } else if (pkg) {
+ //If module name is just the package name, then looking
+ //for the main module.
+ if (moduleName === pkg.name) {
+ pkgPath = pkg.location + '/' + pkg.main;
+ } else {
+ pkgPath = pkg.location;
+ }
+ syms.splice(0, i, pkgPath);
+ break;
+ }
+ }
+
+ //Join the path parts together, then figure out if baseUrl is needed.
+ url = syms.join('/') + (ext || '.js');
+ url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
+ }
+
+ return config.urlArgs ? url +
+ ((url.indexOf('?') === -1 ? '?' : '&') +
+ config.urlArgs) : url;
+ },
+
+ //Delegates to req.load. Broken out as a separate function to
+ //allow overriding in the optimizer.
+ load: function (id, url) {
+ req.load(context, id, url);
+ },
+
+ /**
+ * Executes a module callack function. Broken out as a separate function
+ * solely to allow the build system to sequence the files in the built
+ * layer in the right sequence.
+ *
+ * @private
+ */
+ execCb: function (name, callback, args, exports) {
+ return callback.apply(exports, args);
+ },
+
+ /**
+ * callback for script loads, used to check status of loading.
+ *
+ * @param {Event} evt the event from the browser for the script
+ * that was loaded.
+ */
+ onScriptLoad: function (evt) {
+ //Using currentTarget instead of target for Firefox 2.0's sake. Not
+ //all old browsers will be supported, but this one was easy enough
+ //to support and still makes sense.
+ if (evt.type === 'load' ||
+ (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
+ //Reset interactive script so a script node is not held onto for
+ //to long.
+ interactiveScript = null;
+
+ //Pull out the name of the module and the context.
+ var data = getScriptData(evt);
+ context.completeLoad(data.id);
+ }
+ },
+
+ /**
+ * Callback for script errors.
+ */
+ onScriptError: function (evt) {
+ var data = getScriptData(evt);
+ if (!hasPathFallback(data.id)) {
+ return onError(makeError('scripterror', 'Script error', evt, [data.id]));
+ }
+ }
+ });
+ }
+
+ /**
+ * Main entry point.
+ *
+ * If the only argument to require is a string, then the module that
+ * is represented by that string is fetched for the appropriate context.
+ *
+ * If the first argument is an array, then it will be treated as an array
+ * of dependency string names to fetch. An optional function callback can
+ * be specified to execute when all of those dependencies are available.
+ *
+ * Make a local req variable to help Caja compliance (it assumes things
+ * on a require that are not standardized), and to give a short
+ * name for minification/local scope use.
+ */
+ req = requirejs = function (deps, callback, errback, optional) {
+
+ //Find the right context, use default
+ var contextName = defContextName,
+ context, config;
+
+ // Determine if have config object in the call.
+ if (!isArray(deps) && typeof deps !== 'string') {
+ // deps is a config object
+ config = deps;
+ if (isArray(callback)) {
+ // Adjust args if there are dependencies
+ deps = callback;
+ callback = errback;
+ errback = optional;
+ } else {
+ deps = [];
+ }
+ }
+
+ if (config && config.context) {
+ contextName = config.context;
+ }
+
+ context = contexts[contextName];
+ if (!context) {
+ context = contexts[contextName] = req.s.newContext(contextName);
+ }
+
+ if (config) {
+ context.configure(config);
+ }
+
+ return context.require(deps, callback, errback);
+ };
+
+ /**
+ * Support require.config() to make it easier to cooperate with other
+ * AMD loaders on globally agreed names.
+ */
+ req.config = function (config) {
+ return req(config);
+ };
+
+ /**
+ * Export require as a global, but only if it does not already exist.
+ */
+ if (!require) {
+ require = req;
+ }
+
+ req.version = version;
+
+ //Used to filter out dependencies that are already paths.
+ req.jsExtRegExp = /^\/|:|\?|\.js$/;
+ req.isBrowser = isBrowser;
+ s = req.s = {
+ contexts: contexts,
+ newContext: newContext
+ };
+
+ //Create default context.
+ req({});
+
+ //Exports some context-sensitive methods on global require, using
+ //default context if no context specified.
+ addRequireMethods(req);
+
+ if (isBrowser) {
+ head = s.head = document.getElementsByTagName('head')[0];
+ //If BASE tag is in play, using appendChild is a problem for IE6.
+ //When that browser dies, this can be removed. Details in this jQuery bug:
+ //http://dev.jquery.com/ticket/2709
+ baseElement = document.getElementsByTagName('base')[0];
+ if (baseElement) {
+ head = s.head = baseElement.parentNode;
+ }
+ }
+
+ /**
+ * Any errors that require explicitly generates will be passed to this
+ * function. Intercept/override it if you want custom error handling.
+ * @param {Error} err the error object.
+ */
+ req.onError = function (err) {
+ throw err;
+ };
+
+ /**
+ * Does the request to load a module for the browser case.
+ * Make this a separate function to allow other environments
+ * to override it.
+ *
+ * @param {Object} context the require context to find state.
+ * @param {String} moduleName the name of the module.
+ * @param {Object} url the URL to the module.
+ */
+ req.load = function (context, moduleName, url) {
+ var config = (context && context.config) || {},
+ node;
+ if (isBrowser) {
+ //In the browser so use a script tag
+ node = config.xhtml ?
+ document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
+ document.createElement('script');
+ node.type = config.scriptType || 'text/javascript';
+ node.charset = 'utf-8';
+
+ node.setAttribute('data-requirecontext', context.contextName);
+ node.setAttribute('data-requiremodule', moduleName);
+
+ //Set up load listener. Test attachEvent first because IE9 has
+ //a subtle issue in its addEventListener and script onload firings
+ //that do not match the behavior of all other browsers with
+ //addEventListener support, which fire the onload event for a
+ //script right after the script execution. See:
+ //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
+ //UNFORTUNATELY Opera implements attachEvent but does not follow the script
+ //script execution mode.
+ if (node.attachEvent &&
+ //Check if node.attachEvent is artificially added by custom script or
+ //natively supported by browser
+ //read https://github.com/jrburke/requirejs/issues/187
+ //if we can NOT find [native code] then it must NOT natively supported.
+ //in IE8, node.attachEvent does not have toString()
+ //Note the test for "[native code" with no closing brace, see:
+ //https://github.com/jrburke/requirejs/issues/273
+ !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
+ !isOpera) {
+ //Probably IE. IE (at least 6-8) do not fire
+ //script onload right after executing the script, so
+ //we cannot tie the anonymous define call to a name.
+ //However, IE reports the script as being in 'interactive'
+ //readyState at the time of the define call.
+ useInteractive = true;
+
+ node.attachEvent('onreadystatechange', context.onScriptLoad);
+ //It would be great to add an error handler here to catch
+ //404s in IE9+. However, onreadystatechange will fire before
+ //the error handler, so that does not help. If addEvenListener
+ //is used, then IE will fire error before load, but we cannot
+ //use that pathway given the connect.microsoft.com issue
+ //mentioned above about not doing the 'script execute,
+ //then fire the script load event listener before execute
+ //next script' that other browsers do.
+ //Best hope: IE10 fixes the issues,
+ //and then destroys all installs of IE 6-9.
+ //node.attachEvent('onerror', context.onScriptError);
+ } else {
+ node.addEventListener('load', context.onScriptLoad, false);
+ node.addEventListener('error', context.onScriptError, false);
+ }
+ node.src = url;
+
+ //For some cache cases in IE 6-8, the script executes before the end
+ //of the appendChild execution, so to tie an anonymous define
+ //call to the module name (which is stored on the node), hold on
+ //to a reference to this node, but clear after the DOM insertion.
+ currentlyAddingScript = node;
+ if (baseElement) {
+ head.insertBefore(node, baseElement);
+ } else {
+ head.appendChild(node);
+ }
+ currentlyAddingScript = null;
+
+ return node;
+ } else if (isWebWorker) {
+ //In a web worker, use importScripts. This is not a very
+ //efficient use of importScripts, importScripts will block until
+ //its script is downloaded and evaluated. However, if web workers
+ //are in play, the expectation that a build has been done so that
+ //only one script needs to be loaded anyway. This may need to be
+ //reevaluated if other use cases become common.
+ importScripts(url);
+
+ //Account for anonymous modules
+ context.completeLoad(moduleName);
+ }
+ };
+
+ function getInteractiveScript() {
+ if (interactiveScript && interactiveScript.readyState === 'interactive') {
+ return interactiveScript;
+ }
+
+ eachReverse(scripts(), function (script) {
+ if (script.readyState === 'interactive') {
+ return (interactiveScript = script);
+ }
+ });
+ return interactiveScript;
+ }
+
+ //Look for a data-main script attribute, which could also adjust the baseUrl.
+ if (isBrowser) {
+ //Figure out baseUrl. Get it from the script tag with require.js in it.
+ eachReverse(scripts(), function (script) {
+ //Set the 'head' where we can append children by
+ //using the script's parent.
+ if (!head) {
+ head = script.parentNode;
+ }
+
+ //Look for a data-main attribute to set main script for the page
+ //to load. If it is there, the path to data main becomes the
+ //baseUrl, if it is not already set.
+ dataMain = script.getAttribute('data-main');
+ if (dataMain) {
+
+ //Pull off the directory of data-main for use as the
+ //baseUrl.
+ src = dataMain.split('/');
+ mainScript = src.pop();
+ subPath = src.length ? src.join('/') + '/' : './';
+
+ //Set final baseUrl if there is not already an explicit one.
+ if (!cfg.baseUrl) {
+ cfg.baseUrl = subPath;
+ }
+
+ //Strip off any trailing .js since dataMain is now
+ //like a module name.
+ dataMain = mainScript.replace(jsSuffixRegExp, '');
+
+ //Put the data-main script in the files to load.
+ cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
+
+ return true;
+ }
+ });
+ }
+
+ /**
+ * The function that handles definitions of modules. Differs from
+ * require() in that a string for the module should be the first argument,
+ * and the function to execute after dependencies are loaded should
+ * return a value to define the module corresponding to the first argument's
+ * name.
+ */
+ define = function (name, deps, callback) {
+ var node, context;
+
+ //Allow for anonymous functions
+ if (typeof name !== 'string') {
+ //Adjust args appropriately
+ callback = deps;
+ deps = name;
+ name = null;
+ }
+
+ //This module may not have dependencies
+ if (!isArray(deps)) {
+ callback = deps;
+ deps = [];
+ }
+
+ //If no name, and callback is a function, then figure out if it a
+ //CommonJS thing with dependencies.
+ if (!deps.length && isFunction(callback)) {
+ //Remove comments from the callback string,
+ //look for require calls, and pull them into the dependencies,
+ //but only if there are function args.
+ if (callback.length) {
+ callback
+ .toString()
+ .replace(commentRegExp, '')
+ .replace(cjsRequireRegExp, function (match, dep) {
+ deps.push(dep);
+ });
+
+ //May be a CommonJS thing even without require calls, but still
+ //could use exports, and module. Avoid doing exports and module
+ //work though if it just needs require.
+ //REQUIRES the function to expect the CommonJS variables in the
+ //order listed below.
+ deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
+ }
+ }
+
+ //If in IE 6-8 and hit an anonymous define() call, do the interactive
+ //work.
+ if (useInteractive) {
+ node = currentlyAddingScript || getInteractiveScript();
+ if (node) {
+ if (!name) {
+ name = node.getAttribute('data-requiremodule');
+ }
+ context = contexts[node.getAttribute('data-requirecontext')];
+ }
+ }
+
+ //Always save off evaluating the def call until the script onload handler.
+ //This allows multiple modules to be in a file without prematurely
+ //tracing dependencies, and allows for anonymous module support,
+ //where the module name is not known until the script onload event
+ //occurs. If no context, use the global queue, and get it processed
+ //in the onscript load callback.
+ (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
+ };
+
+ define.amd = {
+ jQuery: true
+ };
+
+
+ /**
+ * Executes the text. Normally just uses eval, but can be modified
+ * to use a better, environment-specific call. Only used for transpiling
+ * loader plugins, not for plain JS modules.
+ * @param {String} text the text to execute/evaluate.
+ */
+ req.exec = function (text) {
+ /*jslint evil: true */
+ return eval(text);
+ };
+
+ //Set up with config info.
+ req(cfg);
+}(this));
+
+
+ if (env === 'rhino') {
+ /**
+ * @license RequireJS rhino Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint */
+/*global require: false, java: false, load: false */
+
+(function () {
+ 'use strict';
+ require.load = function (context, moduleName, url) {
+
+ load(url);
+
+ //Support anonymous modules.
+ context.completeLoad(moduleName);
+ };
+
+}());
+ } else if (env === 'node') {
+ this.requirejsVars = {
+ require: require,
+ requirejs: require,
+ define: define,
+ nodeRequire: nodeRequire
+ };
+ require.nodeRequire = nodeRequire;
+
+ /**
+ * @license RequireJS node Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint regexp: false */
+/*global require: false, define: false, requirejsVars: false, process: false */
+
+/**
+ * This adapter assumes that x.js has loaded it and set up
+ * some variables. This adapter just allows limited RequireJS
+ * usage from within the requirejs directory. The general
+ * node adapater is r.js.
+ */
+
+(function () {
+ 'use strict';
+
+ var nodeReq = requirejsVars.nodeRequire,
+ req = requirejsVars.require,
+ def = requirejsVars.define,
+ fs = nodeReq('fs'),
+ path = nodeReq('path'),
+ vm = nodeReq('vm'),
+ //In Node 0.7+ existsSync is on fs.
+ exists = fs.existsSync || path.existsSync;
+
+ //Supply an implementation that allows synchronous get of a module.
+ req.get = function (context, moduleName, relModuleMap) {
+ if (moduleName === "require" || moduleName === "exports" || moduleName === "module") {
+ req.onError(new Error("Explicit require of " + moduleName + " is not allowed."));
+ }
+
+ var ret,
+ moduleMap = context.makeModuleMap(moduleName, relModuleMap);
+
+ //Normalize module name, if it contains . or ..
+ moduleName = moduleMap.id;
+
+ if (context.defined.hasOwnProperty(moduleName)) {
+ ret = context.defined[moduleName];
+ } else {
+ if (ret === undefined) {
+ //Try to dynamically fetch it.
+ req.load(context, moduleName, moduleMap.url);
+ //The above call is sync, so can do the next thing safely.
+ ret = context.defined[moduleName];
+ }
+ }
+
+ return ret;
+ };
+
+ //Add wrapper around the code so that it gets the requirejs
+ //API instead of the Node API, and it is done lexically so
+ //that it survives later execution.
+ req.makeNodeWrapper = function (contents) {
+ return '(function (require, requirejs, define) { ' +
+ contents +
+ '\n}(requirejsVars.require, requirejsVars.requirejs, requirejsVars.define));';
+ };
+
+ req.load = function (context, moduleName, url) {
+ var contents, err;
+
+ if (exists(url)) {
+ contents = fs.readFileSync(url, 'utf8');
+
+ contents = req.makeNodeWrapper(contents);
+ try {
+ vm.runInThisContext(contents, fs.realpathSync(url));
+ } catch (e) {
+ err = new Error('Evaluating ' + url + ' as module "' +
+ moduleName + '" failed with error: ' + e);
+ err.originalError = e;
+ err.moduleName = moduleName;
+ err.fileName = url;
+ return req.onError(err);
+ }
+ } else {
+ def(moduleName, function () {
+ try {
+ return (context.config.nodeRequire || req.nodeRequire)(moduleName);
+ } catch (e) {
+ err = new Error('Calling node\'s require("' +
+ moduleName + '") failed with error: ' + e);
+ err.originalError = e;
+ err.moduleName = moduleName;
+ return req.onError(err);
+ }
+ });
+ }
+
+ //Support anonymous modules.
+ context.completeLoad(moduleName);
+ };
+
+ //Override to provide the function wrapper for define/require.
+ req.exec = function (text) {
+ /*jslint evil: true */
+ text = req.makeNodeWrapper(text);
+ return eval(text);
+ };
+}());
+
+ }
+
+ //Support a default file name to execute. Useful for hosted envs
+ //like Joyent where it defaults to a server.js as the only executed
+ //script. But only do it if this is not an optimization run.
+ if (commandOption !== 'o' && (!fileName || !jsSuffixRegExp.test(fileName))) {
+ fileName = 'main.js';
+ }
+
+ /**
+ * Loads the library files that can be used for the optimizer, or for other
+ * tasks.
+ */
+ function loadLib() {
+ /**
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global Packages: false, process: false, window: false, navigator: false,
+ document: false, define: false */
+
+/**
+ * A plugin that modifies any /env/ path to be the right path based on
+ * the host environment. Right now only works for Node, Rhino and browser.
+ */
+(function () {
+ var pathRegExp = /(\/|^)env\/|\{env\}/,
+ env = 'unknown';
+
+ if (typeof Packages !== 'undefined') {
+ env = 'rhino';
+ } else if (typeof process !== 'undefined') {
+ env = 'node';
+ } else if (typeof window !== "undefined" && navigator && document) {
+ env = 'browser';
+ }
+
+ define('env', {
+ load: function (name, req, load, config) {
+ //Allow override in the config.
+ if (config.env) {
+ env = config.env;
+ }
+
+ name = name.replace(pathRegExp, function (match, prefix) {
+ if (match.indexOf('{') === -1) {
+ return prefix + env + '/';
+ } else {
+ return env;
+ }
+ });
+
+ req([name], function (mod) {
+ load(mod);
+ });
+ }
+ });
+}());
+if(env === 'node') {
+/**
+ * @license RequireJS Copyright (c) 2012, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, load: false */
+
+//Needed so that rhino/assert can return a stub for uglify's consolidator.js
+define('node/assert', ['assert'], function (assert) {
+ return assert;
+});
+
+}
+
+if(env === 'rhino') {
+/**
+ * @license RequireJS Copyright (c) 2012, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, load: false */
+
+//Just a stub for use with uglify's consolidator.js
+define('rhino/assert', function () {
+ return {};
+});
+
+}
+
+if(env === 'node') {
+/**
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, process: false */
+
+define('node/args', function () {
+ //Do not return the "node" or "r.js" arguments
+ var args = process.argv.slice(2);
+
+ //Ignore any command option used for rq.js
+ if (args[0] && args[0].indexOf('-' === 0)) {
+ args = args.slice(1);
+ }
+
+ return args;
+});
+
+}
+
+if(env === 'rhino') {
+/**
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, process: false */
+
+var jsLibRhinoArgs = (typeof rhinoArgs !== 'undefined' && rhinoArgs) || [].concat(Array.prototype.slice.call(arguments, 0));
+
+define('rhino/args', function () {
+ var args = jsLibRhinoArgs;
+
+ //Ignore any command option used for rq.js
+ if (args[0] && args[0].indexOf('-' === 0)) {
+ args = args.slice(1);
+ }
+
+ return args;
+});
+
+}
+
+if(env === 'node') {
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, console: false */
+
+define('node/load', ['fs'], function (fs) {
+ function load(fileName) {
+ var contents = fs.readFileSync(fileName, 'utf8');
+ process.compile(contents, fileName);
+ }
+
+ return load;
+});
+
+}
+
+if(env === 'rhino') {
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, load: false */
+
+define('rhino/load', function () {
+ return load;
+});
+
+}
+
+if(env === 'node') {
+/**
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint plusplus: false, octal:false, strict: false */
+/*global define: false, process: false */
+
+define('node/file', ['fs', 'path'], function (fs, path) {
+
+ var isWindows = process.platform === 'win32',
+ windowsDriveRegExp = /^[a-zA-Z]\:\/$/,
+ file;
+
+ function frontSlash(path) {
+ return path.replace(/\\/g, '/');
+ }
+
+ function exists(path) {
+ if (isWindows && path.charAt(path.length - 1) === '/' &&
+ path.charAt(path.length - 2) !== ':') {
+ path = path.substring(0, path.length - 1);
+ }
+
+ try {
+ fs.statSync(path);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function mkDir(dir) {
+ if (!exists(dir) && (!isWindows || !windowsDriveRegExp.test(dir))) {
+ fs.mkdirSync(dir, 511);
+ }
+ }
+
+ function mkFullDir(dir) {
+ var parts = dir.split('/'),
+ currDir = '',
+ first = true;
+
+ parts.forEach(function (part) {
+ //First part may be empty string if path starts with a slash.
+ currDir += part + '/';
+ first = false;
+
+ if (part) {
+ mkDir(currDir);
+ }
+ });
+ }
+
+ file = {
+ backSlashRegExp: /\\/g,
+ exclusionRegExp: /^\./,
+ getLineSeparator: function () {
+ return '/';
+ },
+
+ exists: function (fileName) {
+ return exists(fileName);
+ },
+
+ parent: function (fileName) {
+ var parts = fileName.split('/');
+ parts.pop();
+ return parts.join('/');
+ },
+
+ /**
+ * Gets the absolute file path as a string, normalized
+ * to using front slashes for path separators.
+ * @param {String} fileName
+ */
+ absPath: function (fileName) {
+ return frontSlash(path.normalize(frontSlash(fs.realpathSync(fileName))));
+ },
+
+ normalize: function (fileName) {
+ return frontSlash(path.normalize(fileName));
+ },
+
+ isFile: function (path) {
+ return fs.statSync(path).isFile();
+ },
+
+ isDirectory: function (path) {
+ return fs.statSync(path).isDirectory();
+ },
+
+ getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths) {
+ //summary: Recurses startDir and finds matches to the files that match regExpFilters.include
+ //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
+ //and it will be treated as the "include" case.
+ //Ignores files/directories that start with a period (.) unless exclusionRegExp
+ //is set to another value.
+ var files = [], topDir, regExpInclude, regExpExclude, dirFileArray,
+ i, stat, filePath, ok, dirFiles, fileName;
+
+ topDir = startDir;
+
+ regExpInclude = regExpFilters.include || regExpFilters;
+ regExpExclude = regExpFilters.exclude || null;
+
+ if (file.exists(topDir)) {
+ dirFileArray = fs.readdirSync(topDir);
+ for (i = 0; i < dirFileArray.length; i++) {
+ fileName = dirFileArray[i];
+ filePath = path.join(topDir, fileName);
+ stat = fs.statSync(filePath);
+ if (stat.isFile()) {
+ if (makeUnixPaths) {
+ //Make sure we have a JS string.
+ if (filePath.indexOf("/") === -1) {
+ filePath = frontSlash(filePath);
+ }
+ }
+
+ ok = true;
+ if (regExpInclude) {
+ ok = filePath.match(regExpInclude);
+ }
+ if (ok && regExpExclude) {
+ ok = !filePath.match(regExpExclude);
+ }
+
+ if (ok && (!file.exclusionRegExp ||
+ !file.exclusionRegExp.test(fileName))) {
+ files.push(filePath);
+ }
+ } else if (stat.isDirectory() &&
+ (!file.exclusionRegExp || !file.exclusionRegExp.test(fileName))) {
+ dirFiles = this.getFilteredFileList(filePath, regExpFilters, makeUnixPaths);
+ files.push.apply(files, dirFiles);
+ }
+ }
+ }
+
+ return files; //Array
+ },
+
+ copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) {
+ //summary: copies files from srcDir to destDir using the regExpFilter to determine if the
+ //file should be copied. Returns a list file name strings of the destinations that were copied.
+ regExpFilter = regExpFilter || /\w/;
+
+ //Normalize th directory names, but keep front slashes.
+ //path module on windows now returns backslashed paths.
+ srcDir = frontSlash(path.normalize(srcDir));
+ destDir = frontSlash(path.normalize(destDir));
+
+ var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true),
+ copiedFiles = [], i, srcFileName, destFileName;
+
+ for (i = 0; i < fileNames.length; i++) {
+ srcFileName = fileNames[i];
+ destFileName = srcFileName.replace(srcDir, destDir);
+
+ if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) {
+ copiedFiles.push(destFileName);
+ }
+ }
+
+ return copiedFiles.length ? copiedFiles : null; //Array or null
+ },
+
+ copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) {
+ //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
+ //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
+ var parentDir;
+
+ //logger.trace("Src filename: " + srcFileName);
+ //logger.trace("Dest filename: " + destFileName);
+
+ //If onlyCopyNew is true, then compare dates and only copy if the src is newer
+ //than dest.
+ if (onlyCopyNew) {
+ if (file.exists(destFileName) && fs.statSync(destFileName).mtime.getTime() >= fs.statSync(srcFileName).mtime.getTime()) {
+ return false; //Boolean
+ }
+ }
+
+ //Make sure destination dir exists.
+ parentDir = path.dirname(destFileName);
+ if (!file.exists(parentDir)) {
+ mkFullDir(parentDir);
+ }
+
+ fs.writeFileSync(destFileName, fs.readFileSync(srcFileName, 'binary'), 'binary');
+
+ return true; //Boolean
+ },
+
+ /**
+ * Renames a file. May fail if "to" already exists or is on another drive.
+ */
+ renameFile: function (from, to) {
+ return fs.renameSync(from, to);
+ },
+
+ /**
+ * Reads a *text* file.
+ */
+ readFile: function (/*String*/path, /*String?*/encoding) {
+ if (encoding === 'utf-8') {
+ encoding = 'utf8';
+ }
+ if (!encoding) {
+ encoding = 'utf8';
+ }
+
+ var text = fs.readFileSync(path, encoding);
+
+ //Hmm, would not expect to get A BOM, but it seems to happen,
+ //remove it just in case.
+ if (text.indexOf('\uFEFF') === 0) {
+ text = text.substring(1, text.length);
+ }
+
+ return text;
+ },
+
+ saveUtf8File: function (/*String*/fileName, /*String*/fileContents) {
+ //summary: saves a *text* file using UTF-8 encoding.
+ file.saveFile(fileName, fileContents, "utf8");
+ },
+
+ saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) {
+ //summary: saves a *text* file.
+ var parentDir;
+
+ if (encoding === 'utf-8') {
+ encoding = 'utf8';
+ }
+ if (!encoding) {
+ encoding = 'utf8';
+ }
+
+ //Make sure destination directories exist.
+ parentDir = path.dirname(fileName);
+ if (!file.exists(parentDir)) {
+ mkFullDir(parentDir);
+ }
+
+ fs.writeFileSync(fileName, fileContents, encoding);
+ },
+
+ deleteFile: function (/*String*/fileName) {
+ //summary: deletes a file or directory if it exists.
+ var files, i, stat;
+ if (file.exists(fileName)) {
+ stat = fs.statSync(fileName);
+ if (stat.isDirectory()) {
+ files = fs.readdirSync(fileName);
+ for (i = 0; i < files.length; i++) {
+ this.deleteFile(path.join(fileName, files[i]));
+ }
+ fs.rmdirSync(fileName);
+ } else {
+ fs.unlinkSync(fileName);
+ }
+ }
+ }
+ };
+
+ return file;
+
+});
+
+}
+
+if(env === 'rhino') {
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+//Helper functions to deal with file I/O.
+
+/*jslint plusplus: false, strict: false */
+/*global java: false, define: false */
+
+define('rhino/file', function () {
+ var file = {
+ backSlashRegExp: /\\/g,
+
+ exclusionRegExp: /^\./,
+
+ getLineSeparator: function () {
+ return file.lineSeparator;
+ },
+
+ lineSeparator: java.lang.System.getProperty("line.separator"), //Java String
+
+ exists: function (fileName) {
+ return (new java.io.File(fileName)).exists();
+ },
+
+ parent: function (fileName) {
+ return file.absPath((new java.io.File(fileName)).getParentFile());
+ },
+
+ normalize: function (fileName) {
+ return file.absPath(fileName);
+ },
+
+ isFile: function (path) {
+ return (new java.io.File(path)).isFile();
+ },
+
+ isDirectory: function (path) {
+ return (new java.io.File(path)).isDirectory();
+ },
+
+ /**
+ * Gets the absolute file path as a string, normalized
+ * to using front slashes for path separators.
+ * @param {java.io.File||String} file
+ */
+ absPath: function (fileObj) {
+ if (typeof fileObj === "string") {
+ fileObj = new java.io.File(fileObj);
+ }
+ return (fileObj.getCanonicalPath() + "").replace(file.backSlashRegExp, "/");
+ },
+
+ getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject) {
+ //summary: Recurses startDir and finds matches to the files that match regExpFilters.include
+ //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
+ //and it will be treated as the "include" case.
+ //Ignores files/directories that start with a period (.) unless exclusionRegExp
+ //is set to another value.
+ var files = [], topDir, regExpInclude, regExpExclude, dirFileArray,
+ i, fileObj, filePath, ok, dirFiles;
+
+ topDir = startDir;
+ if (!startDirIsJavaObject) {
+ topDir = new java.io.File(startDir);
+ }
+
+ regExpInclude = regExpFilters.include || regExpFilters;
+ regExpExclude = regExpFilters.exclude || null;
+
+ if (topDir.exists()) {
+ dirFileArray = topDir.listFiles();
+ for (i = 0; i < dirFileArray.length; i++) {
+ fileObj = dirFileArray[i];
+ if (fileObj.isFile()) {
+ filePath = fileObj.getPath();
+ if (makeUnixPaths) {
+ //Make sure we have a JS string.
+ filePath = String(filePath);
+ if (filePath.indexOf("/") === -1) {
+ filePath = filePath.replace(/\\/g, "/");
+ }
+ }
+
+ ok = true;
+ if (regExpInclude) {
+ ok = filePath.match(regExpInclude);
+ }
+ if (ok && regExpExclude) {
+ ok = !filePath.match(regExpExclude);
+ }
+
+ if (ok && (!file.exclusionRegExp ||
+ !file.exclusionRegExp.test(fileObj.getName()))) {
+ files.push(filePath);
+ }
+ } else if (fileObj.isDirectory() &&
+ (!file.exclusionRegExp || !file.exclusionRegExp.test(fileObj.getName()))) {
+ dirFiles = this.getFilteredFileList(fileObj, regExpFilters, makeUnixPaths, true);
+ files.push.apply(files, dirFiles);
+ }
+ }
+ }
+
+ return files; //Array
+ },
+
+ copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) {
+ //summary: copies files from srcDir to destDir using the regExpFilter to determine if the
+ //file should be copied. Returns a list file name strings of the destinations that were copied.
+ regExpFilter = regExpFilter || /\w/;
+
+ var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true),
+ copiedFiles = [], i, srcFileName, destFileName;
+
+ for (i = 0; i < fileNames.length; i++) {
+ srcFileName = fileNames[i];
+ destFileName = srcFileName.replace(srcDir, destDir);
+
+ if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) {
+ copiedFiles.push(destFileName);
+ }
+ }
+
+ return copiedFiles.length ? copiedFiles : null; //Array or null
+ },
+
+ copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) {
+ //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
+ //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
+ var destFile = new java.io.File(destFileName), srcFile, parentDir,
+ srcChannel, destChannel;
+
+ //logger.trace("Src filename: " + srcFileName);
+ //logger.trace("Dest filename: " + destFileName);
+
+ //If onlyCopyNew is true, then compare dates and only copy if the src is newer
+ //than dest.
+ if (onlyCopyNew) {
+ srcFile = new java.io.File(srcFileName);
+ if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified()) {
+ return false; //Boolean
+ }
+ }
+
+ //Make sure destination dir exists.
+ parentDir = destFile.getParentFile();
+ if (!parentDir.exists()) {
+ if (!parentDir.mkdirs()) {
+ throw "Could not create directory: " + parentDir.getCanonicalPath();
+ }
+ }
+
+ //Java's version of copy file.
+ srcChannel = new java.io.FileInputStream(srcFileName).getChannel();
+ destChannel = new java.io.FileOutputStream(destFileName).getChannel();
+ destChannel.transferFrom(srcChannel, 0, srcChannel.size());
+ srcChannel.close();
+ destChannel.close();
+
+ return true; //Boolean
+ },
+
+ /**
+ * Renames a file. May fail if "to" already exists or is on another drive.
+ */
+ renameFile: function (from, to) {
+ return (new java.io.File(from)).renameTo((new java.io.File(to)));
+ },
+
+ readFile: function (/*String*/path, /*String?*/encoding) {
+ //A file read function that can deal with BOMs
+ encoding = encoding || "utf-8";
+ var fileObj = new java.io.File(path),
+ input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(fileObj), encoding)),
+ stringBuffer, line;
+ try {
+ stringBuffer = new java.lang.StringBuffer();
+ line = input.readLine();
+
+ // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
+ // http://www.unicode.org/faq/utf_bom.html
+
+ // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
+ if (line && line.length() && line.charAt(0) === 0xfeff) {
+ // Eat the BOM, since we've already found the encoding on this file,
+ // and we plan to concatenating this buffer with others; the BOM should
+ // only appear at the top of a file.
+ line = line.substring(1);
+ }
+ while (line !== null) {
+ stringBuffer.append(line);
+ stringBuffer.append(file.lineSeparator);
+ line = input.readLine();
+ }
+ //Make sure we return a JavaScript string and not a Java string.
+ return String(stringBuffer.toString()); //String
+ } finally {
+ input.close();
+ }
+ },
+
+ saveUtf8File: function (/*String*/fileName, /*String*/fileContents) {
+ //summary: saves a file using UTF-8 encoding.
+ file.saveFile(fileName, fileContents, "utf-8");
+ },
+
+ saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) {
+ //summary: saves a file.
+ var outFile = new java.io.File(fileName), outWriter, parentDir, os;
+
+ parentDir = outFile.getAbsoluteFile().getParentFile();
+ if (!parentDir.exists()) {
+ if (!parentDir.mkdirs()) {
+ throw "Could not create directory: " + parentDir.getAbsolutePath();
+ }
+ }
+
+ if (encoding) {
+ outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding);
+ } else {
+ outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile));
+ }
+
+ os = new java.io.BufferedWriter(outWriter);
+ try {
+ os.write(fileContents);
+ } finally {
+ os.close();
+ }
+ },
+
+ deleteFile: function (/*String*/fileName) {
+ //summary: deletes a file or directory if it exists.
+ var fileObj = new java.io.File(fileName), files, i;
+ if (fileObj.exists()) {
+ if (fileObj.isDirectory()) {
+ files = fileObj.listFiles();
+ for (i = 0; i < files.length; i++) {
+ this.deleteFile(files[i]);
+ }
+ }
+ fileObj["delete"]();
+ }
+ }
+ };
+
+ return file;
+});
+
+}
+
+if(env === 'node') {
+/*global process */
+define('node/quit', function () {
+ 'use strict';
+ return function (code) {
+ return process.exit(code);
+ };
+});
+}
+
+if(env === 'rhino') {
+/*global quit */
+define('rhino/quit', function () {
+ 'use strict';
+ return function (code) {
+ return quit(code);
+ };
+});
+
+}
+/**
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint plusplus: true */
+/*global define */
+
+define('lang', function () {
+ 'use strict';
+
+ var lang = {
+ backSlashRegExp: /\\/g,
+ ostring: Object.prototype.toString,
+
+ isArray: Array.isArray || function (it) {
+ return lang.ostring.call(it) === "[object Array]";
+ },
+
+ isFunction: function(it) {
+ return lang.ostring.call(it) === "[object Function]";
+ },
+
+ isRegExp: function(it) {
+ return it && it instanceof RegExp;
+ },
+
+ _mixin: function(dest, source, override){
+ var name;
+ for (name in source) {
+ if(source.hasOwnProperty(name)
+ && (override || !dest.hasOwnProperty(name))) {
+ dest[name] = source[name];
+ }
+ }
+
+ return dest; // Object
+ },
+
+ /**
+ * mixin({}, obj1, obj2) is allowed. If the last argument is a boolean,
+ * then the source objects properties are force copied over to dest.
+ */
+ mixin: function(dest){
+ var parameters = Array.prototype.slice.call(arguments),
+ override, i, l;
+
+ if (!dest) { dest = {}; }
+
+ if (parameters.length > 2 && typeof arguments[parameters.length-1] === 'boolean') {
+ override = parameters.pop();
+ }
+
+ for (i = 1, l = parameters.length; i < l; i++) {
+ lang._mixin(dest, parameters[i], override);
+ }
+ return dest; // Object
+ },
+
+ delegate: (function () {
+ // boodman/crockford delegation w/ cornford optimization
+ function TMP() {}
+ return function (obj, props) {
+ TMP.prototype = obj;
+ var tmp = new TMP();
+ TMP.prototype = null;
+ if (props) {
+ lang.mixin(tmp, props);
+ }
+ return tmp; // Object
+ };
+ }()),
+
+ /**
+ * Helper function for iterating over an array. If the func returns
+ * a true value, it will break out of the loop.
+ */
+ each: function each(ary, func) {
+ if (ary) {
+ var i;
+ for (i = 0; i < ary.length; i += 1) {
+ if (func(ary[i], i, ary)) {
+ break;
+ }
+ }
+ }
+ },
+
+ /**
+ * Cycles over properties in an object and calls a function for each
+ * property value. If the function returns a truthy value, then the
+ * iteration is stopped.
+ */
+ eachProp: function eachProp(obj, func) {
+ var prop;
+ for (prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ if (func(obj[prop], prop)) {
+ break;
+ }
+ }
+ }
+ },
+
+ //Similar to Function.prototype.bind, but the "this" object is specified
+ //first, since it is easier to read/figure out what "this" will be.
+ bind: function bind(obj, fn) {
+ return function () {
+ return fn.apply(obj, arguments);
+ };
+ },
+
+ //Escapes a content string to be be a string that has characters escaped
+ //for inclusion as part of a JS string.
+ jsEscape: function (content) {
+ return content.replace(/(["'\\])/g, '\\$1')
+ .replace(/[\f]/g, "\\f")
+ .replace(/[\b]/g, "\\b")
+ .replace(/[\n]/g, "\\n")
+ .replace(/[\t]/g, "\\t")
+ .replace(/[\r]/g, "\\r");
+ }
+ };
+ return lang;
+});
+
+if(env === 'node') {
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, console: false */
+
+define('node/print', function () {
+ function print(msg) {
+ console.log(msg);
+ }
+
+ return print;
+});
+
+}
+
+if(env === 'rhino') {
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint strict: false */
+/*global define: false, print: false */
+
+define('rhino/print', function () {
+ return print;
+});
+
+}
+/**
+ * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+
+/*jslint nomen: false, strict: false */
+/*global define: false */
+
+define('logger', ['env!env/print'], function (print) {
+ var logger = {
+ TRACE: 0,
+ INFO: 1,
+ WARN: 2,
+ ERROR: 3,
+ SILENT: 4,
+ level: 0,
+ logPrefix: "",
+
+ logLevel: function( level ) {
+ this.level = level;
+ },
+
+ trace: function (message) {
+ if (this.level <= this.TRACE) {
+ this._print(message);
+ }
+ },
+
+ info: function (message) {
+ if (this.level <= this.INFO) {
+ this._print(message);
+ }
+ },
+
+ warn: function (message) {
+ if (this.level <= this.WARN) {
+ this._print(message);
+ }
+ },
+
+ error: function (message) {
+ if (this.level <= this.ERROR) {
+ this._print(message);
+ }
+ },
+
+ _print: function (message) {
+ this._sysPrint((this.logPrefix ? (this.logPrefix + " ") : "") + message);
+ },
+
+ _sysPrint: function (message) {
+ print(message);
+ }
+ };
+
+ return logger;
+});
+//Just a blank file to use when building the optimizer with the optimizer,
+//so that the build does not attempt to inline some env modules,
+//like Node's fs and path.
+
+//Just a blank file to use when building the optimizer with the optimizer,
+//so that the build does not attempt to inline some env modules,
+//like Node's fs and path.
+
+//Commit d72ed0a000c455290fde6f8114fe38f4aaf31469 on May 15, 2012
+define('esprima', ['exports'], function(exports) {
+/*
+ Copyright (C) 2012 Ariya Hidayat
+ Copyright (C) 2012 Mathias Bynens
+ Copyright (C) 2012 Joost-Wim Boekesteijn
+ Copyright (C) 2012 Kris Kowal
+ Copyright (C) 2012 Yusuke Suzuki
+ Copyright (C) 2012 Arpad Borsos
+ Copyright (C) 2011 Ariya Hidayat
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*jslint bitwise:true plusplus:true */
+/*global esprima:true, exports:true,
+throwError: true, createLiteral: true, generateStatement: true,
+parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
+parseFunctionDeclaration: true, parseFunctionExpression: true,
+parseFunctionSourceElements: true, parseVariableIdentifier: true,
+parseLeftHandSideExpression: true,
+parseStatement: true, parseSourceElement: true */
+
+(function (exports) {
+ 'use strict';
+
+ var Token,
+ TokenName,
+ Syntax,
+ PropertyKind,
+ Messages,
+ Regex,
+ source,
+ strict,
+ index,
+ lineNumber,
+ lineStart,
+ length,
+ buffer,
+ state,
+ extra;
+
+ Token = {
+ BooleanLiteral: 1,
+ EOF: 2,
+ Identifier: 3,
+ Keyword: 4,
+ NullLiteral: 5,
+ NumericLiteral: 6,
+ Punctuator: 7,
+ StringLiteral: 8
+ };
+
+ TokenName = {};
+ TokenName[Token.BooleanLiteral] = 'Boolean';
+ TokenName[Token.EOF] = '';
+ TokenName[Token.Identifier] = 'Identifier';
+ TokenName[Token.Keyword] = 'Keyword';
+ TokenName[Token.NullLiteral] = 'Null';
+ TokenName[Token.NumericLiteral] = 'Numeric';
+ TokenName[Token.Punctuator] = 'Punctuator';
+ TokenName[Token.StringLiteral] = 'String';
+
+ Syntax = {
+ AssignmentExpression: 'AssignmentExpression',
+ ArrayExpression: 'ArrayExpression',
+ BlockStatement: 'BlockStatement',
+ BinaryExpression: 'BinaryExpression',
+ BreakStatement: 'BreakStatement',
+ CallExpression: 'CallExpression',
+ CatchClause: 'CatchClause',
+ ConditionalExpression: 'ConditionalExpression',
+ ContinueStatement: 'ContinueStatement',
+ DoWhileStatement: 'DoWhileStatement',
+ DebuggerStatement: 'DebuggerStatement',
+ EmptyStatement: 'EmptyStatement',
+ ExpressionStatement: 'ExpressionStatement',
+ ForStatement: 'ForStatement',
+ ForInStatement: 'ForInStatement',
+ FunctionDeclaration: 'FunctionDeclaration',
+ FunctionExpression: 'FunctionExpression',
+ Identifier: 'Identifier',
+ IfStatement: 'IfStatement',
+ Literal: 'Literal',
+ LabeledStatement: 'LabeledStatement',
+ LogicalExpression: 'LogicalExpression',
+ MemberExpression: 'MemberExpression',
+ NewExpression: 'NewExpression',
+ ObjectExpression: 'ObjectExpression',
+ Program: 'Program',
+ Property: 'Property',
+ ReturnStatement: 'ReturnStatement',
+ SequenceExpression: 'SequenceExpression',
+ SwitchStatement: 'SwitchStatement',
+ SwitchCase: 'SwitchCase',
+ ThisExpression: 'ThisExpression',
+ ThrowStatement: 'ThrowStatement',
+ TryStatement: 'TryStatement',
+ UnaryExpression: 'UnaryExpression',
+ UpdateExpression: 'UpdateExpression',
+ VariableDeclaration: 'VariableDeclaration',
+ VariableDeclarator: 'VariableDeclarator',
+ WhileStatement: 'WhileStatement',
+ WithStatement: 'WithStatement'
+ };
+
+ PropertyKind = {
+ Data: 1,
+ Get: 2,
+ Set: 4
+ };
+
+ // Error messages should be identical to V8.
+ Messages = {
+ UnexpectedToken: 'Unexpected token %0',
+ UnexpectedNumber: 'Unexpected number',
+ UnexpectedString: 'Unexpected string',
+ UnexpectedIdentifier: 'Unexpected identifier',
+ UnexpectedReserved: 'Unexpected reserved word',
+ UnexpectedEOS: 'Unexpected end of input',
+ NewlineAfterThrow: 'Illegal newline after throw',
+ InvalidRegExp: 'Invalid regular expression',
+ UnterminatedRegExp: 'Invalid regular expression: missing /',
+ InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
+ InvalidLHSInForIn: 'Invalid left-hand side in for-in',
+ NoCatchOrFinally: 'Missing catch or finally after try',
+ UnknownLabel: 'Undefined label \'%0\'',
+ Redeclaration: '%0 \'%1\' has already been declared',
+ IllegalContinue: 'Illegal continue statement',
+ IllegalBreak: 'Illegal break statement',
+ IllegalReturn: 'Illegal return statement',
+ StrictModeWith: 'Strict mode code may not include a with statement',
+ StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
+ StrictVarName: 'Variable name may not be eval or arguments in strict mode',
+ StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
+ StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
+ StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
+ StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
+ StrictDelete: 'Delete of an unqualified identifier in strict mode.',
+ StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
+ AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
+ AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
+ StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
+ StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
+ StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
+ StrictReservedWord: 'Use of future reserved word in strict mode'
+ };
+
+ // See also tools/generate-unicode-regex.py.
+ Regex = {
+ NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'),
+ NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]')
+ };
+
+ // Ensure the condition is true, otherwise throw an error.
+ // This is only to have a better contract semantic, i.e. another safety net
+ // to catch a logic error. The condition shall be fulfilled in normal case.
+ // Do NOT use this to enforce a certain condition on any user input.
+
+ function assert(condition, message) {
+ if (!condition) {
+ throw new Error('ASSERT: ' + message);
+ }
+ }
+
+ function sliceSource(from, to) {
+ return source.slice(from, to);
+ }
+
+ if (typeof 'esprima'[0] === 'undefined') {
+ sliceSource = function sliceArraySource(from, to) {
+ return source.slice(from, to).join('');
+ };
+ }
+
+ function isDecimalDigit(ch) {
+ return '0123456789'.indexOf(ch) >= 0;
+ }
+
+ function isHexDigit(ch) {
+ return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
+ }
+
+ function isOctalDigit(ch) {
+ return '01234567'.indexOf(ch) >= 0;
+ }
+
+
+ // 7.2 White Space
+
+ function isWhiteSpace(ch) {
+ return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
+ (ch === '\u000C') || (ch === '\u00A0') ||
+ (ch.charCodeAt(0) >= 0x1680 &&
+ '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
+ }
+
+ // 7.3 Line Terminators
+
+ function isLineTerminator(ch) {
+ return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
+ }
+
+ // 7.6 Identifier Names and Identifiers
+
+ function isIdentifierStart(ch) {
+ return (ch === '$') || (ch === '_') || (ch === '\\') ||
+ (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+ ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch));
+ }
+
+ function isIdentifierPart(ch) {
+ return (ch === '$') || (ch === '_') || (ch === '\\') ||
+ (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+ ((ch >= '0') && (ch <= '9')) ||
+ ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch));
+ }
+
+ // 7.6.1.2 Future Reserved Words
+
+ function isFutureReservedWord(id) {
+ switch (id) {
+
+ // Future reserved words.
+ case 'class':
+ case 'enum':
+ case 'export':
+ case 'extends':
+ case 'import':
+ case 'super':
+ return true;
+ }
+
+ return false;
+ }
+
+ function isStrictModeReservedWord(id) {
+ switch (id) {
+
+ // Strict Mode reserved words.
+ case 'implements':
+ case 'interface':
+ case 'package':
+ case 'private':
+ case 'protected':
+ case 'public':
+ case 'static':
+ case 'yield':
+ case 'let':
+ return true;
+ }
+
+ return false;
+ }
+
+ function isRestrictedWord(id) {
+ return id === 'eval' || id === 'arguments';
+ }
+
+ // 7.6.1.1 Keywords
+
+ function isKeyword(id) {
+ var keyword = false;
+ switch (id.length) {
+ case 2:
+ keyword = (id === 'if') || (id === 'in') || (id === 'do');
+ break;
+ case 3:
+ keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
+ break;
+ case 4:
+ keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
+ break;
+ case 5:
+ keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
+ break;
+ case 6:
+ keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
+ break;
+ case 7:
+ keyword = (id === 'default') || (id === 'finally');
+ break;
+ case 8:
+ keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
+ break;
+ case 10:
+ keyword = (id === 'instanceof');
+ break;
+ }
+
+ if (keyword) {
+ return true;
+ }
+
+ switch (id) {
+ // Future reserved words.
+ // 'const' is specialized as Keyword in V8.
+ case 'const':
+ return true;
+
+ // For compatiblity to SpiderMonkey and ES.next
+ case 'yield':
+ case 'let':
+ return true;
+ }
+
+ if (strict && isStrictModeReservedWord(id)) {
+ return true;
+ }
+
+ return isFutureReservedWord(id);
+ }
+
+ // Return the next character and move forward.
+
+ function nextChar() {
+ return source[index++];
+ }
+
+ // 7.4 Comments
+
+ function skipComment() {
+ var ch, blockComment, lineComment;
+
+ blockComment = false;
+ lineComment = false;
+
+ while (index < length) {
+ ch = source[index];
+
+ if (lineComment) {
+ ch = nextChar();
+ if (isLineTerminator(ch)) {
+ lineComment = false;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ }
+ } else if (blockComment) {
+ if (isLineTerminator(ch)) {
+ if (ch === '\r' && source[index + 1] === '\n') {
+ ++index;
+ }
+ ++lineNumber;
+ ++index;
+ lineStart = index;
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ } else {
+ ch = nextChar();
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ if (ch === '*') {
+ ch = source[index];
+ if (ch === '/') {
+ ++index;
+ blockComment = false;
+ }
+ }
+ }
+ } else if (ch === '/') {
+ ch = source[index + 1];
+ if (ch === '/') {
+ index += 2;
+ lineComment = true;
+ } else if (ch === '*') {
+ index += 2;
+ blockComment = true;
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ } else {
+ break;
+ }
+ } else if (isWhiteSpace(ch)) {
+ ++index;
+ } else if (isLineTerminator(ch)) {
+ ++index;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ } else {
+ break;
+ }
+ }
+ }
+
+ function scanHexEscape(prefix) {
+ var i, len, ch, code = 0;
+
+ len = (prefix === 'u') ? 4 : 2;
+ for (i = 0; i < len; ++i) {
+ if (index < length && isHexDigit(source[index])) {
+ ch = nextChar();
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+ } else {
+ return '';
+ }
+ }
+ return String.fromCharCode(code);
+ }
+
+ function scanIdentifier() {
+ var ch, start, id, restore;
+
+ ch = source[index];
+ if (!isIdentifierStart(ch)) {
+ return;
+ }
+
+ start = index;
+ if (ch === '\\') {
+ ++index;
+ if (source[index] !== 'u') {
+ return;
+ }
+ ++index;
+ restore = index;
+ ch = scanHexEscape('u');
+ if (ch) {
+ if (ch === '\\' || !isIdentifierStart(ch)) {
+ return;
+ }
+ id = ch;
+ } else {
+ index = restore;
+ id = 'u';
+ }
+ } else {
+ id = nextChar();
+ }
+
+ while (index < length) {
+ ch = source[index];
+ if (!isIdentifierPart(ch)) {
+ break;
+ }
+ if (ch === '\\') {
+ ++index;
+ if (source[index] !== 'u') {
+ return;
+ }
+ ++index;
+ restore = index;
+ ch = scanHexEscape('u');
+ if (ch) {
+ if (ch === '\\' || !isIdentifierPart(ch)) {
+ return;
+ }
+ id += ch;
+ } else {
+ index = restore;
+ id += 'u';
+ }
+ } else {
+ id += nextChar();
+ }
+ }
+
+ // There is no keyword or literal with only one character.
+ // Thus, it must be an identifier.
+ if (id.length === 1) {
+ return {
+ type: Token.Identifier,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (isKeyword(id)) {
+ return {
+ type: Token.Keyword,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // 7.8.1 Null Literals
+
+ if (id === 'null') {
+ return {
+ type: Token.NullLiteral,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // 7.8.2 Boolean Literals
+
+ if (id === 'true' || id === 'false') {
+ return {
+ type: Token.BooleanLiteral,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ return {
+ type: Token.Identifier,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // 7.7 Punctuators
+
+ function scanPunctuator() {
+ var start = index,
+ ch1 = source[index],
+ ch2,
+ ch3,
+ ch4;
+
+ // Check for most common single-character punctuators.
+
+ if (ch1 === ';' || ch1 === '{' || ch1 === '}') {
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: ch1,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === ',' || ch1 === '(' || ch1 === ')') {
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: ch1,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // Dot (.) can also start a floating-point number, hence the need
+ // to check the next character.
+
+ ch2 = source[index + 1];
+ if (ch1 === '.' && !isDecimalDigit(ch2)) {
+ return {
+ type: Token.Punctuator,
+ value: nextChar(),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // Peek more characters.
+
+ ch3 = source[index + 2];
+ ch4 = source[index + 3];
+
+ // 4-character punctuator: >>>=
+
+ if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
+ if (ch4 === '=') {
+ index += 4;
+ return {
+ type: Token.Punctuator,
+ value: '>>>=',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ // 3-character punctuators: === !== >>> <<= >>=
+
+ if (ch1 === '=' && ch2 === '=' && ch3 === '=') {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: '===',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === '!' && ch2 === '=' && ch3 === '=') {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: '!==',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: '>>>',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: '<<=',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: '>>=',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // 2-character punctuators: <= >= == != ++ -- << >> && ||
+ // += -= *= %= &= |= ^= /=
+
+ if (ch2 === '=') {
+ if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: ch1 + ch2,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
+ if ('+-<>&|'.indexOf(ch2) >= 0) {
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: ch1 + ch2,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ // The remaining 1-character punctuators.
+
+ if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) {
+ return {
+ type: Token.Punctuator,
+ value: nextChar(),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ // 7.8.3 Numeric Literals
+
+ function scanNumericLiteral() {
+ var number, start, ch;
+
+ ch = source[index];
+ assert(isDecimalDigit(ch) || (ch === '.'),
+ 'Numeric literal must start with a decimal digit or a decimal point');
+
+ start = index;
+ number = '';
+ if (ch !== '.') {
+ number = nextChar();
+ ch = source[index];
+
+ // Hex number starts with '0x'.
+ // Octal number starts with '0'.
+ if (number === '0') {
+ if (ch === 'x' || ch === 'X') {
+ number += nextChar();
+ while (index < length) {
+ ch = source[index];
+ if (!isHexDigit(ch)) {
+ break;
+ }
+ number += nextChar();
+ }
+
+ if (number.length <= 2) {
+ // only 0x
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+
+ if (index < length) {
+ ch = source[index];
+ if (isIdentifierStart(ch)) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 16),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ } else if (isOctalDigit(ch)) {
+ number += nextChar();
+ while (index < length) {
+ ch = source[index];
+ if (!isOctalDigit(ch)) {
+ break;
+ }
+ number += nextChar();
+ }
+
+ if (index < length) {
+ ch = source[index];
+ if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 8),
+ octal: true,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // decimal number starts with '0' such as '09' is illegal.
+ if (isDecimalDigit(ch)) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+
+ while (index < length) {
+ ch = source[index];
+ if (!isDecimalDigit(ch)) {
+ break;
+ }
+ number += nextChar();
+ }
+ }
+
+ if (ch === '.') {
+ number += nextChar();
+ while (index < length) {
+ ch = source[index];
+ if (!isDecimalDigit(ch)) {
+ break;
+ }
+ number += nextChar();
+ }
+ }
+
+ if (ch === 'e' || ch === 'E') {
+ number += nextChar();
+
+ ch = source[index];
+ if (ch === '+' || ch === '-') {
+ number += nextChar();
+ }
+
+ ch = source[index];
+ if (isDecimalDigit(ch)) {
+ number += nextChar();
+ while (index < length) {
+ ch = source[index];
+ if (!isDecimalDigit(ch)) {
+ break;
+ }
+ number += nextChar();
+ }
+ } else {
+ ch = 'character ' + ch;
+ if (index >= length) {
+ ch = '';
+ }
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+
+ if (index < length) {
+ ch = source[index];
+ if (isIdentifierStart(ch)) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseFloat(number),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // 7.8.4 String Literals
+
+ function scanStringLiteral() {
+ var str = '', quote, start, ch, code, unescaped, restore, octal = false;
+
+ quote = source[index];
+ assert((quote === '\'' || quote === '"'),
+ 'String literal must starts with a quote');
+
+ start = index;
+ ++index;
+
+ while (index < length) {
+ ch = nextChar();
+
+ if (ch === quote) {
+ quote = '';
+ break;
+ } else if (ch === '\\') {
+ ch = nextChar();
+ if (!isLineTerminator(ch)) {
+ switch (ch) {
+ case 'n':
+ str += '\n';
+ break;
+ case 'r':
+ str += '\r';
+ break;
+ case 't':
+ str += '\t';
+ break;
+ case 'u':
+ case 'x':
+ restore = index;
+ unescaped = scanHexEscape(ch);
+ if (unescaped) {
+ str += unescaped;
+ } else {
+ index = restore;
+ str += ch;
+ }
+ break;
+ case 'b':
+ str += '\b';
+ break;
+ case 'f':
+ str += '\f';
+ break;
+ case 'v':
+ str += '\v';
+ break;
+
+ default:
+ if (isOctalDigit(ch)) {
+ code = '01234567'.indexOf(ch);
+
+ // \0 is not octal escape sequence
+ if (code !== 0) {
+ octal = true;
+ }
+
+ if (index < length && isOctalDigit(source[index])) {
+ octal = true;
+ code = code * 8 + '01234567'.indexOf(nextChar());
+
+ // 3 digits are only allowed when string starts
+ // with 0, 1, 2, 3
+ if ('0123'.indexOf(ch) >= 0 &&
+ index < length &&
+ isOctalDigit(source[index])) {
+ code = code * 8 + '01234567'.indexOf(nextChar());
+ }
+ }
+ str += String.fromCharCode(code);
+ } else {
+ str += ch;
+ }
+ break;
+ }
+ } else {
+ ++lineNumber;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ }
+ } else if (isLineTerminator(ch)) {
+ break;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== '') {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+
+ return {
+ type: Token.StringLiteral,
+ value: str,
+ octal: octal,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ function scanRegExp() {
+ var str = '', ch, start, pattern, flags, value, classMarker = false, restore;
+
+ buffer = null;
+ skipComment();
+
+ start = index;
+ ch = source[index];
+ assert(ch === '/', 'Regular expression literal must start with a slash');
+ str = nextChar();
+
+ while (index < length) {
+ ch = nextChar();
+ str += ch;
+ if (classMarker) {
+ if (ch === ']') {
+ classMarker = false;
+ }
+ } else {
+ if (ch === '\\') {
+ ch = nextChar();
+ // ECMA-262 7.8.5
+ if (isLineTerminator(ch)) {
+ throwError({}, Messages.UnterminatedRegExp);
+ }
+ str += ch;
+ }
+ else if (ch === '/') {
+ break;
+ }
+ else if (ch === '[') {
+ classMarker = true;
+ }
+ else if (isLineTerminator(ch)) {
+ throwError({}, Messages.UnterminatedRegExp);
+ }
+ }
+ }
+
+ if (str.length === 1) {
+ throwError({}, Messages.UnterminatedRegExp);
+ }
+
+ // Exclude leading and trailing slash.
+ pattern = str.substr(1, str.length - 2);
+
+ flags = '';
+ while (index < length) {
+ ch = source[index];
+ if (!isIdentifierPart(ch)) {
+ break;
+ }
+
+ ++index;
+ if (ch === '\\' && index < length) {
+ ch = source[index];
+ if (ch === 'u') {
+ ++index;
+ restore = index;
+ ch = scanHexEscape('u');
+ if (ch) {
+ flags += ch;
+ str += '\\u';
+ for (; restore < index; ++restore) {
+ str += source[restore];
+ }
+ } else {
+ index = restore;
+ flags += 'u';
+ str += '\\u';
+ }
+ } else {
+ str += '\\';
+ }
+ } else {
+ flags += ch;
+ str += ch;
+ }
+ }
+
+ try {
+ value = new RegExp(pattern, flags);
+ } catch (e) {
+ throwError({}, Messages.InvalidRegExp);
+ }
+
+ return {
+ literal: str,
+ value: value,
+ range: [start, index]
+ };
+ }
+
+ function isIdentifierName(token) {
+ return token.type === Token.Identifier ||
+ token.type === Token.Keyword ||
+ token.type === Token.BooleanLiteral ||
+ token.type === Token.NullLiteral;
+ }
+
+ function advance() {
+ var ch, token;
+
+ skipComment();
+
+ if (index >= length) {
+ return {
+ type: Token.EOF,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [index, index]
+ };
+ }
+
+ token = scanPunctuator();
+ if (typeof token !== 'undefined') {
+ return token;
+ }
+
+ ch = source[index];
+
+ if (ch === '\'' || ch === '"') {
+ return scanStringLiteral();
+ }
+
+ if (ch === '.' || isDecimalDigit(ch)) {
+ return scanNumericLiteral();
+ }
+
+ token = scanIdentifier();
+ if (typeof token !== 'undefined') {
+ return token;
+ }
+
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+
+ function lex() {
+ var token;
+
+ if (buffer) {
+ index = buffer.range[1];
+ lineNumber = buffer.lineNumber;
+ lineStart = buffer.lineStart;
+ token = buffer;
+ buffer = null;
+ return token;
+ }
+
+ buffer = null;
+ return advance();
+ }
+
+ function lookahead() {
+ var pos, line, start;
+
+ if (buffer !== null) {
+ return buffer;
+ }
+
+ pos = index;
+ line = lineNumber;
+ start = lineStart;
+ buffer = advance();
+ index = pos;
+ lineNumber = line;
+ lineStart = start;
+
+ return buffer;
+ }
+
+ // Return true if there is a line terminator before the next token.
+
+ function peekLineTerminator() {
+ var pos, line, start, found;
+
+ pos = index;
+ line = lineNumber;
+ start = lineStart;
+ skipComment();
+ found = lineNumber !== line;
+ index = pos;
+ lineNumber = line;
+ lineStart = start;
+
+ return found;
+ }
+
+ // Throw an exception
+
+ function throwError(token, messageFormat) {
+ var error,
+ args = Array.prototype.slice.call(arguments, 2),
+ msg = messageFormat.replace(
+ /%(\d)/g,
+ function (whole, index) {
+ return args[index] || '';
+ }
+ );
+
+ if (typeof token.lineNumber === 'number') {
+ error = new Error('Line ' + token.lineNumber + ': ' + msg);
+ error.index = token.range[0];
+ error.lineNumber = token.lineNumber;
+ error.column = token.range[0] - lineStart + 1;
+ } else {
+ error = new Error('Line ' + lineNumber + ': ' + msg);
+ error.index = index;
+ error.lineNumber = lineNumber;
+ error.column = index - lineStart + 1;
+ }
+
+ throw error;
+ }
+
+ function throwErrorTolerant() {
+ var error;
+ try {
+ throwError.apply(null, arguments);
+ } catch (e) {
+ if (extra.errors) {
+ extra.errors.push(e);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+
+ // Throw an exception because of the token.
+
+ function throwUnexpected(token) {
+ var s;
+
+ if (token.type === Token.EOF) {
+ throwError(token, Messages.UnexpectedEOS);
+ }
+
+ if (token.type === Token.NumericLiteral) {
+ throwError(token, Messages.UnexpectedNumber);
+ }
+
+ if (token.type === Token.StringLiteral) {
+ throwError(token, Messages.UnexpectedString);
+ }
+
+ if (token.type === Token.Identifier) {
+ throwError(token, Messages.UnexpectedIdentifier);
+ }
+
+ if (token.type === Token.Keyword) {
+ if (isFutureReservedWord(token.value)) {
+ throwError(token, Messages.UnexpectedReserved);
+ } else if (strict && isStrictModeReservedWord(token.value)) {
+ throwError(token, Messages.StrictReservedWord);
+ }
+ throwError(token, Messages.UnexpectedToken, token.value);
+ }
+
+ // BooleanLiteral, NullLiteral, or Punctuator.
+ throwError(token, Messages.UnexpectedToken, token.value);
+ }
+
+ // Expect the next token to match the specified punctuator.
+ // If not, an exception will be thrown.
+
+ function expect(value) {
+ var token = lex();
+ if (token.type !== Token.Punctuator || token.value !== value) {
+ throwUnexpected(token);
+ }
+ }
+
+ // Expect the next token to match the specified keyword.
+ // If not, an exception will be thrown.
+
+ function expectKeyword(keyword) {
+ var token = lex();
+ if (token.type !== Token.Keyword || token.value !== keyword) {
+ throwUnexpected(token);
+ }
+ }
+
+ // Return true if the next token matches the specified punctuator.
+
+ function match(value) {
+ var token = lookahead();
+ return token.type === Token.Punctuator && token.value === value;
+ }
+
+ // Return true if the next token matches the specified keyword
+
+ function matchKeyword(keyword) {
+ var token = lookahead();
+ return token.type === Token.Keyword && token.value === keyword;
+ }
+
+ // Return true if the next token is an assignment operator
+
+ function matchAssign() {
+ var token = lookahead(),
+ op = token.value;
+
+ if (token.type !== Token.Punctuator) {
+ return false;
+ }
+ return op === '=' ||
+ op === '*=' ||
+ op === '/=' ||
+ op === '%=' ||
+ op === '+=' ||
+ op === '-=' ||
+ op === '<<=' ||
+ op === '>>=' ||
+ op === '>>>=' ||
+ op === '&=' ||
+ op === '^=' ||
+ op === '|=';
+ }
+
+ function consumeSemicolon() {
+ var token, line;
+
+ // Catch the very common case first.
+ if (source[index] === ';') {
+ lex();
+ return;
+ }
+
+ line = lineNumber;
+ skipComment();
+ if (lineNumber !== line) {
+ return;
+ }
+
+ if (match(';')) {
+ lex();
+ return;
+ }
+
+ token = lookahead();
+ if (token.type !== Token.EOF && !match('}')) {
+ throwUnexpected(token);
+ }
+ return;
+ }
+
+ // Return true if provided expression is LeftHandSideExpression
+
+ function isLeftHandSide(expr) {
+ switch (expr.type) {
+ case 'AssignmentExpression':
+ case 'BinaryExpression':
+ case 'ConditionalExpression':
+ case 'LogicalExpression':
+ case 'SequenceExpression':
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return false;
+ }
+ return true;
+ }
+
+ // 11.1.4 Array Initialiser
+
+ function parseArrayInitialiser() {
+ var elements = [],
+ undef;
+
+ expect('[');
+
+ while (!match(']')) {
+ if (match(',')) {
+ lex();
+ elements.push(undef);
+ } else {
+ elements.push(parseAssignmentExpression());
+
+ if (!match(']')) {
+ expect(',');
+ }
+ }
+ }
+
+ expect(']');
+
+ return {
+ type: Syntax.ArrayExpression,
+ elements: elements
+ };
+ }
+
+ // 11.1.5 Object Initialiser
+
+ function parsePropertyFunction(param, first) {
+ var previousStrict, body;
+
+ previousStrict = strict;
+ body = parseFunctionSourceElements();
+ if (first && strict && isRestrictedWord(param[0].name)) {
+ throwError(first, Messages.StrictParamName);
+ }
+ strict = previousStrict;
+
+ return {
+ type: Syntax.FunctionExpression,
+ id: null,
+ params: param,
+ body: body
+ };
+ }
+
+ function parseObjectPropertyKey() {
+ var token = lex();
+
+ // Note: This function is called only from parseObjectProperty(), where
+ // EOF and Punctuator tokens are already filtered out.
+
+ if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
+ if (strict && token.octal) {
+ throwError(token, Messages.StrictOctalLiteral);
+ }
+ return createLiteral(token);
+ }
+
+ return {
+ type: Syntax.Identifier,
+ name: token.value
+ };
+ }
+
+ function parseObjectProperty() {
+ var token, key, id, param;
+
+ token = lookahead();
+
+ if (token.type === Token.Identifier) {
+
+ id = parseObjectPropertyKey();
+
+ // Property Assignment: Getter and Setter.
+
+ if (token.value === 'get' && !match(':')) {
+ key = parseObjectPropertyKey();
+ expect('(');
+ expect(')');
+ return {
+ type: Syntax.Property,
+ key: key,
+ value: parsePropertyFunction([]),
+ kind: 'get'
+ };
+ } else if (token.value === 'set' && !match(':')) {
+ key = parseObjectPropertyKey();
+ expect('(');
+ token = lookahead();
+ if (token.type !== Token.Identifier) {
+ throwUnexpected(lex());
+ }
+ param = [ parseVariableIdentifier() ];
+ expect(')');
+ return {
+ type: Syntax.Property,
+ key: key,
+ value: parsePropertyFunction(param, token),
+ kind: 'set'
+ };
+ } else {
+ expect(':');
+ return {
+ type: Syntax.Property,
+ key: id,
+ value: parseAssignmentExpression(),
+ kind: 'init'
+ };
+ }
+ } else if (token.type === Token.EOF || token.type === Token.Punctuator) {
+ throwUnexpected(token);
+ } else {
+ key = parseObjectPropertyKey();
+ expect(':');
+ return {
+ type: Syntax.Property,
+ key: key,
+ value: parseAssignmentExpression(),
+ kind: 'init'
+ };
+ }
+ }
+
+ function parseObjectInitialiser() {
+ var token, properties = [], property, name, kind, map = {}, toString = String;
+
+ expect('{');
+
+ while (!match('}')) {
+ property = parseObjectProperty();
+
+ if (property.key.type === Syntax.Identifier) {
+ name = property.key.name;
+ } else {
+ name = toString(property.key.value);
+ }
+ kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
+ if (Object.prototype.hasOwnProperty.call(map, name)) {
+ if (map[name] === PropertyKind.Data) {
+ if (strict && kind === PropertyKind.Data) {
+ throwErrorTolerant({}, Messages.StrictDuplicateProperty);
+ } else if (kind !== PropertyKind.Data) {
+ throwError({}, Messages.AccessorDataProperty);
+ }
+ } else {
+ if (kind === PropertyKind.Data) {
+ throwError({}, Messages.AccessorDataProperty);
+ } else if (map[name] & kind) {
+ throwError({}, Messages.AccessorGetSet);
+ }
+ }
+ map[name] |= kind;
+ } else {
+ map[name] = kind;
+ }
+
+ properties.push(property);
+
+ if (!match('}')) {
+ expect(',');
+ }
+ }
+
+ expect('}');
+
+ return {
+ type: Syntax.ObjectExpression,
+ properties: properties
+ };
+ }
+
+ // 11.1 Primary Expressions
+
+ function parsePrimaryExpression() {
+ var expr,
+ token = lookahead(),
+ type = token.type;
+
+ if (type === Token.Identifier) {
+ return {
+ type: Syntax.Identifier,
+ name: lex().value
+ };
+ }
+
+ if (type === Token.StringLiteral || type === Token.NumericLiteral) {
+ if (strict && token.octal) {
+ throwErrorTolerant(token, Messages.StrictOctalLiteral);
+ }
+ return createLiteral(lex());
+ }
+
+ if (type === Token.Keyword) {
+ if (matchKeyword('this')) {
+ lex();
+ return {
+ type: Syntax.ThisExpression
+ };
+ }
+
+ if (matchKeyword('function')) {
+ return parseFunctionExpression();
+ }
+ }
+
+ if (type === Token.BooleanLiteral) {
+ lex();
+ token.value = (token.value === 'true');
+ return createLiteral(token);
+ }
+
+ if (type === Token.NullLiteral) {
+ lex();
+ token.value = null;
+ return createLiteral(token);
+ }
+
+ if (match('[')) {
+ return parseArrayInitialiser();
+ }
+
+ if (match('{')) {
+ return parseObjectInitialiser();
+ }
+
+ if (match('(')) {
+ lex();
+ state.lastParenthesized = expr = parseExpression();
+ expect(')');
+ return expr;
+ }
+
+ if (match('/') || match('/=')) {
+ return createLiteral(scanRegExp());
+ }
+
+ return throwUnexpected(lex());
+ }
+
+ // 11.2 Left-Hand-Side Expressions
+
+ function parseArguments() {
+ var args = [];
+
+ expect('(');
+
+ if (!match(')')) {
+ while (index < length) {
+ args.push(parseAssignmentExpression());
+ if (match(')')) {
+ break;
+ }
+ expect(',');
+ }
+ }
+
+ expect(')');
+
+ return args;
+ }
+
+ function parseNonComputedProperty() {
+ var token = lex();
+
+ if (!isIdentifierName(token)) {
+ throwUnexpected(token);
+ }
+
+ return {
+ type: Syntax.Identifier,
+ name: token.value
+ };
+ }
+
+ function parseNonComputedMember(object) {
+ return {
+ type: Syntax.MemberExpression,
+ computed: false,
+ object: object,
+ property: parseNonComputedProperty()
+ };
+ }
+
+ function parseComputedMember(object) {
+ var property, expr;
+
+ expect('[');
+ property = parseExpression();
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: true,
+ object: object,
+ property: property
+ };
+ expect(']');
+ return expr;
+ }
+
+ function parseCallMember(object) {
+ return {
+ type: Syntax.CallExpression,
+ callee: object,
+ 'arguments': parseArguments()
+ };
+ }
+
+ function parseNewExpression() {
+ var expr;
+
+ expectKeyword('new');
+
+ expr = {
+ type: Syntax.NewExpression,
+ callee: parseLeftHandSideExpression(),
+ 'arguments': []
+ };
+
+ if (match('(')) {
+ expr['arguments'] = parseArguments();
+ }
+
+ return expr;
+ }
+
+ function parseLeftHandSideExpressionAllowCall() {
+ var useNew, expr;
+
+ useNew = matchKeyword('new');
+ expr = useNew ? parseNewExpression() : parsePrimaryExpression();
+
+ while (index < length) {
+ if (match('.')) {
+ lex();
+ expr = parseNonComputedMember(expr);
+ } else if (match('[')) {
+ expr = parseComputedMember(expr);
+ } else if (match('(')) {
+ expr = parseCallMember(expr);
+ } else {
+ break;
+ }
+ }
+
+ return expr;
+ }
+
+ function parseLeftHandSideExpression() {
+ var useNew, expr;
+
+ useNew = matchKeyword('new');
+ expr = useNew ? parseNewExpression() : parsePrimaryExpression();
+
+ while (index < length) {
+ if (match('.')) {
+ lex();
+ expr = parseNonComputedMember(expr);
+ } else if (match('[')) {
+ expr = parseComputedMember(expr);
+ } else {
+ break;
+ }
+ }
+
+ return expr;
+ }
+
+ // 11.3 Postfix Expressions
+
+ function parsePostfixExpression() {
+ var expr = parseLeftHandSideExpressionAllowCall();
+
+ if ((match('++') || match('--')) && !peekLineTerminator()) {
+ // 11.3.1, 11.3.2
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
+ throwError({}, Messages.StrictLHSPostfix);
+ }
+ expr = {
+ type: Syntax.UpdateExpression,
+ operator: lex().value,
+ argument: expr,
+ prefix: false
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.4 Unary Operators
+
+ function parseUnaryExpression() {
+ var token, expr;
+
+ if (match('++') || match('--')) {
+ token = lex();
+ expr = parseUnaryExpression();
+ // 11.4.4, 11.4.5
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
+ throwError({}, Messages.StrictLHSPrefix);
+ }
+ expr = {
+ type: Syntax.UpdateExpression,
+ operator: token.value,
+ argument: expr,
+ prefix: true
+ };
+ return expr;
+ }
+
+ if (match('+') || match('-') || match('~') || match('!')) {
+ expr = {
+ type: Syntax.UnaryExpression,
+ operator: lex().value,
+ argument: parseUnaryExpression()
+ };
+ return expr;
+ }
+
+ if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
+ expr = {
+ type: Syntax.UnaryExpression,
+ operator: lex().value,
+ argument: parseUnaryExpression()
+ };
+ if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
+ throwErrorTolerant({}, Messages.StrictDelete);
+ }
+ return expr;
+ }
+
+ return parsePostfixExpression();
+ }
+
+ // 11.5 Multiplicative Operators
+
+ function parseMultiplicativeExpression() {
+ var expr = parseUnaryExpression();
+
+ while (match('*') || match('/') || match('%')) {
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseUnaryExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.6 Additive Operators
+
+ function parseAdditiveExpression() {
+ var expr = parseMultiplicativeExpression();
+
+ while (match('+') || match('-')) {
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseMultiplicativeExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.7 Bitwise Shift Operators
+
+ function parseShiftExpression() {
+ var expr = parseAdditiveExpression();
+
+ while (match('<<') || match('>>') || match('>>>')) {
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseAdditiveExpression()
+ };
+ }
+
+ return expr;
+ }
+ // 11.8 Relational Operators
+
+ function parseRelationalExpression() {
+ var expr, previousAllowIn;
+
+ previousAllowIn = state.allowIn;
+ state.allowIn = true;
+ expr = parseShiftExpression();
+ state.allowIn = previousAllowIn;
+
+ if (match('<') || match('>') || match('<=') || match('>=')) {
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseRelationalExpression()
+ };
+ } else if (state.allowIn && matchKeyword('in')) {
+ lex();
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: 'in',
+ left: expr,
+ right: parseRelationalExpression()
+ };
+ } else if (matchKeyword('instanceof')) {
+ lex();
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: 'instanceof',
+ left: expr,
+ right: parseRelationalExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.9 Equality Operators
+
+ function parseEqualityExpression() {
+ var expr = parseRelationalExpression();
+
+ while (match('==') || match('!=') || match('===') || match('!==')) {
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseRelationalExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.10 Binary Bitwise Operators
+
+ function parseBitwiseANDExpression() {
+ var expr = parseEqualityExpression();
+
+ while (match('&')) {
+ lex();
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: '&',
+ left: expr,
+ right: parseEqualityExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ function parseBitwiseORExpression() {
+ var expr = parseBitwiseANDExpression();
+
+ while (match('|')) {
+ lex();
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: '|',
+ left: expr,
+ right: parseBitwiseANDExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ function parseBitwiseXORExpression() {
+ var expr = parseBitwiseORExpression();
+
+ while (match('^')) {
+ lex();
+ expr = {
+ type: Syntax.BinaryExpression,
+ operator: '^',
+ left: expr,
+ right: parseBitwiseORExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.11 Binary Logical Operators
+
+ function parseLogicalANDExpression() {
+ var expr = parseBitwiseXORExpression();
+
+ while (match('&&')) {
+ lex();
+ expr = {
+ type: Syntax.LogicalExpression,
+ operator: '&&',
+ left: expr,
+ right: parseBitwiseXORExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ function parseLogicalORExpression() {
+ var expr = parseLogicalANDExpression();
+
+ while (match('||')) {
+ lex();
+ expr = {
+ type: Syntax.LogicalExpression,
+ operator: '||',
+ left: expr,
+ right: parseLogicalANDExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.12 Conditional Operator
+
+ function parseConditionalExpression() {
+ var expr, previousAllowIn, consequent;
+
+ expr = parseLogicalORExpression();
+
+ if (match('?')) {
+ lex();
+ previousAllowIn = state.allowIn;
+ state.allowIn = true;
+ consequent = parseAssignmentExpression();
+ state.allowIn = previousAllowIn;
+ expect(':');
+
+ expr = {
+ type: Syntax.ConditionalExpression,
+ test: expr,
+ consequent: consequent,
+ alternate: parseAssignmentExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.13 Assignment Operators
+
+ function parseAssignmentExpression() {
+ var expr;
+
+ expr = parseConditionalExpression();
+
+ if (matchAssign()) {
+ // LeftHandSideExpression
+ if (state.lastParenthesized !== expr && !isLeftHandSide(expr)) {
+ throwError({}, Messages.InvalidLHSInAssignment);
+ }
+
+ // 11.13.1
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
+ throwError({}, Messages.StrictLHSAssignment);
+ }
+
+ expr = {
+ type: Syntax.AssignmentExpression,
+ operator: lex().value,
+ left: expr,
+ right: parseAssignmentExpression()
+ };
+ }
+
+ return expr;
+ }
+
+ // 11.14 Comma Operator
+
+ function parseExpression() {
+ var expr = parseAssignmentExpression();
+
+ if (match(',')) {
+ expr = {
+ type: Syntax.SequenceExpression,
+ expressions: [ expr ]
+ };
+
+ while (index < length) {
+ if (!match(',')) {
+ break;
+ }
+ lex();
+ expr.expressions.push(parseAssignmentExpression());
+ }
+
+ }
+ return expr;
+ }
+
+ // 12.1 Block
+
+ function parseStatementList() {
+ var list = [],
+ statement;
+
+ while (index < length) {
+ if (match('}')) {
+ break;
+ }
+ statement = parseSourceElement();
+ if (typeof statement === 'undefined') {
+ break;
+ }
+ list.push(statement);
+ }
+
+ return list;
+ }
+
+ function parseBlock() {
+ var block;
+
+ expect('{');
+
+ block = parseStatementList();
+
+ expect('}');
+
+ return {
+ type: Syntax.BlockStatement,
+ body: block
+ };
+ }
+
+ // 12.2 Variable Statement
+
+ function parseVariableIdentifier() {
+ var token = lex();
+
+ if (token.type !== Token.Identifier) {
+ throwUnexpected(token);
+ }
+
+ return {
+ type: Syntax.Identifier,
+ name: token.value
+ };
+ }
+
+ function parseVariableDeclaration(kind) {
+ var id = parseVariableIdentifier(),
+ init = null;
+
+ // 12.2.1
+ if (strict && isRestrictedWord(id.name)) {
+ throwErrorTolerant({}, Messages.StrictVarName);
+ }
+
+ if (kind === 'const') {
+ expect('=');
+ init = parseAssignmentExpression();
+ } else if (match('=')) {
+ lex();
+ init = parseAssignmentExpression();
+ }
+
+ return {
+ type: Syntax.VariableDeclarator,
+ id: id,
+ init: init
+ };
+ }
+
+ function parseVariableDeclarationList(kind) {
+ var list = [];
+
+ while (index < length) {
+ list.push(parseVariableDeclaration(kind));
+ if (!match(',')) {
+ break;
+ }
+ lex();
+ }
+
+ return list;
+ }
+
+ function parseVariableStatement() {
+ var declarations;
+
+ expectKeyword('var');
+
+ declarations = parseVariableDeclarationList();
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.VariableDeclaration,
+ declarations: declarations,
+ kind: 'var'
+ };
+ }
+
+ // kind may be `const` or `let`
+ // Both are experimental and not in the specification yet.
+ // see http://wiki.ecmascript.org/doku.php?id=harmony:const
+ // and http://wiki.ecmascript.org/doku.php?id=harmony:let
+ function parseConstLetDeclaration(kind) {
+ var declarations;
+
+ expectKeyword(kind);
+
+ declarations = parseVariableDeclarationList(kind);
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.VariableDeclaration,
+ declarations: declarations,
+ kind: kind
+ };
+ }
+
+ // 12.3 Empty Statement
+
+ function parseEmptyStatement() {
+ expect(';');
+
+ return {
+ type: Syntax.EmptyStatement
+ };
+ }
+
+ // 12.4 Expression Statement
+
+ function parseExpressionStatement() {
+ var expr = parseExpression();
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.ExpressionStatement,
+ expression: expr
+ };
+ }
+
+ // 12.5 If statement
+
+ function parseIfStatement() {
+ var test, consequent, alternate;
+
+ expectKeyword('if');
+
+ expect('(');
+
+ test = parseExpression();
+
+ expect(')');
+
+ consequent = parseStatement();
+
+ if (matchKeyword('else')) {
+ lex();
+ alternate = parseStatement();
+ } else {
+ alternate = null;
+ }
+
+ return {
+ type: Syntax.IfStatement,
+ test: test,
+ consequent: consequent,
+ alternate: alternate
+ };
+ }
+
+ // 12.6 Iteration Statements
+
+ function parseDoWhileStatement() {
+ var body, test, oldInIteration;
+
+ expectKeyword('do');
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ body = parseStatement();
+
+ state.inIteration = oldInIteration;
+
+ expectKeyword('while');
+
+ expect('(');
+
+ test = parseExpression();
+
+ expect(')');
+
+ if (match(';')) {
+ lex();
+ }
+
+ return {
+ type: Syntax.DoWhileStatement,
+ body: body,
+ test: test
+ };
+ }
+
+ function parseWhileStatement() {
+ var test, body, oldInIteration;
+
+ expectKeyword('while');
+
+ expect('(');
+
+ test = parseExpression();
+
+ expect(')');
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ body = parseStatement();
+
+ state.inIteration = oldInIteration;
+
+ return {
+ type: Syntax.WhileStatement,
+ test: test,
+ body: body
+ };
+ }
+
+ function parseForVariableDeclaration() {
+ var token = lex();
+
+ return {
+ type: Syntax.VariableDeclaration,
+ declarations: parseVariableDeclarationList(),
+ kind: token.value
+ };
+ }
+
+ function parseForStatement() {
+ var init, test, update, left, right, body, oldInIteration;
+
+ init = test = update = null;
+
+ expectKeyword('for');
+
+ expect('(');
+
+ if (match(';')) {
+ lex();
+ } else {
+ if (matchKeyword('var') || matchKeyword('let')) {
+ state.allowIn = false;
+ init = parseForVariableDeclaration();
+ state.allowIn = true;
+
+ if (init.declarations.length === 1 && matchKeyword('in')) {
+ lex();
+ left = init;
+ right = parseExpression();
+ init = null;
+ }
+ } else {
+ state.allowIn = false;
+ init = parseExpression();
+ state.allowIn = true;
+
+ if (matchKeyword('in')) {
+ // LeftHandSideExpression
+ if (matchKeyword('in') && (state.lastParenthesized !== init && !isLeftHandSide(init))) {
+ throwError({}, Messages.InvalidLHSInForIn);
+ }
+ lex();
+ left = init;
+ right = parseExpression();
+ init = null;
+ }
+ }
+
+ if (typeof left === 'undefined') {
+ expect(';');
+ }
+ }
+
+ if (typeof left === 'undefined') {
+
+ if (!match(';')) {
+ test = parseExpression();
+ }
+ expect(';');
+
+ if (!match(')')) {
+ update = parseExpression();
+ }
+ }
+
+ expect(')');
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ body = parseStatement();
+
+ state.inIteration = oldInIteration;
+
+ if (typeof left === 'undefined') {
+ return {
+ type: Syntax.ForStatement,
+ init: init,
+ test: test,
+ update: update,
+ body: body
+ };
+ }
+
+ return {
+ type: Syntax.ForInStatement,
+ left: left,
+ right: right,
+ body: body,
+ each: false
+ };
+ }
+
+ // 12.7 The continue statement
+
+ function parseContinueStatement() {
+ var token, label = null;
+
+ expectKeyword('continue');
+
+ // Optimize the most common form: 'continue;'.
+ if (source[index] === ';') {
+ lex();
+
+ if (!state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return {
+ type: Syntax.ContinueStatement,
+ label: null
+ };
+ }
+
+ if (peekLineTerminator()) {
+ if (!state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return {
+ type: Syntax.ContinueStatement,
+ label: null
+ };
+ }
+
+ token = lookahead();
+ if (token.type === Token.Identifier) {
+ label = parseVariableIdentifier();
+
+ if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
+ throwError({}, Messages.UnknownLabel, label.name);
+ }
+ }
+
+ consumeSemicolon();
+
+ if (label === null && !state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return {
+ type: Syntax.ContinueStatement,
+ label: label
+ };
+ }
+
+ // 12.8 The break statement
+
+ function parseBreakStatement() {
+ var token, label = null;
+
+ expectKeyword('break');
+
+ // Optimize the most common form: 'break;'.
+ if (source[index] === ';') {
+ lex();
+
+ if (!(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return {
+ type: Syntax.BreakStatement,
+ label: null
+ };
+ }
+
+ if (peekLineTerminator()) {
+ if (!(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return {
+ type: Syntax.BreakStatement,
+ label: null
+ };
+ }
+
+ token = lookahead();
+ if (token.type === Token.Identifier) {
+ label = parseVariableIdentifier();
+
+ if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
+ throwError({}, Messages.UnknownLabel, label.name);
+ }
+ }
+
+ consumeSemicolon();
+
+ if (label === null && !(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return {
+ type: Syntax.BreakStatement,
+ label: label
+ };
+ }
+
+ // 12.9 The return statement
+
+ function parseReturnStatement() {
+ var token, argument = null;
+
+ expectKeyword('return');
+
+ if (!state.inFunctionBody) {
+ throwErrorTolerant({}, Messages.IllegalReturn);
+ }
+
+ // 'return' followed by a space and an identifier is very common.
+ if (source[index] === ' ') {
+ if (isIdentifierStart(source[index + 1])) {
+ argument = parseExpression();
+ consumeSemicolon();
+ return {
+ type: Syntax.ReturnStatement,
+ argument: argument
+ };
+ }
+ }
+
+ if (peekLineTerminator()) {
+ return {
+ type: Syntax.ReturnStatement,
+ argument: null
+ };
+ }
+
+ if (!match(';')) {
+ token = lookahead();
+ if (!match('}') && token.type !== Token.EOF) {
+ argument = parseExpression();
+ }
+ }
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.ReturnStatement,
+ argument: argument
+ };
+ }
+
+ // 12.10 The with statement
+
+ function parseWithStatement() {
+ var object, body;
+
+ if (strict) {
+ throwErrorTolerant({}, Messages.StrictModeWith);
+ }
+
+ expectKeyword('with');
+
+ expect('(');
+
+ object = parseExpression();
+
+ expect(')');
+
+ body = parseStatement();
+
+ return {
+ type: Syntax.WithStatement,
+ object: object,
+ body: body
+ };
+ }
+
+ // 12.10 The swith statement
+
+ function parseSwitchCase() {
+ var test,
+ consequent = [],
+ statement;
+
+ if (matchKeyword('default')) {
+ lex();
+ test = null;
+ } else {
+ expectKeyword('case');
+ test = parseExpression();
+ }
+ expect(':');
+
+ while (index < length) {
+ if (match('}') || matchKeyword('default') || matchKeyword('case')) {
+ break;
+ }
+ statement = parseStatement();
+ if (typeof statement === 'undefined') {
+ break;
+ }
+ consequent.push(statement);
+ }
+
+ return {
+ type: Syntax.SwitchCase,
+ test: test,
+ consequent: consequent
+ };
+ }
+
+ function parseSwitchStatement() {
+ var discriminant, cases, oldInSwitch;
+
+ expectKeyword('switch');
+
+ expect('(');
+
+ discriminant = parseExpression();
+
+ expect(')');
+
+ expect('{');
+
+ if (match('}')) {
+ lex();
+ return {
+ type: Syntax.SwitchStatement,
+ discriminant: discriminant
+ };
+ }
+
+ cases = [];
+
+ oldInSwitch = state.inSwitch;
+ state.inSwitch = true;
+
+ while (index < length) {
+ if (match('}')) {
+ break;
+ }
+ cases.push(parseSwitchCase());
+ }
+
+ state.inSwitch = oldInSwitch;
+
+ expect('}');
+
+ return {
+ type: Syntax.SwitchStatement,
+ discriminant: discriminant,
+ cases: cases
+ };
+ }
+
+ // 12.13 The throw statement
+
+ function parseThrowStatement() {
+ var argument;
+
+ expectKeyword('throw');
+
+ if (peekLineTerminator()) {
+ throwError({}, Messages.NewlineAfterThrow);
+ }
+
+ argument = parseExpression();
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.ThrowStatement,
+ argument: argument
+ };
+ }
+
+ // 12.14 The try statement
+
+ function parseCatchClause() {
+ var param;
+
+ expectKeyword('catch');
+
+ expect('(');
+ if (!match(')')) {
+ param = parseExpression();
+ // 12.14.1
+ if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {
+ throwErrorTolerant({}, Messages.StrictCatchVariable);
+ }
+ }
+ expect(')');
+
+ return {
+ type: Syntax.CatchClause,
+ param: param,
+ guard: null,
+ body: parseBlock()
+ };
+ }
+
+ function parseTryStatement() {
+ var block, handlers = [], finalizer = null;
+
+ expectKeyword('try');
+
+ block = parseBlock();
+
+ if (matchKeyword('catch')) {
+ handlers.push(parseCatchClause());
+ }
+
+ if (matchKeyword('finally')) {
+ lex();
+ finalizer = parseBlock();
+ }
+
+ if (handlers.length === 0 && !finalizer) {
+ throwError({}, Messages.NoCatchOrFinally);
+ }
+
+ return {
+ type: Syntax.TryStatement,
+ block: block,
+ handlers: handlers,
+ finalizer: finalizer
+ };
+ }
+
+ // 12.15 The debugger statement
+
+ function parseDebuggerStatement() {
+ expectKeyword('debugger');
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.DebuggerStatement
+ };
+ }
+
+ // 12 Statements
+
+ function parseStatement() {
+ var token = lookahead(),
+ expr,
+ labeledBody;
+
+ if (token.type === Token.EOF) {
+ throwUnexpected(token);
+ }
+
+ if (token.type === Token.Punctuator) {
+ switch (token.value) {
+ case ';':
+ return parseEmptyStatement();
+ case '{':
+ return parseBlock();
+ case '(':
+ return parseExpressionStatement();
+ default:
+ break;
+ }
+ }
+
+ if (token.type === Token.Keyword) {
+ switch (token.value) {
+ case 'break':
+ return parseBreakStatement();
+ case 'continue':
+ return parseContinueStatement();
+ case 'debugger':
+ return parseDebuggerStatement();
+ case 'do':
+ return parseDoWhileStatement();
+ case 'for':
+ return parseForStatement();
+ case 'function':
+ return parseFunctionDeclaration();
+ case 'if':
+ return parseIfStatement();
+ case 'return':
+ return parseReturnStatement();
+ case 'switch':
+ return parseSwitchStatement();
+ case 'throw':
+ return parseThrowStatement();
+ case 'try':
+ return parseTryStatement();
+ case 'var':
+ return parseVariableStatement();
+ case 'while':
+ return parseWhileStatement();
+ case 'with':
+ return parseWithStatement();
+ default:
+ break;
+ }
+ }
+
+ expr = parseExpression();
+
+ // 12.12 Labelled Statements
+ if ((expr.type === Syntax.Identifier) && match(':')) {
+ lex();
+
+ if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) {
+ throwError({}, Messages.Redeclaration, 'Label', expr.name);
+ }
+
+ state.labelSet[expr.name] = true;
+ labeledBody = parseStatement();
+ delete state.labelSet[expr.name];
+
+ return {
+ type: Syntax.LabeledStatement,
+ label: expr,
+ body: labeledBody
+ };
+ }
+
+ consumeSemicolon();
+
+ return {
+ type: Syntax.ExpressionStatement,
+ expression: expr
+ };
+ }
+
+ // 13 Function Definition
+
+ function parseFunctionSourceElements() {
+ var sourceElement, sourceElements = [], token, directive, firstRestricted,
+ oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
+
+ expect('{');
+
+ while (index < length) {
+ token = lookahead();
+ if (token.type !== Token.StringLiteral) {
+ break;
+ }
+
+ sourceElement = parseSourceElement();
+ sourceElements.push(sourceElement);
+ if (sourceElement.expression.type !== Syntax.Literal) {
+ // this is not directive
+ break;
+ }
+ directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
+ if (directive === 'use strict') {
+ strict = true;
+ if (firstRestricted) {
+ throwError(firstRestricted, Messages.StrictOctalLiteral);
+ }
+ } else {
+ if (!firstRestricted && token.octal) {
+ firstRestricted = token;
+ }
+ }
+ }
+
+ oldLabelSet = state.labelSet;
+ oldInIteration = state.inIteration;
+ oldInSwitch = state.inSwitch;
+ oldInFunctionBody = state.inFunctionBody;
+
+ state.labelSet = {};
+ state.inIteration = false;
+ state.inSwitch = false;
+ state.inFunctionBody = true;
+
+ while (index < length) {
+ if (match('}')) {
+ break;
+ }
+ sourceElement = parseSourceElement();
+ if (typeof sourceElement === 'undefined') {
+ break;
+ }
+ sourceElements.push(sourceElement);
+ }
+
+ expect('}');
+
+ state.labelSet = oldLabelSet;
+ state.inIteration = oldInIteration;
+ state.inSwitch = oldInSwitch;
+ state.inFunctionBody = oldInFunctionBody;
+
+ return {
+ type: Syntax.BlockStatement,
+ body: sourceElements
+ };
+ }
+
+ function parseFunctionDeclaration() {
+ var id, param, params = [], body, token, firstRestricted, message, previousStrict, paramSet;
+
+ expectKeyword('function');
+ token = lookahead();
+ id = parseVariableIdentifier();
+ if (strict) {
+ if (isRestrictedWord(token.value)) {
+ throwError(token, Messages.StrictFunctionName);
+ }
+ } else {
+ if (isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictFunctionName;
+ } else if (isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ }
+ }
+
+ expect('(');
+
+ if (!match(')')) {
+ paramSet = {};
+ while (index < length) {
+ token = lookahead();
+ param = parseVariableIdentifier();
+ if (strict) {
+ if (isRestrictedWord(token.value)) {
+ throwError(token, Messages.StrictParamName);
+ }
+ if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
+ throwError(token, Messages.StrictParamDupe);
+ }
+ } else if (!firstRestricted) {
+ if (isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictParamName;
+ } else if (isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictParamDupe;
+ }
+ }
+ params.push(param);
+ paramSet[param.name] = true;
+ if (match(')')) {
+ break;
+ }
+ expect(',');
+ }
+ }
+
+ expect(')');
+
+ previousStrict = strict;
+ body = parseFunctionSourceElements();
+ if (strict && firstRestricted) {
+ throwError(firstRestricted, message);
+ }
+ strict = previousStrict;
+
+ return {
+ type: Syntax.FunctionDeclaration,
+ id: id,
+ params: params,
+ body: body
+ };
+ }
+
+ function parseFunctionExpression() {
+ var token, id = null, firstRestricted, message, param, params = [], body, previousStrict, paramSet;
+
+ expectKeyword('function');
+
+ if (!match('(')) {
+ token = lookahead();
+ id = parseVariableIdentifier();
+ if (strict) {
+ if (isRestrictedWord(token.value)) {
+ throwError(token, Messages.StrictFunctionName);
+ }
+ } else {
+ if (isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictFunctionName;
+ } else if (isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ }
+ }
+ }
+
+ expect('(');
+
+ if (!match(')')) {
+ paramSet = {};
+ while (index < length) {
+ token = lookahead();
+ param = parseVariableIdentifier();
+ if (strict) {
+ if (isRestrictedWord(token.value)) {
+ throwError(token, Messages.StrictParamName);
+ }
+ if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
+ throwError(token, Messages.StrictParamDupe);
+ }
+ } else if (!firstRestricted) {
+ if (isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictParamName;
+ } else if (isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictParamDupe;
+ }
+ }
+ params.push(param);
+ paramSet[param.name] = true;
+ if (match(')')) {
+ break;
+ }
+ expect(',');
+ }
+ }
+
+ expect(')');
+
+ previousStrict = strict;
+ body = parseFunctionSourceElements();
+ if (strict && firstRestricted) {
+ throwError(firstRestricted, message);
+ }
+ strict = previousStrict;
+
+ return {
+ type: Syntax.FunctionExpression,
+ id: id,
+ params: params,
+ body: body
+ };
+ }
+
+ // 14 Program
+
+ function parseSourceElement() {
+ var token = lookahead();
+
+ if (token.type === Token.Keyword) {
+ switch (token.value) {
+ case 'const':
+ case 'let':
+ return parseConstLetDeclaration(token.value);
+ case 'function':
+ return parseFunctionDeclaration();
+ default:
+ return parseStatement();
+ }
+ }
+
+ if (token.type !== Token.EOF) {
+ return parseStatement();
+ }
+ }
+
+ function parseSourceElements() {
+ var sourceElement, sourceElements = [], token, directive, firstRestricted;
+
+ while (index < length) {
+ token = lookahead();
+ if (token.type !== Token.StringLiteral) {
+ break;
+ }
+
+ sourceElement = parseSourceElement();
+ sourceElements.push(sourceElement);
+ if (sourceElement.expression.type !== Syntax.Literal) {
+ // this is not directive
+ break;
+ }
+ directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
+ if (directive === 'use strict') {
+ strict = true;
+ if (firstRestricted) {
+ throwError(firstRestricted, Messages.StrictOctalLiteral);
+ }
+ } else {
+ if (!firstRestricted && token.octal) {
+ firstRestricted = token;
+ }
+ }
+ }
+
+ while (index < length) {
+ sourceElement = parseSourceElement();
+ if (typeof sourceElement === 'undefined') {
+ break;
+ }
+ sourceElements.push(sourceElement);
+ }
+ return sourceElements;
+ }
+
+ function parseProgram() {
+ var program;
+ strict = false;
+ program = {
+ type: Syntax.Program,
+ body: parseSourceElements()
+ };
+ return program;
+ }
+
+ // The following functions are needed only when the option to preserve
+ // the comments is active.
+
+ function addComment(start, end, type, value) {
+ assert(typeof start === 'number', 'Comment must have valid position');
+
+ // Because the way the actual token is scanned, often the comments
+ // (if any) are skipped twice during the lexical analysis.
+ // Thus, we need to skip adding a comment if the comment array already
+ // handled it.
+ if (extra.comments.length > 0) {
+ if (extra.comments[extra.comments.length - 1].range[1] > start) {
+ return;
+ }
+ }
+
+ extra.comments.push({
+ range: [start, end],
+ type: type,
+ value: value
+ });
+ }
+
+ function scanComment() {
+ var comment, ch, start, blockComment, lineComment;
+
+ comment = '';
+ blockComment = false;
+ lineComment = false;
+
+ while (index < length) {
+ ch = source[index];
+
+ if (lineComment) {
+ ch = nextChar();
+ if (index >= length) {
+ lineComment = false;
+ comment += ch;
+ addComment(start, index, 'Line', comment);
+ } else if (isLineTerminator(ch)) {
+ lineComment = false;
+ addComment(start, index, 'Line', comment);
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ comment = '';
+ } else {
+ comment += ch;
+ }
+ } else if (blockComment) {
+ if (isLineTerminator(ch)) {
+ if (ch === '\r' && source[index + 1] === '\n') {
+ ++index;
+ comment += '\r\n';
+ } else {
+ comment += ch;
+ }
+ ++lineNumber;
+ ++index;
+ lineStart = index;
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ } else {
+ ch = nextChar();
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ comment += ch;
+ if (ch === '*') {
+ ch = source[index];
+ if (ch === '/') {
+ comment = comment.substr(0, comment.length - 1);
+ blockComment = false;
+ ++index;
+ addComment(start, index, 'Block', comment);
+ comment = '';
+ }
+ }
+ }
+ } else if (ch === '/') {
+ ch = source[index + 1];
+ if (ch === '/') {
+ start = index;
+ index += 2;
+ lineComment = true;
+ } else if (ch === '*') {
+ start = index;
+ index += 2;
+ blockComment = true;
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ } else {
+ break;
+ }
+ } else if (isWhiteSpace(ch)) {
+ ++index;
+ } else if (isLineTerminator(ch)) {
+ ++index;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ } else {
+ break;
+ }
+ }
+ }
+
+ function collectToken() {
+ var token = extra.advance(),
+ range,
+ value;
+
+ if (token.type !== Token.EOF) {
+ range = [token.range[0], token.range[1]];
+ value = sliceSource(token.range[0], token.range[1]);
+ extra.tokens.push({
+ type: TokenName[token.type],
+ value: value,
+ range: range
+ });
+ }
+
+ return token;
+ }
+
+ function collectRegex() {
+ var pos, regex, token;
+
+ skipComment();
+
+ pos = index;
+ regex = extra.scanRegExp();
+
+ // Pop the previous token, which is likely '/' or '/='
+ if (extra.tokens.length > 0) {
+ token = extra.tokens[extra.tokens.length - 1];
+ if (token.range[0] === pos && token.type === 'Punctuator') {
+ if (token.value === '/' || token.value === '/=') {
+ extra.tokens.pop();
+ }
+ }
+ }
+
+ extra.tokens.push({
+ type: 'RegularExpression',
+ value: regex.literal,
+ range: [pos, index]
+ });
+
+ return regex;
+ }
+
+ function createLiteral(token) {
+ return {
+ type: Syntax.Literal,
+ value: token.value
+ };
+ }
+
+ function createRawLiteral(token) {
+ return {
+ type: Syntax.Literal,
+ value: token.value,
+ raw: sliceSource(token.range[0], token.range[1])
+ };
+ }
+
+ function wrapTrackingFunction(range, loc) {
+
+ return function (parseFunction) {
+
+ function isBinary(node) {
+ return node.type === Syntax.LogicalExpression ||
+ node.type === Syntax.BinaryExpression;
+ }
+
+ function visit(node) {
+ if (isBinary(node.left)) {
+ visit(node.left);
+ }
+ if (isBinary(node.right)) {
+ visit(node.right);
+ }
+
+ if (range && typeof node.range === 'undefined') {
+ node.range = [node.left.range[0], node.right.range[1]];
+ }
+ if (loc && typeof node.loc === 'undefined') {
+ node.loc = {
+ start: node.left.loc.start,
+ end: node.right.loc.end
+ };
+ }
+ }
+
+ return function () {
+ var node, rangeInfo, locInfo;
+
+ skipComment();
+ rangeInfo = [index, 0];
+ locInfo = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+
+ node = parseFunction.apply(null, arguments);
+ if (typeof node !== 'undefined') {
+
+ if (range) {
+ rangeInfo[1] = index;
+ node.range = rangeInfo;
+ }
+
+ if (loc) {
+ locInfo.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ node.loc = locInfo;
+ }
+
+ if (isBinary(node)) {
+ visit(node);
+ }
+
+ if (node.type === Syntax.MemberExpression) {
+ if (typeof node.object.range !== 'undefined') {
+ node.range[0] = node.object.range[0];
+ }
+ if (typeof node.object.loc !== 'undefined') {
+ node.loc.start = node.object.loc.start;
+ }
+ }
+ return node;
+ }
+ };
+
+ };
+ }
+
+ function patch() {
+
+ var wrapTracking;
+
+ if (extra.comments) {
+ extra.skipComment = skipComment;
+ skipComment = scanComment;
+ }
+
+ if (extra.raw) {
+ extra.createLiteral = createLiteral;
+ createLiteral = createRawLiteral;
+ }
+
+ if (extra.range || extra.loc) {
+
+ wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
+
+ extra.parseAdditiveExpression = parseAdditiveExpression;
+ extra.parseAssignmentExpression = parseAssignmentExpression;
+ extra.parseBitwiseANDExpression = parseBitwiseANDExpression;
+ extra.parseBitwiseORExpression = parseBitwiseORExpression;
+ extra.parseBitwiseXORExpression = parseBitwiseXORExpression;
+ extra.parseBlock = parseBlock;
+ extra.parseFunctionSourceElements = parseFunctionSourceElements;
+ extra.parseCallMember = parseCallMember;
+ extra.parseCatchClause = parseCatchClause;
+ extra.parseComputedMember = parseComputedMember;
+ extra.parseConditionalExpression = parseConditionalExpression;
+ extra.parseConstLetDeclaration = parseConstLetDeclaration;
+ extra.parseEqualityExpression = parseEqualityExpression;
+ extra.parseExpression = parseExpression;
+ extra.parseForVariableDeclaration = parseForVariableDeclaration;
+ extra.parseFunctionDeclaration = parseFunctionDeclaration;
+ extra.parseFunctionExpression = parseFunctionExpression;
+ extra.parseLogicalANDExpression = parseLogicalANDExpression;
+ extra.parseLogicalORExpression = parseLogicalORExpression;
+ extra.parseMultiplicativeExpression = parseMultiplicativeExpression;
+ extra.parseNewExpression = parseNewExpression;
+ extra.parseNonComputedMember = parseNonComputedMember;
+ extra.parseNonComputedProperty = parseNonComputedProperty;
+ extra.parseObjectProperty = parseObjectProperty;
+ extra.parseObjectPropertyKey = parseObjectPropertyKey;
+ extra.parsePostfixExpression = parsePostfixExpression;
+ extra.parsePrimaryExpression = parsePrimaryExpression;
+ extra.parseProgram = parseProgram;
+ extra.parsePropertyFunction = parsePropertyFunction;
+ extra.parseRelationalExpression = parseRelationalExpression;
+ extra.parseStatement = parseStatement;
+ extra.parseShiftExpression = parseShiftExpression;
+ extra.parseSwitchCase = parseSwitchCase;
+ extra.parseUnaryExpression = parseUnaryExpression;
+ extra.parseVariableDeclaration = parseVariableDeclaration;
+ extra.parseVariableIdentifier = parseVariableIdentifier;
+
+ parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression);
+ parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
+ parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression);
+ parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression);
+ parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression);
+ parseBlock = wrapTracking(extra.parseBlock);
+ parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
+ parseCallMember = wrapTracking(extra.parseCallMember);
+ parseCatchClause = wrapTracking(extra.parseCatchClause);
+ parseComputedMember = wrapTracking(extra.parseComputedMember);
+ parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
+ parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
+ parseEqualityExpression = wrapTracking(extra.parseEqualityExpression);
+ parseExpression = wrapTracking(extra.parseExpression);
+ parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
+ parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
+ parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
+ parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression);
+ parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression);
+ parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression);
+ parseNewExpression = wrapTracking(extra.parseNewExpression);
+ parseNonComputedMember = wrapTracking(extra.parseNonComputedMember);
+ parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
+ parseObjectProperty = wrapTracking(extra.parseObjectProperty);
+ parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
+ parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
+ parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
+ parseProgram = wrapTracking(extra.parseProgram);
+ parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
+ parseRelationalExpression = wrapTracking(extra.parseRelationalExpression);
+ parseStatement = wrapTracking(extra.parseStatement);
+ parseShiftExpression = wrapTracking(extra.parseShiftExpression);
+ parseSwitchCase = wrapTracking(extra.parseSwitchCase);
+ parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
+ parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
+ parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
+ }
+
+ if (typeof extra.tokens !== 'undefined') {
+ extra.advance = advance;
+ extra.scanRegExp = scanRegExp;
+
+ advance = collectToken;
+ scanRegExp = collectRegex;
+ }
+ }
+
+ function unpatch() {
+ if (typeof extra.skipComment === 'function') {
+ skipComment = extra.skipComment;
+ }
+
+ if (extra.raw) {
+ createLiteral = extra.createLiteral;
+ }
+
+ if (extra.range || extra.loc) {
+ parseAdditiveExpression = extra.parseAdditiveExpression;
+ parseAssignmentExpression = extra.parseAssignmentExpression;
+ parseBitwiseANDExpression = extra.parseBitwiseANDExpression;
+ parseBitwiseORExpression = extra.parseBitwiseORExpression;
+ parseBitwiseXORExpression = extra.parseBitwiseXORExpression;
+ parseBlock = extra.parseBlock;
+ parseFunctionSourceElements = extra.parseFunctionSourceElements;
+ parseCallMember = extra.parseCallMember;
+ parseCatchClause = extra.parseCatchClause;
+ parseComputedMember = extra.parseComputedMember;
+ parseConditionalExpression = extra.parseConditionalExpression;
+ parseConstLetDeclaration = extra.parseConstLetDeclaration;
+ parseEqualityExpression = extra.parseEqualityExpression;
+ parseExpression = extra.parseExpression;
+ parseForVariableDeclaration = extra.parseForVariableDeclaration;
+ parseFunctionDeclaration = extra.parseFunctionDeclaration;
+ parseFunctionExpression = extra.parseFunctionExpression;
+ parseLogicalANDExpression = extra.parseLogicalANDExpression;
+ parseLogicalORExpression = extra.parseLogicalORExpression;
+ parseMultiplicativeExpression = extra.parseMultiplicativeExpression;
+ parseNewExpression = extra.parseNewExpression;
+ parseNonComputedMember = extra.parseNonComputedMember;
+ parseNonComputedProperty = extra.parseNonComputedProperty;
+ parseObjectProperty = extra.parseObjectProperty;
+ parseObjectPropertyKey = extra.parseObjectPropertyKey;
+ parsePrimaryExpression = extra.parsePrimaryExpression;
+ parsePostfixExpression = extra.parsePostfixExpression;
+ parseProgram = extra.parseProgram;
+ parsePropertyFunction = extra.parsePropertyFunction;
+ parseRelationalExpression = extra.parseRelationalExpression;
+ parseStatement = extra.parseStatement;
+ parseShiftExpression = extra.parseShiftExpression;
+ parseSwitchCase = extra.parseSwitchCase;
+ parseUnaryExpression = extra.parseUnaryExpression;
+ parseVariableDeclaration = extra.parseVariableDeclaration;
+ parseVariableIdentifier = extra.parseVariableIdentifier;
+ }
+
+ if (typeof extra.scanRegExp === 'function') {
+ advance = extra.advance;
+ scanRegExp = extra.scanRegExp;
+ }
+ }
+
+ function stringToArray(str) {
+ var length = str.length,
+ result = [],
+ i;
+ for (i = 0; i < length; ++i) {
+ result[i] = str.charAt(i);
+ }
+ return result;
+ }
+
+ function parse(code, options) {
+ var program, toString;
+
+ toString = String;
+ if (typeof code !== 'string' && !(code instanceof String)) {
+ code = toString(code);
+ }
+
+ source = code;
+ index = 0;
+ lineNumber = (source.length > 0) ? 1 : 0;
+ lineStart = 0;
+ length = source.length;
+ buffer = null;
+ state = {
+ allowIn: true,
+ labelSet: {},
+ lastParenthesized: null,
+ inFunctionBody: false,
+ inIteration: false,
+ inSwitch: false
+ };
+
+ extra = {};
+ if (typeof options !== 'undefined') {
+ extra.range = (typeof options.range === 'boolean') && options.range;
+ extra.loc = (typeof options.loc === 'boolean') && options.loc;
+ extra.raw = (typeof options.raw === 'boolean') && options.raw;
+ if (typeof options.tokens === 'boolean' && options.tokens) {
+ extra.tokens = [];
+ }
+ if (typeof options.comment === 'boolean' && options.comment) {
+ extra.comments = [];
+ }
+ if (typeof options.tolerant === 'boolean' && options.tolerant) {
+ extra.errors = [];
+ }
+ }
+
+ if (length > 0) {
+ if (typeof source[0] === 'undefined') {
+ // Try first to convert to a string. This is good as fast path
+ // for old IE which understands string indexing for string
+ // literals only and not for string object.
+ if (code instanceof String) {
+ source = code.valueOf();
+ }
+
+ // Force accessing the characters via an array.
+ if (typeof source[0] === 'undefined') {
+ source = stringToArray(code);
+ }
+ }
+ }
+
+ patch();
+ try {
+ program = parseProgram();
+ if (typeof extra.comments !== 'undefined') {
+ program.comments = extra.comments;
+ }
+ if (typeof extra.tokens !== 'undefined') {
+ program.tokens = extra.tokens;
+ }
+ if (typeof extra.errors !== 'undefined') {
+ program.errors = extra.errors;
+ }
+ } catch (e) {
+ throw e;
+ } finally {
+ unpatch();
+ extra = {};
+ }
+
+ return program;
+ }
+
+ // Sync with package.json.
+ exports.version = '1.0.0-dev';
+
+ exports.parse = parse;
+
+ // Deep copy.
+ exports.Syntax = (function () {
+ var name, types = {};
+
+ if (typeof Object.create === 'function') {
+ types = Object.create(null);
+ }
+
+ for (name in Syntax) {
+ if (Syntax.hasOwnProperty(name)) {
+ types[name] = Syntax[name];
+ }
+ }
+
+ if (typeof Object.freeze === 'function') {
+ Object.freeze(types);
+ }
+
+ return types;
+ }());
+
+}(typeof exports === 'undefined' ? (esprima = {}) : exports));
+/* vim: set sw=4 ts=4 et tw=80 : */
+});
+define('uglifyjs/consolidator', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) {
+/**
+ * @preserve Copyright 2012 Robert Gust-Bardon .
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * @fileoverview Enhances UglifyJS with consolidation of null, Boolean, and String values.
+ *
Also known as aliasing, this feature has been deprecated in the Closure Compiler since its
+ * initial release, where it is unavailable from the CLI. The Closure Compiler allows one to log and
+ * influence this process. In contrast, this implementation does not introduce
+ * any variable declarations in global code and derives String values from
+ * identifier names used as property accessors.
+ *
Consolidating literals may worsen the data compression ratio when an encoding
+ * transformation is applied. For instance, jQuery 1.7.1 takes 248235 bytes.
+ * Building it with
+ * UglifyJS v1.2.5 results in 93647 bytes (37.73% of the original) which are
+ * then compressed to 33154 bytes (13.36% of the original) using gzip(1). Building it with the same
+ * version of UglifyJS 1.2.5 patched with the implementation of consolidation
+ * results in 80784 bytes (a decrease of 12863 bytes, i.e. 13.74%, in comparison
+ * to the aforementioned 93647 bytes) which are then compressed to 34013 bytes
+ * (an increase of 859 bytes, i.e. 2.59%, in comparison to the aforementioned
+ * 33154 bytes).
+ */
+
+/*global console:false, exports:true, module:false, require:false */
+/*jshint sub:true */
+/**
+ * Consolidates null, Boolean, and String values found inside an AST.
+ * @param {!TSyntacticCodeUnit} oAbstractSyntaxTree An array-like object
+ * representing an AST.
+ * @return {!TSyntacticCodeUnit} An array-like object representing an AST with its null, Boolean, and
+ * String values consolidated.
+ */
+// TODO(user) Consolidation of mathematical values found in numeric literals.
+// TODO(user) Unconsolidation.
+// TODO(user) Consolidation of ECMA-262 6th Edition programs.
+// TODO(user) Rewrite in ECMA-262 6th Edition.
+exports['ast_consolidate'] = function(oAbstractSyntaxTree) {
+ 'use strict';
+ /*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true,
+ latedef:true, newcap:true, noarge:true, noempty:true, nonew:true,
+ onevar:true, plusplus:true, regexp:true, undef:true, strict:true,
+ sub:false, trailing:true */
+
+ var _,
+ /**
+ * A record consisting of data about one or more source elements.
+ * @constructor
+ * @nosideeffects
+ */
+ TSourceElementsData = function() {
+ /**
+ * The category of the elements.
+ * @type {number}
+ * @see ESourceElementCategories
+ */
+ this.nCategory = ESourceElementCategories.N_OTHER;
+ /**
+ * The number of occurrences (within the elements) of each primitive
+ * value that could be consolidated.
+ * @type {!Array.>}
+ */
+ this.aCount = [];
+ this.aCount[EPrimaryExpressionCategories.N_IDENTIFIER_NAMES] = {};
+ this.aCount[EPrimaryExpressionCategories.N_STRING_LITERALS] = {};
+ this.aCount[EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS] =
+ {};
+ /**
+ * Identifier names found within the elements.
+ * @type {!Array.}
+ */
+ this.aIdentifiers = [];
+ /**
+ * Prefixed representation Strings of each primitive value that could be
+ * consolidated within the elements.
+ * @type {!Array.}
+ */
+ this.aPrimitiveValues = [];
+ },
+ /**
+ * A record consisting of data about a primitive value that could be
+ * consolidated.
+ * @constructor
+ * @nosideeffects
+ */
+ TPrimitiveValue = function() {
+ /**
+ * The difference in the number of terminal symbols between the original
+ * source text and the one with the primitive value consolidated. If the
+ * difference is positive, the primitive value is considered worthwhile.
+ * @type {number}
+ */
+ this.nSaving = 0;
+ /**
+ * An identifier name of the variable that will be declared and assigned
+ * the primitive value if the primitive value is consolidated.
+ * @type {string}
+ */
+ this.sName = '';
+ },
+ /**
+ * A record consisting of data on what to consolidate within the range of
+ * source elements that is currently being considered.
+ * @constructor
+ * @nosideeffects
+ */
+ TSolution = function() {
+ /**
+ * An object whose keys are prefixed representation Strings of each
+ * primitive value that could be consolidated within the elements and
+ * whose values are corresponding data about those primitive values.
+ * @type {!Object.}
+ * @see TPrimitiveValue
+ */
+ this.oPrimitiveValues = {};
+ /**
+ * The difference in the number of terminal symbols between the original
+ * source text and the one with all the worthwhile primitive values
+ * consolidated.
+ * @type {number}
+ * @see TPrimitiveValue#nSaving
+ */
+ this.nSavings = 0;
+ },
+ /**
+ * The processor of ASTs found
+ * in UglifyJS.
+ * @namespace
+ * @type {!TProcessor}
+ */
+ oProcessor = (/** @type {!TProcessor} */ require('./process')),
+ /**
+ * A record consisting of a number of constants that represent the
+ * difference in the number of terminal symbols between a source text with
+ * a modified syntactic code unit and the original one.
+ * @namespace
+ * @type {!Object.}
+ */
+ oWeights = {
+ /**
+ * The difference in the number of punctuators required by the bracket
+ * notation and the dot notation.
+ *
'[]'.length - '.'.length
+ * @const
+ * @type {number}
+ */
+ N_PROPERTY_ACCESSOR: 1,
+ /**
+ * The number of punctuators required by a variable declaration with an
+ * initialiser.
+ *
':'.length + ';'.length
+ * @const
+ * @type {number}
+ */
+ N_VARIABLE_DECLARATION: 2,
+ /**
+ * The number of terminal symbols required to introduce a variable
+ * statement (excluding its variable declaration list).
+ *
'var '.length
+ * @const
+ * @type {number}
+ */
+ N_VARIABLE_STATEMENT_AFFIXATION: 4,
+ /**
+ * The number of terminal symbols needed to enclose source elements
+ * within a function call with no argument values to a function with an
+ * empty parameter list.
+ *
'(function(){}());'.length
+ * @const
+ * @type {number}
+ */
+ N_CLOSURE: 17
+ },
+ /**
+ * Categories of primary expressions from which primitive values that
+ * could be consolidated are derivable.
+ * @namespace
+ * @enum {number}
+ */
+ EPrimaryExpressionCategories = {
+ /**
+ * Identifier names used as property accessors.
+ * @type {number}
+ */
+ N_IDENTIFIER_NAMES: 0,
+ /**
+ * String literals.
+ * @type {number}
+ */
+ N_STRING_LITERALS: 1,
+ /**
+ * Null and Boolean literals.
+ * @type {number}
+ */
+ N_NULL_AND_BOOLEAN_LITERALS: 2
+ },
+ /**
+ * Prefixes of primitive values that could be consolidated.
+ * The String values of the prefixes must have same number of characters.
+ * The prefixes must not be used in any properties defined in any version
+ * of ECMA-262.
+ * @namespace
+ * @enum {string}
+ */
+ EValuePrefixes = {
+ /**
+ * Identifies String values.
+ * @type {string}
+ */
+ S_STRING: '#S',
+ /**
+ * Identifies null and Boolean values.
+ * @type {string}
+ */
+ S_SYMBOLIC: '#O'
+ },
+ /**
+ * Categories of source elements in terms of their appropriateness of
+ * having their primitive values consolidated.
+ * @namespace
+ * @enum {number}
+ */
+ ESourceElementCategories = {
+ /**
+ * Identifies a source element that includes the {@code with} statement.
+ * @type {number}
+ */
+ N_WITH: 0,
+ /**
+ * Identifies a source element that includes the {@code eval} identifier name.
+ * @type {number}
+ */
+ N_EVAL: 1,
+ /**
+ * Identifies a source element that must be excluded from the process
+ * unless its whole scope is examined.
+ * @type {number}
+ */
+ N_EXCLUDABLE: 2,
+ /**
+ * Identifies source elements not posing any problems.
+ * @type {number}
+ */
+ N_OTHER: 3
+ },
+ /**
+ * The list of literals (other than the String ones) whose primitive
+ * values can be consolidated.
+ * @const
+ * @type {!Array.}
+ */
+ A_OTHER_SUBSTITUTABLE_LITERALS = [
+ 'null', // The null literal.
+ 'false', // The Boolean literal {@code false}.
+ 'true' // The Boolean literal {@code true}.
+ ];
+
+ (/**
+ * Consolidates all worthwhile primitive values in a syntactic code unit.
+ * @param {!TSyntacticCodeUnit} oSyntacticCodeUnit An array-like object
+ * representing the branch of the abstract syntax tree representing the
+ * syntactic code unit along with its scope.
+ * @see TPrimitiveValue#nSaving
+ */
+ function fExamineSyntacticCodeUnit(oSyntacticCodeUnit) {
+ var _,
+ /**
+ * Indicates whether the syntactic code unit represents global code.
+ * @type {boolean}
+ */
+ bIsGlobal = 'toplevel' === oSyntacticCodeUnit[0],
+ /**
+ * Indicates whether the whole scope is being examined.
+ * @type {boolean}
+ */
+ bIsWhollyExaminable = !bIsGlobal,
+ /**
+ * An array-like object representing source elements that constitute a
+ * syntactic code unit.
+ * @type {!TSyntacticCodeUnit}
+ */
+ oSourceElements,
+ /**
+ * A record consisting of data about the source element that is
+ * currently being examined.
+ * @type {!TSourceElementsData}
+ */
+ oSourceElementData,
+ /**
+ * The scope of the syntactic code unit.
+ * @type {!TScope}
+ */
+ oScope,
+ /**
+ * An instance of an object that allows the traversal of an AST.
+ * @type {!TWalker}
+ */
+ oWalker,
+ /**
+ * An object encompassing collections of functions used during the
+ * traversal of an AST.
+ * @namespace
+ * @type {!Object.>}
+ */
+ oWalkers = {
+ /**
+ * A collection of functions used during the surveyance of source
+ * elements.
+ * @namespace
+ * @type {!Object.}
+ */
+ oSurveySourceElement: {
+ /**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name. Adds the identifier of the function and its formal
+ * parameters to the list of identifier names found.
+ * @param {string} sIdentifier The identifier of the function.
+ * @param {!Array.} aFormalParameterList Formal parameters.
+ * @param {!TSyntacticCodeUnit} oFunctionBody Function code.
+ */
+ 'defun': function(
+ sIdentifier,
+ aFormalParameterList,
+ oFunctionBody) {
+ fClassifyAsExcludable();
+ fAddIdentifier(sIdentifier);
+ aFormalParameterList.forEach(fAddIdentifier);
+ },
+ /**
+ * Increments the count of the number of occurrences of the String
+ * value that is equivalent to the sequence of terminal symbols
+ * that constitute the encountered identifier name.
+ * @param {!TSyntacticCodeUnit} oExpression The nonterminal
+ * MemberExpression.
+ * @param {string} sIdentifierName The identifier name used as the
+ * property accessor.
+ * @return {!Array} The encountered branch of an AST with its nonterminal
+ * MemberExpression traversed.
+ */
+ 'dot': function(oExpression, sIdentifierName) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_IDENTIFIER_NAMES,
+ EValuePrefixes.S_STRING + sIdentifierName);
+ return ['dot', oWalker.walk(oExpression), sIdentifierName];
+ },
+ /**
+ * Adds the optional identifier of the function and its formal
+ * parameters to the list of identifier names found.
+ * @param {?string} sIdentifier The optional identifier of the
+ * function.
+ * @param {!Array.} aFormalParameterList Formal parameters.
+ * @param {!TSyntacticCodeUnit} oFunctionBody Function code.
+ */
+ 'function': function(
+ sIdentifier,
+ aFormalParameterList,
+ oFunctionBody) {
+ if ('string' === typeof sIdentifier) {
+ fAddIdentifier(sIdentifier);
+ }
+ aFormalParameterList.forEach(fAddIdentifier);
+ },
+ /**
+ * Either increments the count of the number of occurrences of the
+ * encountered null or Boolean value or classifies a source element
+ * as containing the {@code eval} identifier name.
+ * @param {string} sIdentifier The identifier encountered.
+ */
+ 'name': function(sIdentifier) {
+ if (-1 !== A_OTHER_SUBSTITUTABLE_LITERALS.indexOf(sIdentifier)) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS,
+ EValuePrefixes.S_SYMBOLIC + sIdentifier);
+ } else {
+ if ('eval' === sIdentifier) {
+ oSourceElementData.nCategory =
+ ESourceElementCategories.N_EVAL;
+ }
+ fAddIdentifier(sIdentifier);
+ }
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name.
+ * @param {TSyntacticCodeUnit} oExpression The expression whose
+ * value is to be returned.
+ */
+ 'return': function(oExpression) {
+ fClassifyAsExcludable();
+ },
+ /**
+ * Increments the count of the number of occurrences of the
+ * encountered String value.
+ * @param {string} sStringValue The String value of the string
+ * literal encountered.
+ */
+ 'string': function(sStringValue) {
+ if (sStringValue.length > 0) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_STRING_LITERALS,
+ EValuePrefixes.S_STRING + sStringValue);
+ }
+ },
+ /**
+ * Adds the identifier reserved for an exception to the list of
+ * identifier names found.
+ * @param {!TSyntacticCodeUnit} oTry A block of code in which an
+ * exception can occur.
+ * @param {Array} aCatch The identifier reserved for an exception
+ * and a block of code to handle the exception.
+ * @param {TSyntacticCodeUnit} oFinally An optional block of code
+ * to be evaluated regardless of whether an exception occurs.
+ */
+ 'try': function(oTry, aCatch, oFinally) {
+ if (Array.isArray(aCatch)) {
+ fAddIdentifier(aCatch[0]);
+ }
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name. Adds the identifier of each declared variable to the list
+ * of identifier names found.
+ * @param {!Array.} aVariableDeclarationList Variable
+ * declarations.
+ */
+ 'var': function(aVariableDeclarationList) {
+ fClassifyAsExcludable();
+ aVariableDeclarationList.forEach(fAddVariable);
+ },
+ /**
+ * Classifies a source element as containing the {@code with}
+ * statement.
+ * @param {!TSyntacticCodeUnit} oExpression An expression whose
+ * value is to be converted to a value of type Object and
+ * become the binding object of a new object environment
+ * record of a new lexical environment in which the statement
+ * is to be executed.
+ * @param {!TSyntacticCodeUnit} oStatement The statement to be
+ * executed in the augmented lexical environment.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'with': function(oExpression, oStatement) {
+ oSourceElementData.nCategory = ESourceElementCategories.N_WITH;
+ return [];
+ }
+ /**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ },
+ /**
+ * A collection of functions used while looking for nested functions.
+ * @namespace
+ * @type {!Object.}
+ */
+ oExamineFunctions: {
+ /**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ /**
+ * Orders an examination of a nested function declaration.
+ * @this {!TSyntacticCodeUnit} An array-like object representing
+ * the branch of an AST representing the syntactic code unit along with
+ * its scope.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'defun': function() {
+ fExamineSyntacticCodeUnit(this);
+ return [];
+ },
+ /**
+ * Orders an examination of a nested function expression.
+ * @this {!TSyntacticCodeUnit} An array-like object representing
+ * the branch of an AST representing the syntactic code unit along with
+ * its scope.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'function': function() {
+ fExamineSyntacticCodeUnit(this);
+ return [];
+ }
+ /**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ }
+ },
+ /**
+ * Records containing data about source elements.
+ * @type {Array.}
+ */
+ aSourceElementsData = [],
+ /**
+ * The index (in the source text order) of the source element
+ * immediately following a Directive Prologue.
+ * @type {number}
+ */
+ nAfterDirectivePrologue = 0,
+ /**
+ * The index (in the source text order) of the source element that is
+ * currently being considered.
+ * @type {number}
+ */
+ nPosition,
+ /**
+ * The index (in the source text order) of the source element that is
+ * the last element of the range of source elements that is currently
+ * being considered.
+ * @type {(undefined|number)}
+ */
+ nTo,
+ /**
+ * Initiates the traversal of a source element.
+ * @param {!TWalker} oWalker An instance of an object that allows the
+ * traversal of an abstract syntax tree.
+ * @param {!TSyntacticCodeUnit} oSourceElement A source element from
+ * which the traversal should commence.
+ * @return {function(): !TSyntacticCodeUnit} A function that is able to
+ * initiate the traversal from a given source element.
+ */
+ cContext = function(oWalker, oSourceElement) {
+ /**
+ * @return {!TSyntacticCodeUnit} A function that is able to
+ * initiate the traversal from a given source element.
+ */
+ var fLambda = function() {
+ return oWalker.walk(oSourceElement);
+ };
+
+ return fLambda;
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name.
+ */
+ fClassifyAsExcludable = function() {
+ if (oSourceElementData.nCategory ===
+ ESourceElementCategories.N_OTHER) {
+ oSourceElementData.nCategory =
+ ESourceElementCategories.N_EXCLUDABLE;
+ }
+ },
+ /**
+ * Adds an identifier to the list of identifier names found.
+ * @param {string} sIdentifier The identifier to be added.
+ */
+ fAddIdentifier = function(sIdentifier) {
+ if (-1 === oSourceElementData.aIdentifiers.indexOf(sIdentifier)) {
+ oSourceElementData.aIdentifiers.push(sIdentifier);
+ }
+ },
+ /**
+ * Adds the identifier of a variable to the list of identifier names
+ * found.
+ * @param {!Array} aVariableDeclaration A variable declaration.
+ */
+ fAddVariable = function(aVariableDeclaration) {
+ fAddIdentifier(/** @type {string} */ aVariableDeclaration[0]);
+ },
+ /**
+ * Increments the count of the number of occurrences of the prefixed
+ * String representation attributed to the primary expression.
+ * @param {number} nCategory The category of the primary expression.
+ * @param {string} sName The prefixed String representation attributed
+ * to the primary expression.
+ */
+ fCountPrimaryExpression = function(nCategory, sName) {
+ if (!oSourceElementData.aCount[nCategory].hasOwnProperty(sName)) {
+ oSourceElementData.aCount[nCategory][sName] = 0;
+ if (-1 === oSourceElementData.aPrimitiveValues.indexOf(sName)) {
+ oSourceElementData.aPrimitiveValues.push(sName);
+ }
+ }
+ oSourceElementData.aCount[nCategory][sName] += 1;
+ },
+ /**
+ * Consolidates all worthwhile primitive values in a range of source
+ * elements.
+ * @param {number} nFrom The index (in the source text order) of the
+ * source element that is the first element of the range.
+ * @param {number} nTo The index (in the source text order) of the
+ * source element that is the last element of the range.
+ * @param {boolean} bEnclose Indicates whether the range should be
+ * enclosed within a function call with no argument values to a
+ * function with an empty parameter list if any primitive values
+ * are consolidated.
+ * @see TPrimitiveValue#nSaving
+ */
+ fExamineSourceElements = function(nFrom, nTo, bEnclose) {
+ var _,
+ /**
+ * The index of the last mangled name.
+ * @type {number}
+ */
+ nIndex = oScope.cname,
+ /**
+ * The index of the source element that is currently being
+ * considered.
+ * @type {number}
+ */
+ nPosition,
+ /**
+ * A collection of functions used during the consolidation of
+ * primitive values and identifier names used as property
+ * accessors.
+ * @namespace
+ * @type {!Object.}
+ */
+ oWalkersTransformers = {
+ /**
+ * If the String value that is equivalent to the sequence of
+ * terminal symbols that constitute the encountered identifier
+ * name is worthwhile, a syntactic conversion from the dot
+ * notation to the bracket notation ensues with that sequence
+ * being substituted by an identifier name to which the value
+ * is assigned.
+ * Applies to property accessors that use the dot notation.
+ * @param {!TSyntacticCodeUnit} oExpression The nonterminal
+ * MemberExpression.
+ * @param {string} sIdentifierName The identifier name used as
+ * the property accessor.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'dot': function(oExpression, sIdentifierName) {
+ /**
+ * The prefixed String value that is equivalent to the
+ * sequence of terminal symbols that constitute the
+ * encountered identifier name.
+ * @type {string}
+ */
+ var sPrefixed = EValuePrefixes.S_STRING + sIdentifierName;
+
+ return oSolutionBest.oPrimitiveValues.hasOwnProperty(
+ sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ ['sub',
+ oWalker.walk(oExpression),
+ ['name',
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName]] :
+ ['dot', oWalker.walk(oExpression), sIdentifierName];
+ },
+ /**
+ * If the encountered identifier is a null or Boolean literal
+ * and its value is worthwhile, the identifier is substituted
+ * by an identifier name to which that value is assigned.
+ * Applies to identifier names.
+ * @param {string} sIdentifier The identifier encountered.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'name': function(sIdentifier) {
+ /**
+ * The prefixed representation String of the identifier.
+ * @type {string}
+ */
+ var sPrefixed = EValuePrefixes.S_SYMBOLIC + sIdentifier;
+
+ return [
+ 'name',
+ oSolutionBest.oPrimitiveValues.hasOwnProperty(sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName :
+ sIdentifier
+ ];
+ },
+ /**
+ * If the encountered String value is worthwhile, it is
+ * substituted by an identifier name to which that value is
+ * assigned.
+ * Applies to String values.
+ * @param {string} sStringValue The String value of the string
+ * literal encountered.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'string': function(sStringValue) {
+ /**
+ * The prefixed representation String of the primitive value
+ * of the literal.
+ * @type {string}
+ */
+ var sPrefixed =
+ EValuePrefixes.S_STRING + sStringValue;
+
+ return oSolutionBest.oPrimitiveValues.hasOwnProperty(
+ sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ ['name',
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName] :
+ ['string', sStringValue];
+ }
+ },
+ /**
+ * Such data on what to consolidate within the range of source
+ * elements that is currently being considered that lead to the
+ * greatest known reduction of the number of the terminal symbols
+ * in comparison to the original source text.
+ * @type {!TSolution}
+ */
+ oSolutionBest = new TSolution(),
+ /**
+ * Data representing an ongoing attempt to find a better
+ * reduction of the number of the terminal symbols in comparison
+ * to the original source text than the best one that is
+ * currently known.
+ * @type {!TSolution}
+ * @see oSolutionBest
+ */
+ oSolutionCandidate = new TSolution(),
+ /**
+ * A record consisting of data about the range of source elements
+ * that is currently being examined.
+ * @type {!TSourceElementsData}
+ */
+ oSourceElementsData = new TSourceElementsData(),
+ /**
+ * Variable declarations for each primitive value that is to be
+ * consolidated within the elements.
+ * @type {!Array.}
+ */
+ aVariableDeclarations = [],
+ /**
+ * Augments a list with a prefixed representation String.
+ * @param {!Array.} aList A list that is to be augmented.
+ * @return {function(string)} A function that augments a list
+ * with a prefixed representation String.
+ */
+ cAugmentList = function(aList) {
+ /**
+ * @param {string} sPrefixed Prefixed representation String of
+ * a primitive value that could be consolidated within the
+ * elements.
+ */
+ var fLambda = function(sPrefixed) {
+ if (-1 === aList.indexOf(sPrefixed)) {
+ aList.push(sPrefixed);
+ }
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of a primitive value of a given
+ * category that could be consolidated in the source element with
+ * a given index to the count of occurrences of that primitive
+ * value within the range of source elements that is currently
+ * being considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ * @param {number} nCategory The category of the primary
+ * expression from which the primitive value is derived.
+ * @return {function(string)} A function that performs the
+ * addition.
+ * @see cAddOccurrencesInCategory
+ */
+ cAddOccurrences = function(nPosition, nCategory) {
+ /**
+ * @param {string} sPrefixed The prefixed representation String
+ * of a primitive value.
+ */
+ var fLambda = function(sPrefixed) {
+ if (!oSourceElementsData.aCount[nCategory].hasOwnProperty(
+ sPrefixed)) {
+ oSourceElementsData.aCount[nCategory][sPrefixed] = 0;
+ }
+ oSourceElementsData.aCount[nCategory][sPrefixed] +=
+ aSourceElementsData[nPosition].aCount[nCategory][
+ sPrefixed];
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of each primitive value of a
+ * given category that could be consolidated in the source
+ * element with a given index to the count of occurrences of that
+ * primitive values within the range of source elements that is
+ * currently being considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ * @return {function(number)} A function that performs the
+ * addition.
+ * @see fAddOccurrences
+ */
+ cAddOccurrencesInCategory = function(nPosition) {
+ /**
+ * @param {number} nCategory The category of the primary
+ * expression from which the primitive value is derived.
+ */
+ var fLambda = function(nCategory) {
+ Object.keys(
+ aSourceElementsData[nPosition].aCount[nCategory]
+ ).forEach(cAddOccurrences(nPosition, nCategory));
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of each primitive value that
+ * could be consolidated in the source element with a given index
+ * to the count of occurrences of that primitive values within
+ * the range of source elements that is currently being
+ * considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ */
+ fAddOccurrences = function(nPosition) {
+ Object.keys(aSourceElementsData[nPosition].aCount).forEach(
+ cAddOccurrencesInCategory(nPosition));
+ },
+ /**
+ * Creates a variable declaration for a primitive value if that
+ * primitive value is to be consolidated within the elements.
+ * @param {string} sPrefixed Prefixed representation String of a
+ * primitive value that could be consolidated within the
+ * elements.
+ * @see aVariableDeclarations
+ */
+ cAugmentVariableDeclarations = function(sPrefixed) {
+ if (oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0) {
+ aVariableDeclarations.push([
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName,
+ [0 === sPrefixed.indexOf(EValuePrefixes.S_SYMBOLIC) ?
+ 'name' : 'string',
+ sPrefixed.substring(EValuePrefixes.S_SYMBOLIC.length)]
+ ]);
+ }
+ },
+ /**
+ * Sorts primitive values with regard to the difference in the
+ * number of terminal symbols between the original source text
+ * and the one with those primitive values consolidated.
+ * @param {string} sPrefixed0 The prefixed representation String
+ * of the first of the two primitive values that are being
+ * compared.
+ * @param {string} sPrefixed1 The prefixed representation String
+ * of the second of the two primitive values that are being
+ * compared.
+ * @return {number}
+ *
+ *
-1
+ *
if the first primitive value must be placed before
+ * the other one,
+ *
0
+ *
if the first primitive value may be placed before
+ * the other one,
+ *
1
+ *
if the first primitive value must not be placed
+ * before the other one.
varslice = Array.prototype.slice
+ , net = require('net');
+
+
+
+
+
The server that does the Policy File severing
+
+
Options
+
+
log false or a function that can output log information, defaults to console.log?
+
+
+
+
param: Object options Options to customize the servers functionality.
param: Array origins The origins that are allowed on this server, defaults to *:*.
api: public
+
+
+
functionServer(options, origins){
+ varme = this;
+
+ this.origins = origins || ['*:*'];
+ this.port = 843;
+ this.log = console.log;
+
+ // merge `this` with the options
+ Object.keys(options).forEach(function(key){
+ me[key] && (me[key] = options[key])
+ });
+
+ // create the net server
+ this.socket = net.createServer(functioncreateServer(socket){
+ socket.on('error', functionsocketError(){ me.responder.call(me, socket) });
+ me.responder.call(me, socket);
+ });
+
+ // Listen for errors as the port might be blocked because we do not have root priv.
+ this.socket.on('error', functionserverError(err){
+ // Special and common case error handling
+ if (err.errno == 13){
+ me.log && me.log(
+ 'Unable to listen to port `' + me.port + '` as your Node.js instance does not have root privileges. ' +
+ (
+ me.server
+ ? 'The Flash Policy file will now be served inline over the supplied HTTP server, Flash Policy files request will suffer.'
+ : 'No fallback server supplied.'
+ )
+ );
+
+ me.socket.removeAllListeners();
+ deleteme.socket;
+
+ me.emit('connect_failed', err);
+ } else {
+ me.log && me.log('FlashPolicyFileServer received a error event:\n' + (err.message ? err.message : err));
+ }
+ });
+
+ this.socket.on('timeout', functionserverTimeout(){});
+ this.socket.on('close', functionserverClosed(err){
+ err && me.log && me.log('Server closing due to an error: \n' + (err.message ? err.message : err));
+
+ if (me.server){
+ // not online anymore
+ deleteme.server.online;
+
+ // Remove the inline policy listener if we close down
+ // but only when the server was `online` (see listen prototype)
+ if( me.server['@'] && me.server.online){
+ me.server.removeListener('connection', me.server['@']);
+ }
+ }
+ me.log && me.log('Shutting down FlashPolicyFileServer');
+ });
+
+ // Compile the initial `buffer`
+ this.compile();
+}
+
+
+
+
+
Start listening for requests
+
+
+
+
param: Number port The port number it should be listening to.
param: Server server A HTTP server instance, this will be used to listen for inline requests
param: Function cb The callback needs to be called once server is ready
api: public
+
+
+
Server.prototype.listen = functionlisten(port, server, cb){
+ varme = this
+ , args = slice.call(arguments, 0)
+ , callback;
+
+ // assign the correct vars, for flexible arguments
+ args.forEach(functionargs(arg){
+ vartype = typeofarg;
+
+ if (type === 'number') me.port = arg;
+ if (type === 'function') callback = arg;
+ if (type === 'object') me.server = arg;
+ });
+
+ if (this.server){
+
+ // no one in their right mind would ever create a `@` prototype, so Im just gonna store
+ // my function on the server, so I can remove it later again once the server(s) closes
+ this.server['@'] = functionconnection(socket){
+ socket.once('data', functionrequestData(data){
+ // if it's a Flash policy request, and we can write to the
+ if (
+ data
+ && data[0] === 60
+ && data.toString() === '<policy-file-request/>\0'
+ && socket
+ && (socket.readyState === 'open' || socket.readyState === 'writeOnly')
+ ){
+ // send the buffer
+ socket.end(me.buffer);
+ }
+ });
+ };
+ // attach it
+ this.server.on('connection', this.server['@']);
+ }
+
+ // We add a callback method, so we can set a flag for when the server is `enabled` or `online`.
+ // this flag is needed because if a error occurs and the we cannot boot up the server the
+ // fallback functionality should not be removed during the `close` event
+ this.socket.listen(this.port, functionserverListening(){
+ me.socket.online = true;
+
+ if (callback) callback(), callback = undefined;
+
+ });
+
+ returnthis;
+};
+
+
+
+
+
Adds a new origin to the Flash Policy File.
+
+
+
+
param: Arguments The origins that need to be added.
api: public
+
+
+
Server.prototype.add = functionadd(){
+ varargs = slice.call(arguments, 0)
+ , i = args.length;
+
+ // flag duplicates
+ while (i--){
+ if (this.origins.indexOf(args[i]) >= 0){
+ args[i] = null;
+ }
+ }
+
+ // Add all the arguments to the array
+ // but first we want to remove all `falsy` values from the args
+ Array.prototype.push.apply(
+ this.origins
+ , args.filter(function(value){ return !!value })
+ );
+
+ this.compile();
+ returnthis;
+};
+
+
+
+
+
Removes a origin from the Flash Policy File.
+
+
+
+
param: String origin The origin that needs to be removed from the server
api: public
+
+
+
Server.prototype.remove = functionremove(origin){
+ varposition = this.origins.indexOf(origin);
+
+ // only remove and recompile if we have a match
+ if (position > 0){
+ this.origins.splice(position,1);
+ this.compile();
+ }
+
+ returnthis;
+};